[PATCH] D31853: [clangd] Implement item kind for completion results

2017-04-10 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu added a comment.

In https://reviews.llvm.org/D31853#722219, @krasimir wrote:

> Looks good! However it would be easier for reviewers if you could please use 
> arc: http://llvm.org/docs/Phabricator.html#id2
>  This makes it easy since I only have to do `arc patch D31853` in order to 
> update my client source tree with your changes.
>  Could you please create a review like that?


I did use arc diff to upload this patch, from my git clone as described in 
http://llvm.org/docs/GettingStarted.html#developers-work-with-git-svn
I've recreated the clone now and the `arc patch D31853`  seems to work for both 
git+svn/svn clones.
Sorry if my setup was causing issues.


https://reviews.llvm.org/D31853



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31853: [clangd] Implement item kind for completion results

2017-04-10 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu updated this revision to Diff 94720.
stanionascu added a comment.

One more try updating the revision on fresh git+svn clone.


https://reviews.llvm.org/D31853

Files:
  clangd/ASTManager.cpp
  clangd/Protocol.cpp
  test/clangd/completion.test

Index: test/clangd/completion.test
===
--- test/clangd/completion.test
+++ test/clangd/completion.test
@@ -16,9 +16,9 @@
 # nondeterministic, so we check regardless of order.
 #
 # CHECK: {"jsonrpc":"2.0","id":1,"result":[
-# CHECK-DAG: {"label":"a"}
-# CHECK-DAG: {"label":"bb"}
-# CHECK-DAG: {"label":"ccc"}
+# CHECK-DAG: {"label":"a","kind":5}
+# CHECK-DAG: {"label":"bb","kind":5}
+# CHECK-DAG: {"label":"ccc","kind":5}
 # CHECK: ]}
 Content-Length: 44
 
Index: clangd/Protocol.cpp
===
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -672,7 +672,7 @@
   assert(!CI.label.empty() && "completion item label is required");
   Os << R"("label":")" << llvm::yaml::escape(CI.label) << R"(",)";
   if (CI.kind != CompletionItemKind::Missing)
-Os << R"("kind":)" << static_cast(CI.kind) << R"(",)";
+Os << R"("kind":)" << static_cast(CI.kind) << R"(,)";
   if (!CI.detail.empty())
 Os << R"("detail":")" << llvm::yaml::escape(CI.detail) << R"(",)";
   if (!CI.documentation.empty())
Index: clangd/ASTManager.cpp
===
--- clangd/ASTManager.cpp
+++ clangd/ASTManager.cpp
@@ -76,6 +76,49 @@
   llvm_unreachable("Unknown diagnostic level!");
 }
 
+static CompletionItemKind getKind(CXCursorKind K) {
+  switch (K) {
+  case CXCursor_MacroInstantiation:
+  case CXCursor_MacroDefinition:
+return CompletionItemKind::Text;
+  case CXCursor_CXXMethod:
+return CompletionItemKind::Method;
+  case CXCursor_FunctionDecl:
+  case CXCursor_FunctionTemplate:
+return CompletionItemKind::Function;
+  case CXCursor_Constructor:
+  case CXCursor_Destructor:
+return CompletionItemKind::Constructor;
+  case CXCursor_FieldDecl:
+return CompletionItemKind::Field;
+  case CXCursor_VarDecl:
+  case CXCursor_ParmDecl:
+return CompletionItemKind::Variable;
+  case CXCursor_ClassDecl:
+  case CXCursor_StructDecl:
+  case CXCursor_UnionDecl:
+  case CXCursor_ClassTemplate:
+  case CXCursor_ClassTemplatePartialSpecialization:
+return CompletionItemKind::Class;
+  case CXCursor_Namespace:
+  case CXCursor_NamespaceAlias:
+  case CXCursor_NamespaceRef:
+return CompletionItemKind::Module;
+  case CXCursor_EnumConstantDecl:
+return CompletionItemKind::Value;
+  case CXCursor_EnumDecl:
+return CompletionItemKind::Enum;
+  case CXCursor_TypeAliasDecl:
+  case CXCursor_TypeAliasTemplateDecl:
+  case CXCursor_TypedefDecl:
+  case CXCursor_MemberRef:
+  case CXCursor_TypeRef:
+return CompletionItemKind::Reference;
+  default:
+return CompletionItemKind::Missing;
+  }
+}
+
 ASTManager::ASTManager(JSONOutput , DocumentStore ,
bool RunSynchronously)
 : Output(Output), Store(Store), RunSynchronously(RunSynchronously),
@@ -334,13 +377,15 @@
   CodeCompletionResult *Results,
   unsigned NumResults) override {
 for (unsigned I = 0; I != NumResults; ++I) {
-  CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
+  CodeCompletionResult  = Results[I];
+  CodeCompletionString *CCS = Result.CreateCodeCompletionString(
   S, Context, *Allocator, CCTUInfo,
   CodeCompleteOpts.IncludeBriefComments);
   if (CCS) {
 CompletionItem Item;
 assert(CCS->getTypedText());
 Item.label = CCS->getTypedText();
+Item.kind = getKind(Result.CursorKind);
 if (CCS->getBriefComment())
   Item.documentation = CCS->getBriefComment();
 Items->push_back(std::move(Item));
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31853: [clangd] Implement item kind for completion results

2017-04-10 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu updated this revision to Diff 94716.
stanionascu added a comment.

recreated from svn checkout


https://reviews.llvm.org/D31853

Files:
  clangd/ASTManager.cpp
  clangd/Protocol.cpp
  test/clangd/completion.test

Index: test/clangd/completion.test
===
--- test/clangd/completion.test
+++ test/clangd/completion.test
@@ -16,9 +16,9 @@
 # nondeterministic, so we check regardless of order.
 #
 # CHECK: {"jsonrpc":"2.0","id":1,"result":[
-# CHECK-DAG: {"label":"a"}
-# CHECK-DAG: {"label":"bb"}
-# CHECK-DAG: {"label":"ccc"}
+# CHECK-DAG: {"label":"a","kind":5}
+# CHECK-DAG: {"label":"bb","kind":5}
+# CHECK-DAG: {"label":"ccc","kind":5}
 # CHECK: ]}
 Content-Length: 44
 
Index: clangd/Protocol.cpp
===
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -672,7 +672,7 @@
   assert(!CI.label.empty() && "completion item label is required");
   Os << R"("label":")" << llvm::yaml::escape(CI.label) << R"(",)";
   if (CI.kind != CompletionItemKind::Missing)
-Os << R"("kind":)" << static_cast(CI.kind) << R"(",)";
+Os << R"("kind":)" << static_cast(CI.kind) << R"(,)";
   if (!CI.detail.empty())
 Os << R"("detail":")" << llvm::yaml::escape(CI.detail) << R"(",)";
   if (!CI.documentation.empty())
Index: clangd/ASTManager.cpp
===
--- clangd/ASTManager.cpp
+++ clangd/ASTManager.cpp
@@ -76,6 +76,49 @@
   llvm_unreachable("Unknown diagnostic level!");
 }
 
+static CompletionItemKind getKind(CXCursorKind K) {
+  switch (K) {
+  case CXCursor_MacroInstantiation:
+  case CXCursor_MacroDefinition:
+return CompletionItemKind::Text;
+  case CXCursor_CXXMethod:
+return CompletionItemKind::Method;
+  case CXCursor_FunctionDecl:
+  case CXCursor_FunctionTemplate:
+return CompletionItemKind::Function;
+  case CXCursor_Constructor:
+  case CXCursor_Destructor:
+return CompletionItemKind::Constructor;
+  case CXCursor_FieldDecl:
+return CompletionItemKind::Field;
+  case CXCursor_VarDecl:
+  case CXCursor_ParmDecl:
+return CompletionItemKind::Variable;
+  case CXCursor_ClassDecl:
+  case CXCursor_StructDecl:
+  case CXCursor_UnionDecl:
+  case CXCursor_ClassTemplate:
+  case CXCursor_ClassTemplatePartialSpecialization:
+return CompletionItemKind::Class;
+  case CXCursor_Namespace:
+  case CXCursor_NamespaceAlias:
+  case CXCursor_NamespaceRef:
+return CompletionItemKind::Module;
+  case CXCursor_EnumConstantDecl:
+return CompletionItemKind::Value;
+  case CXCursor_EnumDecl:
+return CompletionItemKind::Enum;
+  case CXCursor_TypeAliasDecl:
+  case CXCursor_TypeAliasTemplateDecl:
+  case CXCursor_TypedefDecl:
+  case CXCursor_MemberRef:
+  case CXCursor_TypeRef:
+return CompletionItemKind::Reference;
+  default:
+return CompletionItemKind::Missing;
+  }
+}
+
 ASTManager::ASTManager(JSONOutput , DocumentStore ,
bool RunSynchronously)
 : Output(Output), Store(Store), RunSynchronously(RunSynchronously),
@@ -334,13 +377,15 @@
   CodeCompletionResult *Results,
   unsigned NumResults) override {
 for (unsigned I = 0; I != NumResults; ++I) {
-  CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
+  CodeCompletionResult  = Results[I];
+  CodeCompletionString *CCS = Result.CreateCodeCompletionString(
   S, Context, *Allocator, CCTUInfo,
   CodeCompleteOpts.IncludeBriefComments);
   if (CCS) {
 CompletionItem Item;
 assert(CCS->getTypedText());
 Item.label = CCS->getTypedText();
+Item.kind = getKind(Result.CursorKind);
 if (CCS->getBriefComment())
   Item.documentation = CCS->getBriefComment();
 Items->push_back(std::move(Item));
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31853: [clangd] Implement item kind for completion results

2017-04-10 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu created this revision.
stanionascu added a project: clang-tools-extra.

The patch implements the conversion method from CXCursorKind to 
clangd::CompletionItemKind.


https://reviews.llvm.org/D31853

Files:
  clangd/ASTManager.cpp
  clangd/Protocol.cpp
  test/clangd/completion.test

Index: test/clangd/completion.test
===
--- test/clangd/completion.test
+++ test/clangd/completion.test
@@ -16,9 +16,9 @@
 # nondeterministic, so we check regardless of order.
 #
 # CHECK: {"jsonrpc":"2.0","id":1,"result":[
-# CHECK-DAG: {"label":"a"}
-# CHECK-DAG: {"label":"bb"}
-# CHECK-DAG: {"label":"ccc"}
+# CHECK-DAG: {"label":"a","kind":5}
+# CHECK-DAG: {"label":"bb","kind":5}
+# CHECK-DAG: {"label":"ccc","kind":5}
 # CHECK: ]}
 Content-Length: 44
 
Index: clangd/Protocol.cpp
===
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -645,7 +645,7 @@
   assert(!CI.label.empty() && "completion item label is required");
   Os << R"("label":")" << llvm::yaml::escape(CI.label) << R"(",)";
   if (CI.kind != CompletionItemKind::Missing)
-Os << R"("kind":)" << static_cast(CI.kind) << R"(",)";
+Os << R"("kind":)" << static_cast(CI.kind) << R"(,)";
   if (!CI.detail.empty())
 Os << R"("detail":")" << llvm::yaml::escape(CI.detail) << R"(",)";
   if (!CI.documentation.empty())
Index: clangd/ASTManager.cpp
===
--- clangd/ASTManager.cpp
+++ clangd/ASTManager.cpp
@@ -53,6 +53,49 @@
   llvm_unreachable("Unknown diagnostic level!");
 }
 
+static CompletionItemKind getKind(CXCursorKind K) {
+  switch (K) {
+  case CXCursor_MacroInstantiation:
+  case CXCursor_MacroDefinition:
+return CompletionItemKind::Text;
+  case CXCursor_CXXMethod:
+return CompletionItemKind::Method;
+  case CXCursor_FunctionDecl:
+  case CXCursor_FunctionTemplate:
+return CompletionItemKind::Function;
+  case CXCursor_Constructor:
+  case CXCursor_Destructor:
+return CompletionItemKind::Constructor;
+  case CXCursor_FieldDecl:
+return CompletionItemKind::Field;
+  case CXCursor_VarDecl:
+  case CXCursor_ParmDecl:
+return CompletionItemKind::Variable;
+  case CXCursor_ClassDecl:
+  case CXCursor_StructDecl:
+  case CXCursor_UnionDecl:
+  case CXCursor_ClassTemplate:
+  case CXCursor_ClassTemplatePartialSpecialization:
+return CompletionItemKind::Class;
+  case CXCursor_Namespace:
+  case CXCursor_NamespaceAlias:
+  case CXCursor_NamespaceRef:
+return CompletionItemKind::Module;
+  case CXCursor_EnumConstantDecl:
+return CompletionItemKind::Value;
+  case CXCursor_EnumDecl:
+return CompletionItemKind::Enum;
+  case CXCursor_TypeAliasDecl:
+  case CXCursor_TypeAliasTemplateDecl:
+  case CXCursor_TypedefDecl:
+  case CXCursor_MemberRef:
+  case CXCursor_TypeRef:
+return CompletionItemKind::Reference;
+  default:
+return CompletionItemKind::Missing;
+  }
+}
+
 ASTManager::ASTManager(JSONOutput , DocumentStore ,
bool RunSynchronously)
 : Output(Output), Store(Store), RunSynchronously(RunSynchronously),
@@ -252,13 +295,15 @@
   CodeCompletionResult *Results,
   unsigned NumResults) override {
 for (unsigned I = 0; I != NumResults; ++I) {
-  CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
+  CodeCompletionResult  = Results[I];
+  CodeCompletionString *CCS = Result.CreateCodeCompletionString(
   S, Context, *Allocator, CCTUInfo,
   CodeCompleteOpts.IncludeBriefComments);
   if (CCS) {
 CompletionItem Item;
 assert(CCS->getTypedText());
 Item.label = CCS->getTypedText();
+Item.kind = getKind(Result.CursorKind);
 if (CCS->getBriefComment())
   Item.documentation = CCS->getBriefComment();
 Items->push_back(std::move(Item));
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31401: [clangd] Extract FsPath from file:// uri

2017-04-06 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu marked 2 inline comments as done.
stanionascu added a comment.

Thank you for the review!

If there are no other comments/suggestions, would be great if someone would 
merge it as I'm lacking the permission to do so.


https://reviews.llvm.org/D31401



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31401: [clangd] Extract FsPath from file:// uri

2017-04-05 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu marked 5 inline comments as done.
stanionascu added inline comments.



Comment at: clangd/Protocol.cpp:61
 if (KeyValue == "uri") {
-  Result.uri = Value->getValue(Storage);
+  Result.uri = Uri::parse(Value->getValue(Storage));
 } else if (KeyValue == "version") {

krasimir wrote:
> Hm, seems to me that here the uri should be kept as-is and the clients of 
> `Result.uri` should convert it to file when appropriate. Otherwise it's 
> confusing.
Implemented the "URI::parse" to store both representations.



Comment at: clangd/Protocol.h:32
 
+struct Uri {
+  static std::string parse(llvm::StringRef uri);

krasimir wrote:
> It's a little confusing: the `parse` method turns an `uri` to a `file` and 
> the `unparse` method does the opposite. Maybe we should use more descriptive 
> names, like `uriToFile` and `fileToUri`. This does not seem to be 
> inconsistent with the rest of the protocol since the protocol only cares 
> about uri-s, and file-s are an implementation detail of clangd I guess.
2nd try now, instead of actually storing a string based URI, store the object 
which both representations (uri and file).



Comment at: clangd/clients/clangd-vscode/src/extension.ts:28
+uriConverters: {
+// FIXME: implement percent decoding in clangd
+code2Protocol: (uri: vscode.Uri) : string => uri.toString(true),

krasimir wrote:
> By the way, what does this do? I'm not a typescript vs code guru.
Extended the FIXME, with the description, e.g. when vscode (on windows) sends 
the uri to clangd, it's represented as "file:///c%3A/path/tofile" which leads 
to:
- incorrect detection of the compilation database location.
- cannot find the actual unit in the database.

uri.toString(true) - skips the percent encoding and sends the uri parameter to 
clangd as "file:///c:/path/tofile"


https://reviews.llvm.org/D31401



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31401: [clangd] Extract FsPath from file:// uri

2017-04-05 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu updated this revision to Diff 94271.
stanionascu added a comment.

Refactored URI handling to make it more explicit, also updated the parts which 
expect a File parameter and not an URI.


https://reviews.llvm.org/D31401

Files:
  clangd/ASTManager.cpp
  clangd/ASTManager.h
  clangd/DocumentStore.h
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/ProtocolHandlers.cpp
  clangd/clients/clangd-vscode/src/extension.ts

Index: clangd/clients/clangd-vscode/src/extension.ts
===
--- clangd/clients/clangd-vscode/src/extension.ts
+++ clangd/clients/clangd-vscode/src/extension.ts
@@ -23,15 +23,23 @@
 
 const clientOptions: vscodelc.LanguageClientOptions = {
 // Register the server for C/C++ files
-documentSelector: ['c', 'cc', 'cpp', 'h', 'hh', 'hpp']
+documentSelector: ['c', 'cc', 'cpp', 'h', 'hh', 'hpp'],
+uriConverters: {
+// FIXME: by default the URI sent over the protocol will be percent encoded (see rfc3986#section-2.1)
+//the "workaround" below disables temporarily the encoding until decoding
+//is implemented properly in clangd
+code2Protocol: (uri: vscode.Uri) : string => uri.toString(true),
+protocol2Code: (uri: string) : vscode.Uri => undefined
+}
 };
 
 const clangdClient = new vscodelc.LanguageClient('Clang Language Server', serverOptions, clientOptions);
 
 function applyTextEdits(uri: string, edits: vscodelc.TextEdit[]) {
 let textEditor = vscode.window.activeTextEditor;
 
-if (textEditor && textEditor.document.uri.toString() === uri) {
+// FIXME: vscode expects that uri will be percent encoded
+if (textEditor && textEditor.document.uri.toString(true) === uri) {
 textEditor.edit(mutator => {
 for (const edit of edits) {
 mutator.replace(vscodelc.Protocol2Code.asRange(edit.range), edit.newText);
Index: clangd/ProtocolHandlers.cpp
===
--- clangd/ProtocolHandlers.cpp
+++ clangd/ProtocolHandlers.cpp
@@ -21,7 +21,7 @@
 Output.log("Failed to decode DidOpenTextDocumentParams!\n");
 return;
   }
-  Store.addDocument(DOTDP->textDocument.uri, DOTDP->textDocument.text);
+  Store.addDocument(DOTDP->textDocument.uri.file, DOTDP->textDocument.text);
 }
 
 void TextDocumentDidChangeHandler::handleNotification(
@@ -32,7 +32,7 @@
 return;
   }
   // We only support full syncing right now.
-  Store.addDocument(DCTDP->textDocument.uri, DCTDP->contentChanges[0].text);
+  Store.addDocument(DCTDP->textDocument.uri.file, DCTDP->contentChanges[0].text);
 }
 
 /// Turn a [line, column] pair into an offset in Code.
@@ -83,9 +83,6 @@
   // Call clang-format.
   // FIXME: Don't ignore style.
   format::FormatStyle Style = format::getLLVMStyle();
-  // On windows FileManager doesn't like file://. Just strip it, clang-format
-  // doesn't need it.
-  Filename.consume_front("file://");
   tooling::Replacements Replacements =
   format::reformat(Style, Code, Ranges, Filename);
 
@@ -102,12 +99,12 @@
 return;
   }
 
-  std::string Code = Store.getDocument(DRFP->textDocument.uri);
+  std::string Code = Store.getDocument(DRFP->textDocument.uri.file);
 
   size_t Begin = positionToOffset(Code, DRFP->range.start);
   size_t Len = positionToOffset(Code, DRFP->range.end) - Begin;
 
-  writeMessage(formatCode(Code, DRFP->textDocument.uri,
+  writeMessage(formatCode(Code, DRFP->textDocument.uri.file,
   {clang::tooling::Range(Begin, Len)}, ID));
 }
 
@@ -121,14 +118,14 @@
 
   // Look for the previous opening brace from the character position and format
   // starting from there.
-  std::string Code = Store.getDocument(DOTFP->textDocument.uri);
+  std::string Code = Store.getDocument(DOTFP->textDocument.uri.file);
   size_t CursorPos = positionToOffset(Code, DOTFP->position);
   size_t PreviousLBracePos = StringRef(Code).find_last_of('{', CursorPos);
   if (PreviousLBracePos == StringRef::npos)
 PreviousLBracePos = CursorPos;
   size_t Len = 1 + CursorPos - PreviousLBracePos;
 
-  writeMessage(formatCode(Code, DOTFP->textDocument.uri,
+  writeMessage(formatCode(Code, DOTFP->textDocument.uri.file,
   {clang::tooling::Range(PreviousLBracePos, Len)}, ID));
 }
 
@@ -141,8 +138,8 @@
   }
 
   // Format everything.
-  std::string Code = Store.getDocument(DFP->textDocument.uri);
-  writeMessage(formatCode(Code, DFP->textDocument.uri,
+  std::string Code = Store.getDocument(DFP->textDocument.uri.file);
+  writeMessage(formatCode(Code, DFP->textDocument.uri.file,
   {clang::tooling::Range(0, Code.size())}, ID));
 }
 
@@ -156,7 +153,7 @@
 
   // We provide a code action for each diagnostic at the requested location
   // which has FixIts available.
-  std::string Code = 

[PATCH] D31328: [clangd] Add code completion support

2017-04-02 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu added inline comments.



Comment at: clangd/Protocol.cpp:613
+  if (CI.kind != CompletionItemKind::Missing)
+Os << R"("kind":)" << static_cast(CI.kind) << R"(",)";
+  if (!CI.detail.empty())

if kind is actually provided there will be a trailing quote, as in ("kind": 4").


https://reviews.llvm.org/D31328



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31401: [clangd] Extract FsPath from file:// uri

2017-03-27 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu created this revision.

rfc8089#appendix-E.2 specifies that paths can begin with a drive letter e.g. as 
file:///c:/.
In this case just consuming front file:// is not enough and the 3rd slash must 
be consumed to produce a valid path on windows.

The patch introduce a generic way of converting an uri to a filesystem path and 
back.


https://reviews.llvm.org/D31401

Files:
  clangd/ASTManager.cpp
  clangd/Protocol.cpp
  clangd/Protocol.h
  clangd/clients/clangd-vscode/src/extension.ts

Index: clangd/clients/clangd-vscode/src/extension.ts
===
--- clangd/clients/clangd-vscode/src/extension.ts
+++ clangd/clients/clangd-vscode/src/extension.ts
@@ -23,7 +23,12 @@
 
 const clientOptions: vscodelc.LanguageClientOptions = {
 // Register the server for C/C++ files
-documentSelector: ['c', 'cc', 'cpp', 'h', 'hh', 'hpp']
+documentSelector: ['c', 'cc', 'cpp', 'h', 'hh', 'hpp'],
+uriConverters: {
+// FIXME: implement percent decoding in clangd
+code2Protocol: (uri: vscode.Uri) : string => uri.toString(true),
+protocol2Code: (file: string) : vscode.Uri => vscode.Uri.file(file)
+}
 };
 
 const clangdClient = new vscodelc.LanguageClient('Clang Language Server', serverOptions, clientOptions);
Index: clangd/Protocol.h
===
--- clangd/Protocol.h
+++ clangd/Protocol.h
@@ -29,6 +29,11 @@
 namespace clang {
 namespace clangd {
 
+struct Uri {
+  static std::string parse(llvm::StringRef uri);
+  static std::string unparse(llvm::StringRef file);
+};
+
 struct TextDocumentIdentifier {
   /// The text document's URI.
   std::string uri;
Index: clangd/Protocol.cpp
===
--- clangd/Protocol.cpp
+++ clangd/Protocol.cpp
@@ -17,8 +17,30 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Path.h"
 using namespace clang::clangd;
 
+std::string Uri::parse(llvm::StringRef uri) {
+  uri.consume_front("file://");
+  // For Windows paths e.g. /X:
+  if (uri.size() > 2 && uri[0] == '/' && uri[2] == ':')
+uri.consume_front("/");
+  // Make sure that file paths are in native separators
+  std::string Result = llvm::sys::path::convert_to_slash(uri);
+  return Result;
+}
+
+std::string Uri::unparse(llvm::StringRef file) {
+  using namespace llvm::sys;
+  std::string Result = "file://";
+  // For Windows paths e.g. X:
+  if (file.size() > 1 && file[1] == ':')
+Result += "/";
+  // Make sure that uri paths are with posix separators
+  Result += path::convert_to_slash(file, path::Style::posix);
+  return Result;
+}
+
 llvm::Optional
 TextDocumentIdentifier::parse(llvm::yaml::MappingNode *Params) {
   TextDocumentIdentifier Result;
@@ -36,7 +58,7 @@
 
 llvm::SmallString<10> Storage;
 if (KeyValue == "uri") {
-  Result.uri = Value->getValue(Storage);
+  Result.uri = Uri::parse(Value->getValue(Storage));
 } else if (KeyValue == "version") {
   // FIXME: parse version, but only for VersionedTextDocumentIdentifiers.
 } else {
@@ -142,7 +164,7 @@
 
 llvm::SmallString<10> Storage;
 if (KeyValue == "uri") {
-  Result.uri = Value->getValue(Storage);
+  Result.uri = Uri::parse(Value->getValue(Storage));
 } else if (KeyValue == "languageId") {
   Result.languageId = Value->getValue(Storage);
 } else if (KeyValue == "version") {
Index: clangd/ASTManager.cpp
===
--- clangd/ASTManager.cpp
+++ clangd/ASTManager.cpp
@@ -28,7 +28,6 @@
   std::vector RemappedFiles;
   for (const auto  : Docs.getAllDocuments()) {
 StringRef FileName = P.first;
-FileName.consume_front("file://");
 RemappedFiles.push_back(ASTUnit::RemappedFile(
 FileName,
 llvm::MemoryBuffer::getMemBufferCopy(P.second, FileName).release()));
@@ -138,7 +137,7 @@
 Diagnostics.pop_back(); // Drop trailing comma.
   Output.writeMessage(
   R"({"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":")" +
-  File + R"(","diagnostics":[)" + Diagnostics + R"(]}})");
+  Uri::unparse(File) + R"(","diagnostics":[)" + Diagnostics + R"(]}})");
 }
 
 ASTManager::~ASTManager() {
@@ -169,8 +168,6 @@
   if (I)
 return I.get();
 
-  Uri.consume_front("file://");
-
   std::string Error;
   I = tooling::CompilationDatabase::autoDetectFromSource(Uri, Error);
   Output.log("Failed to load compilation database: " + Twine(Error) + "\n");
@@ -182,7 +179,6 @@
   tooling::CompilationDatabase *CDB =
   getOrCreateCompilationDatabaseForFile(Uri);
 
-  Uri.consume_front("file://");
   std::vector Commands;
 
   if (CDB) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D31121: [clangd] Add support for vscode extension configuration

2017-03-23 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu added a comment.

Thanks for review!
Would be great if somebody would commit it, as I cannot do it myself.


https://reviews.llvm.org/D31121



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31121: [clangd] Add support for vscode extension configuration

2017-03-20 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu added inline comments.



Comment at: clangd/clients/clangd-vscode/package.json:45
+"default": "clangd",
+"description": "The path to clangd executable"
+},

krasimir wrote:
> krasimir wrote:
> > Maybe prepend a `, for example: /usr/bin/clangd` to the "description".
> meh, it's OK like that.
I still extended the description with the example :)


https://reviews.llvm.org/D31121



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31121: [clangd] Add support for vscode extension configuration

2017-03-20 Thread Stanislav Ionascu via Phabricator via cfe-commits
stanionascu updated this revision to Diff 92367.
stanionascu edited the summary of this revision.
stanionascu added a comment.

- removed unrelated new line change
- extended the "clang.path" description a bit
- removed defaultValue for getConfig<>, as it's anyway "contributed" by 
extension package.json


https://reviews.llvm.org/D31121

Files:
  clangd/clients/clangd-vscode/package.json
  clangd/clients/clangd-vscode/src/extension.ts


Index: clangd/clients/clangd-vscode/src/extension.ts
===
--- clangd/clients/clangd-vscode/src/extension.ts
+++ clangd/clients/clangd-vscode/src/extension.ts
@@ -2,14 +2,24 @@
 import * as vscodelc from 'vscode-languageclient';
 
 /**
+ * Method to get workspace configuration option
+ * @param option name of the option (e.g. for clangd.path should be path)
+ * @param defaultValue default value to return if option is not set
+ */
+function getConfig(option: string, defaultValue?: any) : T {
+const config = vscode.workspace.getConfiguration('clangd');
+return config.get(option, defaultValue);
+}
+
+/**
  *  this method is called when your extension is activate
  *  your extension is activated the very first time the command is executed
  */
 export function activate(context: vscode.ExtensionContext) {
-// TODO: make this configurable
-const clangdPath = '/usr/bin/clangd';
+const clangdPath = getConfig('path');
+const clangdArgs = getConfig('arguments');
 
-const serverOptions: vscodelc.ServerOptions = { command: clangdPath };
+const serverOptions: vscodelc.ServerOptions = { command: clangdPath, args: 
clangdArgs };
 
 const clientOptions: vscodelc.LanguageClientOptions = {
 // Register the server for C/C++ files
@@ -39,4 +49,4 @@
 const disposable = clangdClient.start();
 
 context.subscriptions.push(disposable, 
vscode.commands.registerCommand('clangd.applyFix', applyTextEdits));
-}
\ No newline at end of file
+}
Index: clangd/clients/clangd-vscode/package.json
===
--- clangd/clients/clangd-vscode/package.json
+++ clangd/clients/clangd-vscode/package.json
@@ -33,5 +33,26 @@
 "mocha": "^2.3.3",
 "@types/node": "^6.0.40",
 "@types/mocha": "^2.2.32"
+},
+"contributes": {
+"configuration": {
+"type": "object",
+"title": "clangd configuration",
+"properties": {
+"clangd.path": {
+"type": "string",
+"default": "clangd",
+"description": "The path to clangd executable, e.g.: 
/usr/bin/clangd"
+},
+"clangd.arguments": {
+"type": "array",
+"default": [],
+"items": {
+"type": "string"
+},
+"description": "Arguments for clangd server"
+}
+}
+}
 }
-}
\ No newline at end of file
+}


Index: clangd/clients/clangd-vscode/src/extension.ts
===
--- clangd/clients/clangd-vscode/src/extension.ts
+++ clangd/clients/clangd-vscode/src/extension.ts
@@ -2,14 +2,24 @@
 import * as vscodelc from 'vscode-languageclient';
 
 /**
+ * Method to get workspace configuration option
+ * @param option name of the option (e.g. for clangd.path should be path)
+ * @param defaultValue default value to return if option is not set
+ */
+function getConfig(option: string, defaultValue?: any) : T {
+const config = vscode.workspace.getConfiguration('clangd');
+return config.get(option, defaultValue);
+}
+
+/**
  *  this method is called when your extension is activate
  *  your extension is activated the very first time the command is executed
  */
 export function activate(context: vscode.ExtensionContext) {
-// TODO: make this configurable
-const clangdPath = '/usr/bin/clangd';
+const clangdPath = getConfig('path');
+const clangdArgs = getConfig('arguments');
 
-const serverOptions: vscodelc.ServerOptions = { command: clangdPath };
+const serverOptions: vscodelc.ServerOptions = { command: clangdPath, args: clangdArgs };
 
 const clientOptions: vscodelc.LanguageClientOptions = {
 // Register the server for C/C++ files
@@ -39,4 +49,4 @@
 const disposable = clangdClient.start();
 
 context.subscriptions.push(disposable, vscode.commands.registerCommand('clangd.applyFix', applyTextEdits));
-}
\ No newline at end of file
+}
Index: clangd/clients/clangd-vscode/package.json
===
--- clangd/clients/clangd-vscode/package.json
+++ clangd/clients/clangd-vscode/package.json
@@ -33,5 +33,26 @@
 "mocha": "^2.3.3",
 "@types/node": "^6.0.40",
 "@types/mocha": "^2.2.32"
+},
+"contributes":