Use a specific option type completions for insert completion

Fix escaping in jedi.kak as well
This commit is contained in:
Maxime Coste 2016-04-01 01:27:23 +01:00
parent e8c2adf17f
commit b5a68307ba
7 changed files with 51 additions and 38 deletions

View File

@ -1,7 +1,7 @@
decl str clang_options
decl -hidden str clang_tmp_dir
decl -hidden str-list clang_completions
decl -hidden completions clang_completions
decl -hidden line-flags clang_flags
decl -hidden str clang_errors
@ -50,8 +50,10 @@ def clang-parse -params 0..1 -docstring "Parse the contents of the current buffe
gsub(/ +$/, "", $3)
id=substr($2, 1, length($2)-1)
gsub(/:/, "\\:", id)
gsub(/\|/, "\\\|", id)
desc=$4 ? $3 "\\n" $4 : $3
gsub(/:/, "\\:", desc)
gsub(/\|/, "\\\|", desc)
if (id in docstrings)
docstrings[id]=docstrings[id] "\\n" desc
else
@ -64,7 +66,7 @@ def clang-parse -params 0..1 -docstring "Parse the contents of the current buffe
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)
print id "@" docstrings[id] "@" menu
print id "|" docstrings[id] "|" menu
}
}' | sort | paste -s -d ':' | sed -e "s/\\\\n/\\n/g; s/'/\\\\'/g")
echo "eval -client ${kak_client} echo 'clang completion done'

View File

@ -1,5 +1,5 @@
decl -hidden str jedi_tmp_dir
decl -hidden str-list jedi_completions
decl -hidden completions jedi_completions
decl str-list jedi_python_path ''
def jedi-complete -docstring "Complete the current selection with jedi" %{
@ -20,10 +20,11 @@ def jedi-complete -docstring "Complete the current selection with jedi" %{
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) + "@" + str(c.docstring()).replace(":", "\\:") for c in script.completions()])
print ':'.join([(str(c.name).replace("|", "\\|") + "|" + str(c.docstring()).replace("|", "\\|")).replace(":", "\\:") + "|" + str(c.name).replace("|", "\\|") for c in script.completions()]).replace("'", r"\\\\'")
END
)
echo "eval -client ${kak_client} %[ echo completed; set 'buffer=${kak_buffile}' jedi_completions %[${header}:${compl}] ]" | kak -p ${kak_session}
printf %s "${compl}" > /tmp/kak-jedi-out
printf %s "eval -client ${kak_client} 'echo completed; set %{buffer=${kak_buffile}} jedi_completions \'${header}:${compl}\''" | kak -p ${kak_session}
rm -r ${dir}
) > /dev/null 2>&1 < /dev/null &
}

View File

@ -19,6 +19,7 @@
#include "parameters_parser.hh"
#include "ranked_match.hh"
#include "register_manager.hh"
#include "insert_completer.hh"
#include "remote.hh"
#include "shell_manager.hh"
#include "string.hh"
@ -1191,6 +1192,7 @@ const CommandDesc declare_option_cmd = {
" regex: regular expression\n"
" int-list: list of integers\n"
" str-list: list of character strings\n"
" completions: list of completion candidates"
" line-flags: list of line flags\n"
" range-faces: list of range faces\n",
ParameterDesc{
@ -1224,6 +1226,8 @@ const CommandDesc declare_option_cmd = {
opt = &reg.declare_option<Vector<int, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
else if (parser[0] == "str-list")
opt = &reg.declare_option<Vector<String, MemoryDomain::Options>>(parser[1], docstring, {}, flags);
else if (parser[0] == "completions")
opt = &reg.declare_option<CompletionList>(parser[1], docstring, {}, flags);
else if (parser[0] == "line-flags")
opt = &reg.declare_option<TimestampedList<LineAndFlag>>(parser[1], docstring, {}, flags);
else if (parser[0] == "range-faces")

View File

@ -917,13 +917,13 @@ HighlighterAndId create_flag_lines_highlighter(HighlighterParameters params)
auto& lines = line_flags.list;
auto& buffer = context.buffer();
if (line_flags.timestamp != buffer.timestamp())
if (line_flags.prefix != buffer.timestamp())
{
std::sort(lines.begin(), lines.end(),
[](const LineAndFlag& lhs, const LineAndFlag& rhs)
{ return std::get<0>(lhs) < std::get<0>(rhs); });
auto modifs = compute_line_modifications(buffer, line_flags.timestamp);
auto modifs = compute_line_modifications(buffer, line_flags.prefix);
auto ins_pos = lines.begin();
for (auto it = lines.begin(); it != lines.end(); ++it)
{
@ -945,7 +945,7 @@ HighlighterAndId create_flag_lines_highlighter(HighlighterParameters params)
++ins_pos;
}
lines.erase(ins_pos, lines.end());
line_flags.timestamp = buffer.timestamp();
line_flags.prefix = buffer.timestamp();
}
auto def_face = get_face(default_face);
@ -1003,7 +1003,7 @@ HighlighterAndId create_ranges_highlighter(HighlighterParameters params)
auto& ranges = range_and_faces.list;
auto& buffer = context.buffer();
if (range_and_faces.timestamp != buffer.timestamp())
if (range_and_faces.prefix != buffer.timestamp())
{
// TODO: update ranges to current timestamp
return;

View File

@ -215,11 +215,11 @@ InsertCompletion complete_filename(const Buffer& buffer, ByteCoord cursor_pos,
InsertCompletion complete_option(const Buffer& buffer, ByteCoord cursor_pos,
const OptionManager& options, StringView option_name)
{
const StringList& opt = options[option_name].get<StringList>();
if (opt.empty())
const CompletionList& opt = options[option_name].get<CompletionList>();
if (opt.list.empty())
return {};
auto& desc = opt[0];
auto& desc = opt.prefix;
static const Regex re(R"((\d+)\.(\d+)(?:\+(\d+))?@(\d+))");
MatchResults<String::const_iterator> match;
if (regex_match(desc.begin(), desc.end(), match, re))
@ -260,17 +260,15 @@ InsertCompletion complete_option(const Buffer& buffer, ByteCoord cursor_pos,
Vector<RankedMatchAndInfo> matches;
for (auto it = opt.begin() + 1; it != opt.end(); ++it)
for (auto& candidate : opt.list)
{
auto splitted = split(*it, '@');
if (splitted.empty())
continue;
if (RankedMatchAndInfo match{splitted[0], query})
if (RankedMatchAndInfo match{std::get<0>(candidate), query})
{
match.docstring = splitted.size() > 1 ? splitted[1] : StringView{};
match.menu_entry = splitted.size() > 2 ?
parse_display_line(expand_tabs(splitted[2], tabstop, column))
: DisplayLine{ expand_tabs(splitted[0], tabstop, column) };
match.docstring = std::get<1>(candidate);
auto& menu = std::get<2>(candidate);
match.menu_entry = not menu.empty() ?
parse_display_line(expand_tabs(menu, tabstop, column))
: DisplayLine{ expand_tabs(menu, tabstop, column) };
matches.push_back(std::move(match));
}

View File

@ -34,10 +34,12 @@ struct InsertCompleterDesc
using InsertCompleterDescList = Vector<InsertCompleterDesc, MemoryDomain::Options>;
String option_to_string(const InsertCompleterDesc& opt);
void option_from_string(StringView str, InsertCompleterDesc& opt);
using CompletionCandidate = std::tuple<String, String, String>;
using CompletionList = PrefixedList<String, CompletionCandidate>;
struct InsertCompletion
{
struct Candidate

View File

@ -29,6 +29,9 @@ inline bool option_add(int& opt, StringView str)
return val != 0;
}
inline String option_to_string(size_t opt) { return to_string(opt); }
inline void option_from_string(StringView str, size_t& opt) { opt = str_to_int(str); }
inline String option_to_string(bool opt) { return opt ? "true" : "false"; }
inline void option_from_string(StringView str, bool& opt)
{
@ -223,46 +226,49 @@ constexpr Array<EnumDesc<DebugFlags>, 3> enum_desc(DebugFlags)
} };
}
template<typename T>
struct TimestampedList
template<typename P, typename T>
struct PrefixedList
{
size_t timestamp;
P prefix;
Vector<T, MemoryDomain::Options> list;
};
template<typename T>
inline bool operator==(const TimestampedList<T>& lhs, const TimestampedList<T>& rhs)
template<typename P, typename T>
inline bool operator==(const PrefixedList<P, T>& lhs, const PrefixedList<P, T>& rhs)
{
return lhs.timestamp == rhs.timestamp and lhs.list == rhs.list;
return lhs.prefix == rhs.prefix and lhs.list == rhs.list;
}
template<typename T>
inline bool operator!=(const TimestampedList<T>& lhs, const TimestampedList<T>& rhs)
template<typename P, typename T>
inline bool operator!=(const PrefixedList<P, T>& lhs, const PrefixedList<P, T>& rhs)
{
return not (lhs == rhs);
}
template<typename T>
inline String option_to_string(const TimestampedList<T>& opt)
template<typename P, typename T>
inline String option_to_string(const PrefixedList<P, T>& opt)
{
return format("{}:{}", opt.timestamp, option_to_string(opt.list));
return format("{}:{}", opt.prefix, option_to_string(opt.list));
}
template<typename T>
inline void option_from_string(StringView str, TimestampedList<T>& opt)
template<typename P, typename T>
inline void option_from_string(StringView str, PrefixedList<P, T>& opt)
{
auto it = find(str, ':');
opt.timestamp = str_to_int({str.begin(), it});
option_from_string(StringView{str.begin(), it}, opt.prefix);
if (it != str.end())
option_from_string({it+1, str.end()}, opt.list);
}
template<typename T>
inline bool option_add(TimestampedList<T>& opt, StringView str)
template<typename P, typename T>
inline bool option_add(PrefixedList<P, T>& opt, StringView str)
{
return option_add(opt.list, str);
}
template<typename T>
using TimestampedList = PrefixedList<size_t, T>;
}
#endif // option_types_hh_INCLUDED