diff --git a/doc/interfacing.asciidoc b/doc/interfacing.asciidoc index 5ab5f878..38fbe696 100644 --- a/doc/interfacing.asciidoc +++ b/doc/interfacing.asciidoc @@ -85,11 +85,15 @@ External completions are provided using an option to store completion, which have the following format. ---- -line.column[+len]@timestamp candidate1|desc1|menu1 candidate2|desc2|menu2 ... +line.column[+len]@timestamp candidate1|select1|menu1 candidate2|select2|menu2 ... ---- the first element of this string list specify where and when this completion -applies, the others are a triplet `||` +applies, the others are a triplet `||` candidates, except for the first element which follows the `.[+]@` format to define where the - completion apply in the buffer. Markup (see - <>) can be used in the - menu text. + completion apply in the buffer. + + Select commands are arbitrary kakoune commands that will be executed + each time the element is selected in the menu. The common use case is + to display element specific documentation. + + Markup can be used in the menu text. + (see <>) + `set -add` adds a new completion to the list *enum(value1|value2|...)*:: diff --git a/rc/tools/clang.kak b/rc/tools/clang.kak index 310cca06..f513c626 100644 --- a/rc/tools/clang.kak +++ b/rc/tools/clang.kak @@ -57,6 +57,7 @@ The syntaxic errors detected during parsing are shown when auto-diagnostics are desc=$4 ? $3 "\n" $4 : $3 gsub(/~/, "~~", desc) + gsub(/!/, "!!", desc) gsub(/\|/, "\\|", desc) if (id in docstrings) docstrings[id]=docstrings[id] "\n" desc @@ -69,7 +70,7 @@ The syntaxic errors detected during parsing are shown when auto-diagnostics are gsub(/(^|[^[:alnum:]_])(operator|new|delete)($|[^{}_[:alnum:]]+)/, "{keyword}&{}", menu) gsub(/(^|[[:space:]])(int|size_t|bool|char|unsigned|signed|long)($|[[:space:]])/, "{type}&{}", menu) gsub(/[^{}_[:alnum:]]+/, "{operator}&{}", menu) - printf "%%~%s|%s|%s~ ", id, docstrings[id], menu + printf "%%~%s|info -style menu %!%s!|%s~ ", id, docstrings[id], menu } }') printf %s\\n "evaluate-commands -client ${kak_client} echo 'clang completion done' diff --git a/rc/tools/python/jedi.kak b/rc/tools/python/jedi.kak index a0fe9449..f86a20f2 100644 --- a/rc/tools/python/jedi.kak +++ b/rc/tools/python/jedi.kak @@ -21,7 +21,7 @@ define-command jedi-complete -docstring "Complete the current selection" %{ compl=$(python 2> "${dir}/fifo" <<-END import jedi script=jedi.Script(open('$dir/buf', 'r').read(), $kak_cursor_line, $kak_cursor_column - 1, '$kak_buffile') - print(' '.join(["'" + (str(c.name).replace("|", "\\|") + "|" + str(c.docstring()).replace("|", "\\|") + "|" + str(c.name).replace("|", "\\|")).replace("~", "~~").replace("'", "''") + "'" for c in script.completions()])) + print(' '.join(["'" + (str(c.name).replace("|", "\\|") + "|info -style menu %!" + str(c.docstring()).replace("|", "\\|").replace("!", "!!") + "!|" + str(c.name).replace("|", "\\|")).replace("~", "~~").replace("'", "''") + "'" for c in script.completions()])) END ) printf %s\\n "evaluate-commands -client ${kak_client} %~echo completed; set-option %{buffer=${kak_buffile}} jedi_completions ${header} ${compl}~" | kak -p ${kak_session} diff --git a/rc/tools/rust/racer.kak b/rc/tools/rust/racer.kak index 2371c597..28890431 100644 --- a/rc/tools/rust/racer.kak +++ b/rc/tools/rust/racer.kak @@ -24,6 +24,7 @@ define-command racer-complete -docstring "Complete the current selection with ra desc = substr($9, 2, length($9) - 2) gsub(/\|/, "\\|", desc) gsub(/\\n/, "\n", desc) + gsub(/!/, "!!", desc) menu = $8 sub(/^pub /, "", menu) gsub(/\|/, "\\|", menu) @@ -66,7 +67,7 @@ define-command racer-complete -docstring "Complete the current selection with ra } else { menu = "{default+F}" word "{default+d} " menu } - candidate = word "|" desc "|" menu + candidate = word "|info -style menu %!" desc "!|" menu gsub(/:/, "\\:", candidate) print candidate }' diff --git a/src/insert_completer.cc b/src/insert_completer.cc index 2c8479a6..3e44d325 100644 --- a/src/insert_completer.cc +++ b/src/insert_completer.cc @@ -3,6 +3,7 @@ #include "buffer_manager.hh" #include "buffer_utils.hh" #include "client.hh" +#include "command_manager.hh" #include "changes.hh" #include "context.hh" #include "display_buffer.hh" @@ -287,7 +288,7 @@ InsertCompletion complete_option(const SelectionList& sels, using RankedMatch::operator==; using RankedMatch::operator<; - StringView docstring; + StringView on_select; DisplayLine menu_entry; }; @@ -297,7 +298,7 @@ InsertCompletion complete_option(const SelectionList& sels, { if (RankedMatchAndInfo match{std::get<0>(candidate), query}) { - match.docstring = std::get<1>(candidate); + match.on_select = std::get<1>(candidate); auto& menu = std::get<2>(candidate); match.menu_entry = not menu.empty() ? parse_display_line(expand_tabs(menu, tabstop, column), faces) @@ -318,7 +319,7 @@ InsertCompletion complete_option(const SelectionList& sels, while (candidates.size() < max_count and first != last) { if (candidates.empty() or candidates.back().completion != first->candidate()) - candidates.push_back({ first->candidate().str(), first->docstring.str(), + candidates.push_back({ first->candidate().str(), first->on_select.str(), std::move(first->menu_entry) }); std::pop_heap(first, last--, greater); } @@ -437,11 +438,6 @@ void InsertCompleter::select(int index, bool relative, Vector& keystrokes) if (m_context.has_client()) { m_context.client().menu_select(m_current_candidate); - if (not candidate.docstring.empty()) - m_context.client().info_show(candidate.completion, candidate.docstring, - {}, InfoStyle::MenuDoc); - else - m_context.client().info_hide(); } for (auto i = 0_byte; i < prefix_len; ++i) @@ -457,6 +453,8 @@ void InsertCompleter::select(int index, bool relative, Vector& keystrokes) StringView{} : candidate.completion; m_context.hooks().run_hook(Hook::InsertCompletionSelect, param, m_context); } + if (not candidate.on_select.empty()) + CommandManager::instance().execute(candidate.on_select, m_context); } void InsertCompleter::update(bool allow_implicit) diff --git a/src/insert_completer.hh b/src/insert_completer.hh index 305435a9..1270d732 100644 --- a/src/insert_completer.hh +++ b/src/insert_completer.hh @@ -58,7 +58,7 @@ struct InsertCompletion struct Candidate { String completion; - String docstring; + String on_select; DisplayLine menu_entry; bool operator==(const Candidate& other) const { return completion == other.completion; }