From b5a68307ba3c80d20ac88633d7c1e440307728de Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Fri, 1 Apr 2016 01:27:23 +0100 Subject: [PATCH] Use a specific option type completions for insert completion Fix escaping in jedi.kak as well --- rc/extra/clang.kak | 6 ++++-- rc/extra/jedi.kak | 7 ++++--- src/commands.cc | 4 ++++ src/highlighters.cc | 8 ++++---- src/insert_completer.cc | 22 ++++++++++------------ src/insert_completer.hh | 4 +++- src/option_types.hh | 38 ++++++++++++++++++++++---------------- 7 files changed, 51 insertions(+), 38 deletions(-) diff --git a/rc/extra/clang.kak b/rc/extra/clang.kak index 1e0a849a..1089815c 100644 --- a/rc/extra/clang.kak +++ b/rc/extra/clang.kak @@ -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' diff --git a/rc/extra/jedi.kak b/rc/extra/jedi.kak index 49d70c80..65bc1ec4 100644 --- a/rc/extra/jedi.kak +++ b/rc/extra/jedi.kak @@ -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 & } diff --git a/src/commands.cc b/src/commands.cc index cdaf41c8..e0dbef07 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -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 = ®.declare_option>(parser[1], docstring, {}, flags); else if (parser[0] == "str-list") opt = ®.declare_option>(parser[1], docstring, {}, flags); + else if (parser[0] == "completions") + opt = ®.declare_option(parser[1], docstring, {}, flags); else if (parser[0] == "line-flags") opt = ®.declare_option>(parser[1], docstring, {}, flags); else if (parser[0] == "range-faces") diff --git a/src/highlighters.cc b/src/highlighters.cc index 11d13adc..9e5b60c6 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -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; diff --git a/src/insert_completer.cc b/src/insert_completer.cc index 8e854937..b4e4aef7 100644 --- a/src/insert_completer.cc +++ b/src/insert_completer.cc @@ -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(); - if (opt.empty()) + const CompletionList& opt = options[option_name].get(); + if (opt.list.empty()) return {}; - auto& desc = opt[0]; + auto& desc = opt.prefix; static const Regex re(R"((\d+)\.(\d+)(?:\+(\d+))?@(\d+))"); MatchResults match; if (regex_match(desc.begin(), desc.end(), match, re)) @@ -260,17 +260,15 @@ InsertCompletion complete_option(const Buffer& buffer, ByteCoord cursor_pos, Vector 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)); } diff --git a/src/insert_completer.hh b/src/insert_completer.hh index 86695eab..5192313a 100644 --- a/src/insert_completer.hh +++ b/src/insert_completer.hh @@ -34,10 +34,12 @@ struct InsertCompleterDesc using InsertCompleterDescList = Vector; - String option_to_string(const InsertCompleterDesc& opt); void option_from_string(StringView str, InsertCompleterDesc& opt); +using CompletionCandidate = std::tuple; +using CompletionList = PrefixedList; + struct InsertCompletion { struct Candidate diff --git a/src/option_types.hh b/src/option_types.hh index 0330a7e9..ad35bd92 100644 --- a/src/option_types.hh +++ b/src/option_types.hh @@ -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, 3> enum_desc(DebugFlags) } }; } -template -struct TimestampedList +template +struct PrefixedList { - size_t timestamp; + P prefix; Vector list; }; -template -inline bool operator==(const TimestampedList& lhs, const TimestampedList& rhs) +template +inline bool operator==(const PrefixedList& lhs, const PrefixedList& rhs) { - return lhs.timestamp == rhs.timestamp and lhs.list == rhs.list; + return lhs.prefix == rhs.prefix and lhs.list == rhs.list; } -template -inline bool operator!=(const TimestampedList& lhs, const TimestampedList& rhs) +template +inline bool operator!=(const PrefixedList& lhs, const PrefixedList& rhs) { return not (lhs == rhs); } -template -inline String option_to_string(const TimestampedList& opt) +template +inline String option_to_string(const PrefixedList& opt) { - return format("{}:{}", opt.timestamp, option_to_string(opt.list)); + return format("{}:{}", opt.prefix, option_to_string(opt.list)); } -template -inline void option_from_string(StringView str, TimestampedList& opt) +template +inline void option_from_string(StringView str, PrefixedList& 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 -inline bool option_add(TimestampedList& opt, StringView str) +template +inline bool option_add(PrefixedList& opt, StringView str) { return option_add(opt.list, str); } +template +using TimestampedList = PrefixedList; + } #endif // option_types_hh_INCLUDED