Skip to content

Commit eefaad7

Browse files
scturtleMaskRay
authored andcommitted
Preprocessor keyword completion.
1 parent 9ba8767 commit eefaad7

File tree

1 file changed

+47
-16
lines changed

1 file changed

+47
-16
lines changed

src/messages/text_document_completion.cc

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ void DecorateIncludePaths(const std::smatch& match,
9898

9999
struct ParseIncludeLineResult {
100100
bool ok;
101+
std::string keyword;
102+
std::string quote;
101103
std::string pattern;
102104
std::smatch match;
103105
};
@@ -115,8 +117,28 @@ ParseIncludeLineResult ParseIncludeLine(const std::string& line) {
115117
"(.*)"); // [7]: suffix after quote char
116118
std::smatch match;
117119
bool ok = std::regex_match(line, match, pattern);
118-
std::string text = match[3].str() + match[6].str();
119-
return {ok, text, match};
120+
return {ok, match[3], match[5], match[6], match};
121+
}
122+
123+
static const std::vector<std::string> preprocessorKeywords = {
124+
"define", "undef", "include", "if", "ifdef", "ifndef",
125+
"else", "elif", "endif", "line", "error", "pragma"};
126+
127+
std::vector<lsCompletionItem> preprocessorKeywordCompletionItems(
128+
const std::smatch& match) {
129+
std::vector<lsCompletionItem> items;
130+
for (auto& keyword : preprocessorKeywords) {
131+
lsCompletionItem item;
132+
item.label = keyword;
133+
item.priority_ = (keyword == "include" ? 2 : 1);
134+
item.textEdit = lsTextEdit();
135+
std::string space = (keyword == "else" || keyword == "endif") ? "" : " ";
136+
item.textEdit->newText = match[1].str() + "#" + match[2].str() + keyword +
137+
space + match[6].str();
138+
item.insertTextFormat = lsInsertTextFormat::PlainText;
139+
items.push_back(item);
140+
}
141+
return items;
120142
}
121143

122144
template <typename T>
@@ -298,22 +320,31 @@ struct Handler_TextDocumentCompletion : MessageHandler {
298320
Out_TextDocumentComplete out;
299321
out.id = request->id;
300322

301-
{
302-
std::unique_lock<std::mutex> lock(
303-
include_complete->completion_items_mutex, std::defer_lock);
304-
if (include_complete->is_scanning)
305-
lock.lock();
306-
out.result.items = include_complete->completion_items;
323+
if (result.quote.empty() && result.pattern.empty()) {
324+
// no quote or path of file, do preprocessor keyword completion
325+
if (!std::any_of(preprocessorKeywords.begin(),
326+
preprocessorKeywords.end(),
327+
[&result](std::string_view k) {
328+
return k == result.keyword;
329+
})) {
330+
out.result.items = preprocessorKeywordCompletionItems(result.match);
331+
FilterAndSortCompletionResponse(&out, result.keyword,
332+
config->completion.filterAndSort);
333+
}
334+
} else if (result.keyword.compare("include") == 0) {
335+
{
336+
// do include completion
337+
std::unique_lock<std::mutex> lock(
338+
include_complete->completion_items_mutex, std::defer_lock);
339+
if (include_complete->is_scanning)
340+
lock.lock();
341+
out.result.items = include_complete->completion_items;
342+
}
343+
FilterAndSortCompletionResponse(&out, result.pattern,
344+
config->completion.filterAndSort);
345+
DecorateIncludePaths(result.match, &out.result.items);
307346
}
308347

309-
// Needed by |FilterAndSortCompletionResponse|.
310-
for (lsCompletionItem& item : out.result.items)
311-
item.filterText = "include" + item.label;
312-
313-
FilterAndSortCompletionResponse(&out, result.pattern,
314-
config->completion.filterAndSort);
315-
DecorateIncludePaths(result.match, &out.result.items);
316-
317348
for (lsCompletionItem& item : out.result.items) {
318349
item.textEdit->range.start.line = request->params.position.line;
319350
item.textEdit->range.start.character = 0;

0 commit comments

Comments
 (0)