Change completions option docstring element to be an arbitrary command

We can have the previous behaviour by just passing the docstring to
`info -placement menu`.
This commit is contained in:
Maxime Coste 2019-04-15 17:42:58 +02:00
parent 02fc42a12a
commit 9118a18d5d
7 changed files with 28 additions and 18 deletions

View File

@ -85,11 +85,15 @@ External completions are provided using an option to store completion, which
have the following format. 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 the first element of this string list specify where and when this completion
applies, the others are a triplet `<completion text>|<docstring>|<menu text>` applies, the others are a triplet `<completion text>|<select cmd>|<menu text>`
The select command is executed whenever this menu item gets selected, and
is usually used to display an item specific documentation with
`info -placement menu '<menu item description>'`
The menu text is a markup string (see <<faces#markup-strings,`:doc faces The menu text is a markup string (see <<faces#markup-strings,`:doc faces
markup-strings`>>), so it can contain `{face}` directives. markup-strings`>>), so it can contain `{face}` directives.

View File

@ -111,12 +111,18 @@ are exclusively available to built-in options.
`set -add` appends the new spec to the list `set -add` appends the new spec to the list
*completions*:: *completions*::
a list of `<text>|<docstring>|<menu text>` candidates, a list of `<text>|<select cmd>|<menu text>` candidates,
except for the first element which follows the except for the first element which follows the
`<line>.<column>[+<length>]@<timestamp>` format to define where the `<line>.<column>[+<length>]@<timestamp>` format to define where the
completion apply in the buffer. Markup (see completion apply in the buffer.
<<faces#markup-strings,`:doc faces markup-strings`>>) can be used in the
menu text. 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 <<faces#markup-strings,`:doc faces markup-strings`>>)
`set -add` adds a new completion to the list `set -add` adds a new completion to the list
*enum(value1|value2|...)*:: *enum(value1|value2|...)*::

View File

@ -57,6 +57,7 @@ The syntaxic errors detected during parsing are shown when auto-diagnostics are
desc=$4 ? $3 "\n" $4 : $3 desc=$4 ? $3 "\n" $4 : $3
gsub(/~/, "~~", desc) gsub(/~/, "~~", desc)
gsub(/!/, "!!", desc)
gsub(/\|/, "\\|", desc) gsub(/\|/, "\\|", desc)
if (id in docstrings) if (id in docstrings)
docstrings[id]=docstrings[id] "\n" desc 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(/(^|[^[:alnum:]_])(operator|new|delete)($|[^{}_[:alnum:]]+)/, "{keyword}&{}", menu)
gsub(/(^|[[:space:]])(int|size_t|bool|char|unsigned|signed|long)($|[[:space:]])/, "{type}&{}", menu) gsub(/(^|[[:space:]])(int|size_t|bool|char|unsigned|signed|long)($|[[:space:]])/, "{type}&{}", menu)
gsub(/[^{}_[:alnum:]]+/, "{operator}&{}", 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' printf %s\\n "evaluate-commands -client ${kak_client} echo 'clang completion done'

View File

@ -21,7 +21,7 @@ define-command jedi-complete -docstring "Complete the current selection" %{
compl=$(python 2> "${dir}/fifo" <<-END compl=$(python 2> "${dir}/fifo" <<-END
import jedi import jedi
script=jedi.Script(open('$dir/buf', 'r').read(), $kak_cursor_line, $kak_cursor_column - 1, '$kak_buffile') 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 END
) )
printf %s\\n "evaluate-commands -client ${kak_client} %~echo completed; set-option %{buffer=${kak_buffile}} jedi_completions ${header} ${compl}~" | kak -p ${kak_session} printf %s\\n "evaluate-commands -client ${kak_client} %~echo completed; set-option %{buffer=${kak_buffile}} jedi_completions ${header} ${compl}~" | kak -p ${kak_session}

View File

@ -24,6 +24,7 @@ define-command racer-complete -docstring "Complete the current selection with ra
desc = substr($9, 2, length($9) - 2) desc = substr($9, 2, length($9) - 2)
gsub(/\|/, "\\|", desc) gsub(/\|/, "\\|", desc)
gsub(/\\n/, "\n", desc) gsub(/\\n/, "\n", desc)
gsub(/!/, "!!", desc)
menu = $8 menu = $8
sub(/^pub /, "", menu) sub(/^pub /, "", menu)
gsub(/\|/, "\\|", menu) gsub(/\|/, "\\|", menu)
@ -66,7 +67,7 @@ define-command racer-complete -docstring "Complete the current selection with ra
} else { } else {
menu = "{default+F}" word "{default+d} " menu menu = "{default+F}" word "{default+d} " menu
} }
candidate = word "|" desc "|" menu candidate = word "|info -style menu %!" desc "!|" menu
gsub(/:/, "\\:", candidate) gsub(/:/, "\\:", candidate)
print candidate print candidate
}' }'

View File

@ -3,6 +3,7 @@
#include "buffer_manager.hh" #include "buffer_manager.hh"
#include "buffer_utils.hh" #include "buffer_utils.hh"
#include "client.hh" #include "client.hh"
#include "command_manager.hh"
#include "changes.hh" #include "changes.hh"
#include "context.hh" #include "context.hh"
#include "display_buffer.hh" #include "display_buffer.hh"
@ -287,7 +288,7 @@ InsertCompletion complete_option(const SelectionList& sels,
using RankedMatch::operator==; using RankedMatch::operator==;
using RankedMatch::operator<; using RankedMatch::operator<;
StringView docstring; StringView on_select;
DisplayLine menu_entry; DisplayLine menu_entry;
}; };
@ -297,7 +298,7 @@ InsertCompletion complete_option(const SelectionList& sels,
{ {
if (RankedMatchAndInfo match{std::get<0>(candidate), query}) 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); auto& menu = std::get<2>(candidate);
match.menu_entry = not menu.empty() ? match.menu_entry = not menu.empty() ?
parse_display_line(expand_tabs(menu, tabstop, column), faces) 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) while (candidates.size() < max_count and first != last)
{ {
if (candidates.empty() or candidates.back().completion != first->candidate()) 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::move(first->menu_entry) });
std::pop_heap(first, last--, greater); std::pop_heap(first, last--, greater);
} }
@ -437,11 +438,6 @@ void InsertCompleter::select(int index, bool relative, Vector<Key>& keystrokes)
if (m_context.has_client()) if (m_context.has_client())
{ {
m_context.client().menu_select(m_current_candidate); 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) for (auto i = 0_byte; i < prefix_len; ++i)
@ -457,6 +453,8 @@ void InsertCompleter::select(int index, bool relative, Vector<Key>& keystrokes)
StringView{} : candidate.completion; StringView{} : candidate.completion;
m_context.hooks().run_hook(Hook::InsertCompletionSelect, param, m_context); 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) void InsertCompleter::update(bool allow_implicit)

View File

@ -58,7 +58,7 @@ struct InsertCompletion
struct Candidate struct Candidate
{ {
String completion; String completion;
String docstring; String on_select;
DisplayLine menu_entry; DisplayLine menu_entry;
bool operator==(const Candidate& other) const { return completion == other.completion; } bool operator==(const Candidate& other) const { return completion == other.completion; }