Browse Source

Language client: autocomplete documentation now supports markdown

pipelines/235045657
eidheim 6 years ago
parent
commit
f2dee85d0f
  1. 9
      src/autocomplete.cc
  2. 2
      src/autocomplete.h
  3. 9
      src/source_clang.cc
  4. 9
      src/source_generic.cc
  5. 75
      src/source_language_protocol.cc
  6. 10
      src/source_language_protocol.h

9
src/autocomplete.cc

@ -156,16 +156,15 @@ void Autocomplete::setup_dialog() {
on_changed(index, text); on_changed(index, text);
auto tooltip = get_tooltip(index); auto set_buffer = set_tooltip_buffer(index);
if(tooltip.empty()) if(!set_buffer)
tooltips.hide(); tooltips.hide();
else { else {
tooltips.clear(); tooltips.clear();
auto iter = CompletionDialog::get()->start_mark->get_iter(); auto iter = CompletionDialog::get()->start_mark->get_iter();
tooltips.emplace_back(view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter), [tooltip_text = std::move(tooltip)](Tooltip &tooltip) { tooltips.emplace_back(view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter), [set_buffer = std::move(set_buffer)](Tooltip &tooltip) {
tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), tooltip_text); set_buffer(tooltip);
}); });
tooltips.show(true); tooltips.show(true);
} }
}; };

2
src/autocomplete.h

@ -49,7 +49,7 @@ public:
std::function<void(unsigned int, const std::string &)> on_changed = [](unsigned int index, const std::string &text) {}; std::function<void(unsigned int, const std::string &)> on_changed = [](unsigned int index, const std::string &text) {};
std::function<void(unsigned int, const std::string &, bool)> on_select = [](unsigned int index, const std::string &text, bool hide_window) {}; std::function<void(unsigned int, const std::string &, bool)> on_select = [](unsigned int index, const std::string &text, bool hide_window) {};
std::function<std::string(unsigned int)> get_tooltip = [](unsigned int index) { return std::string(); }; std::function<std::function<void(Tooltip &tooltip)>(unsigned int)> set_tooltip_buffer = [](unsigned int index) { return nullptr; };
Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool pass_buffer_and_strip_word); Autocomplete(Gtk::TextView *view, bool &interactive_completion, guint &last_keyval, bool pass_buffer_and_strip_word);

9
src/source_clang.cc

@ -908,8 +908,13 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa
} }
}; };
autocomplete.get_tooltip = [this](unsigned int index) { autocomplete.set_tooltip_buffer = [this](unsigned int index) -> std::function<void(Tooltip & tooltip)> {
return completion_strings[index] ? clangmm::to_string(clang_getCompletionBriefComment(completion_strings[index])) : snippet_comments[index]; auto tooltip_str = completion_strings[index] ? clangmm::to_string(clang_getCompletionBriefComment(completion_strings[index])) : snippet_comments[index];
if(tooltip_str.empty())
return nullptr;
return [tooltip_str = std::move(tooltip_str)](Tooltip &tooltip) {
tooltip.insert_with_links_tagged(tooltip_str);
};
}; };
} }

9
src/source_generic.cc

@ -310,7 +310,12 @@ void Source::GenericView::setup_autocomplete() {
get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert); get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert);
}; };
autocomplete.get_tooltip = [this](unsigned int index) { autocomplete.set_tooltip_buffer = [this](unsigned int index) -> std::function<void(Tooltip & tooltip)> {
return autocomplete_comment[index]; auto tooltip_str = autocomplete_comment[index];
if(tooltip_str.empty())
return nullptr;
return [tooltip_str = std::move(tooltip_str)](Tooltip &tooltip) {
tooltip.insert_with_links_tagged(tooltip_str);
};
}; };
} }

75
src/source_language_protocol.cc

@ -1230,8 +1230,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
}; };
autocomplete->reparse = [this] { autocomplete->reparse = [this] {
autocomplete_comment.clear(); autocomplete_rows.clear();
autocomplete_insert.clear();
}; };
if(capabilities.signature_help) { if(capabilities.signature_help) {
@ -1355,14 +1354,12 @@ void Source::LanguageProtocolView::setup_autocomplete() {
}; };
autocomplete->on_add_rows_error = [this] { autocomplete->on_add_rows_error = [this] {
autocomplete_comment.clear(); autocomplete_rows.clear();
autocomplete_insert.clear();
}; };
autocomplete->add_rows = [this](std::string &buffer, int line_number, int column) { autocomplete->add_rows = [this](std::string &buffer, int line_number, int column) {
if(autocomplete->state == Autocomplete::State::starting) { if(autocomplete->state == Autocomplete::State::starting) {
autocomplete_comment.clear(); autocomplete_rows.clear();
autocomplete_insert.clear();
std::promise<void> result_processed; std::promise<void> result_processed;
if(autocomplete_show_arguments) { if(autocomplete_show_arguments) {
if(!capabilities.signature_help) if(!capabilities.signature_help)
@ -1375,10 +1372,20 @@ void Source::LanguageProtocolView::setup_autocomplete() {
for(auto parameter_it = parameters.begin(); parameter_it != parameters.end(); ++parameter_it) { for(auto parameter_it = parameters.begin(); parameter_it != parameters.end(); ++parameter_it) {
auto label = parameter_it->second.get<std::string>("label", ""); auto label = parameter_it->second.get<std::string>("label", "");
auto insert = label; auto insert = label;
auto documentation = parameter_it->second.get<std::string>("documentation", ""); auto plaintext = parameter_it->second.get<std::string>("documentation", "");
std::string markdown;
if(plaintext.empty()) {
auto documentation = parameter_it->second.get_child_optional("documentation");
if(documentation) {
auto kind = documentation->get<std::string>("kind", "");
if(kind == "markdown")
markdown = documentation->get<std::string>("value", "");
else
plaintext = documentation->get<std::string>("value", "");
}
}
autocomplete->rows.emplace_back(std::move(label)); autocomplete->rows.emplace_back(std::move(label));
autocomplete_insert.emplace_back(std::move(insert)); autocomplete_rows.emplace_back(AutocompleteRow{std::move(insert), std::move(plaintext), std::move(markdown)});
autocomplete_comment.emplace_back(std::move(documentation));
} }
} }
} }
@ -1401,9 +1408,18 @@ void Source::LanguageProtocolView::setup_autocomplete() {
for(auto it = begin; it != end; ++it) { for(auto it = begin; it != end; ++it) {
auto label = it->second.get<std::string>("label", ""); auto label = it->second.get<std::string>("label", "");
auto detail = it->second.get<std::string>("detail", ""); auto detail = it->second.get<std::string>("detail", "");
auto documentation = it->second.get<std::string>("documentation", ""); auto plaintext = it->second.get<std::string>("documentation", "");
if(documentation.empty()) std::string markdown;
documentation = it->second.get<std::string>("documentation.value", ""); if(plaintext.empty()) {
auto documentation = it->second.get_child_optional("documentation");
if(documentation) {
auto kind = documentation->get<std::string>("kind", "");
if(kind == "markdown")
markdown = documentation->get<std::string>("value", "");
else
plaintext = documentation->get<std::string>("value", "");
}
}
auto insert = it->second.get<std::string>("insertText", ""); auto insert = it->second.get<std::string>("insertText", "");
if(insert.empty()) if(insert.empty())
insert = it->second.get<std::string>("textEdit.newText", ""); insert = it->second.get<std::string>("textEdit.newText", "");
@ -1442,13 +1458,12 @@ void Source::LanguageProtocolView::setup_autocomplete() {
} }
if(prefix.compare(0, prefix.size(), label, 0, prefix.size()) == 0) { if(prefix.compare(0, prefix.size(), label, 0, prefix.size()) == 0) {
autocomplete->rows.emplace_back(std::move(label)); autocomplete->rows.emplace_back(std::move(label));
autocomplete_comment.emplace_back(std::move(detail)); if(!plaintext.empty() && detail != plaintext) {
if(!documentation.empty() && documentation != autocomplete_comment.back()) { if(!detail.empty())
if(!autocomplete_comment.back().empty()) detail += "\n\n";
autocomplete_comment.back() += "\n\n"; detail += plaintext;
autocomplete_comment.back() += documentation;
} }
autocomplete_insert.emplace_back(std::move(insert)); autocomplete_rows.emplace_back(AutocompleteRow{std::move(insert), std::move(detail), std::move(markdown)});
} }
} }
} }
@ -1464,8 +1479,7 @@ void Source::LanguageProtocolView::setup_autocomplete() {
for(auto &snippet : *snippets) { for(auto &snippet : *snippets) {
if(prefix.compare(0, prefix.size(), snippet.prefix, 0, prefix.size()) == 0) { if(prefix.compare(0, prefix.size(), snippet.prefix, 0, prefix.size()) == 0) {
autocomplete->rows.emplace_back(snippet.prefix); autocomplete->rows.emplace_back(snippet.prefix);
autocomplete_insert.emplace_back(snippet.body); autocomplete_rows.emplace_back(AutocompleteRow{snippet.body, snippet.description, {}});
autocomplete_comment.emplace_back(snippet.description);
} }
} }
} }
@ -1483,12 +1497,11 @@ void Source::LanguageProtocolView::setup_autocomplete() {
}; };
autocomplete->on_hide = [this] { autocomplete->on_hide = [this] {
autocomplete_comment.clear(); autocomplete_rows.clear();
autocomplete_insert.clear();
}; };
autocomplete->on_select = [this](unsigned int index, const std::string &text, bool hide_window) { autocomplete->on_select = [this](unsigned int index, const std::string &text, bool hide_window) {
Glib::ustring insert = hide_window ? autocomplete_insert[index] : text; Glib::ustring insert = hide_window ? autocomplete_rows[index].insert : text;
get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter());
@ -1525,8 +1538,20 @@ void Source::LanguageProtocolView::setup_autocomplete() {
get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert); get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), insert);
}; };
autocomplete->get_tooltip = [this](unsigned int index) { autocomplete->set_tooltip_buffer = [this](unsigned int index) -> std::function<void(Tooltip & tooltip)> {
return autocomplete_comment[index]; auto plaintext = autocomplete_rows[index].plaintext;
auto markdown = autocomplete_rows[index].markdown;
if(plaintext.empty() && markdown.empty())
return nullptr;
return [plaintext = std::move(plaintext), markdown = std::move(markdown)](Tooltip &tooltip) {
if(!plaintext.empty())
tooltip.insert_with_links_tagged(plaintext);
if(!markdown.empty()) {
if(!plaintext.empty())
tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), "\n\n");
tooltip.insert_markdown(markdown);
}
};
}; };
} }

10
src/source_language_protocol.h

@ -192,8 +192,14 @@ namespace Source {
std::unique_ptr<Autocomplete> autocomplete; std::unique_ptr<Autocomplete> autocomplete;
void setup_signals(); void setup_signals();
void setup_autocomplete(); void setup_autocomplete();
std::vector<std::string> autocomplete_comment;
std::vector<std::string> autocomplete_insert; struct AutocompleteRow {
std::string insert;
std::string plaintext;
std::string markdown;
};
std::vector<AutocompleteRow> autocomplete_rows;
std::atomic<bool> autocomplete_enable_snippets = {false}; std::atomic<bool> autocomplete_enable_snippets = {false};
bool autocomplete_show_arguments = false; bool autocomplete_show_arguments = false;
sigc::connection autocomplete_delayed_show_arguments_connection; sigc::connection autocomplete_delayed_show_arguments_connection;

Loading…
Cancel
Save