Skip to content

Commit

Permalink
Preprocessor keyword completion.
Browse files Browse the repository at this point in the history
  • Loading branch information
scturtle authored and jacobdufault committed Mar 24, 2018
1 parent d87afce commit ddc318e
Showing 1 changed file with 47 additions and 16 deletions.
63 changes: 47 additions & 16 deletions src/messages/text_document_completion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ void DecorateIncludePaths(const std::smatch& match,

struct ParseIncludeLineResult {
bool ok;
std::string keyword;
std::string quote;
std::string pattern;
std::smatch match;
};
Expand All @@ -115,8 +117,28 @@ ParseIncludeLineResult ParseIncludeLine(const std::string& line) {
"(.*)"); // [7]: suffix after quote char
std::smatch match;
bool ok = std::regex_match(line, match, pattern);
std::string text = match[3].str() + match[6].str();
return {ok, text, match};
return {ok, match[3], match[5], match[6], match};
}

static const std::vector<std::string> preprocessorKeywords = {
"define", "undef", "include", "if", "ifdef", "ifndef",
"else", "elif", "endif", "line", "error", "pragma"};

std::vector<lsCompletionItem> preprocessorKeywordCompletionItems(
const std::smatch& match) {
std::vector<lsCompletionItem> items;
for (auto& keyword : preprocessorKeywords) {
lsCompletionItem item;
item.label = keyword;
item.priority_ = (keyword == "include" ? 2 : 1);
item.textEdit = lsTextEdit();
std::string space = (keyword == "else" || keyword == "endif") ? "" : " ";
item.textEdit->newText = match[1].str() + "#" + match[2].str() + keyword +
space + match[6].str();
item.insertTextFormat = lsInsertTextFormat::PlainText;
items.push_back(item);
}
return items;
}

template <typename T>
Expand Down Expand Up @@ -298,22 +320,31 @@ struct Handler_TextDocumentCompletion : MessageHandler {
Out_TextDocumentComplete out;
out.id = request->id;

{
std::unique_lock<std::mutex> lock(
include_complete->completion_items_mutex, std::defer_lock);
if (include_complete->is_scanning)
lock.lock();
out.result.items = include_complete->completion_items;
if (result.quote.empty() && result.pattern.empty()) {
// no quote or path of file, do preprocessor keyword completion
if (!std::any_of(preprocessorKeywords.begin(),
preprocessorKeywords.end(),
[&result](std::string_view k) {
return k == result.keyword;
})) {
out.result.items = preprocessorKeywordCompletionItems(result.match);
FilterAndSortCompletionResponse(&out, result.keyword,
config->completion.filterAndSort);
}
} else if (result.keyword.compare("include") == 0) {
{
// do include completion
std::unique_lock<std::mutex> lock(
include_complete->completion_items_mutex, std::defer_lock);
if (include_complete->is_scanning)
lock.lock();
out.result.items = include_complete->completion_items;
}
FilterAndSortCompletionResponse(&out, result.pattern,
config->completion.filterAndSort);
DecorateIncludePaths(result.match, &out.result.items);
}

// Needed by |FilterAndSortCompletionResponse|.
for (lsCompletionItem& item : out.result.items)
item.filterText = "include" + item.label;

FilterAndSortCompletionResponse(&out, result.pattern,
config->completion.filterAndSort);
DecorateIncludePaths(result.match, &out.result.items);

for (lsCompletionItem& item : out.result.items) {
item.textEdit->range.start.line = request->params.position.line;
item.textEdit->range.start.character = 0;
Expand Down

0 comments on commit ddc318e

Please sign in to comment.