Add support for line completion in all buffers
- via completers option with line=all vs line=buffer - via <c-x> L mapping
This commit is contained in:
parent
9bd9fecb53
commit
0568836943
|
@ -718,6 +718,7 @@ using `<c-x>`, followed, by:
|
||||||
* *w* : word completion (current buffer)
|
* *w* : word completion (current buffer)
|
||||||
* *W* : word completion (all buffers)
|
* *W* : word completion (all buffers)
|
||||||
* *l* : line completion (current buffer)
|
* *l* : line completion (current buffer)
|
||||||
|
* *L* : line completion (all buffers)
|
||||||
|
|
||||||
Completion candidates can be selected using `<c-n>` and `<c-p>`.
|
Completion candidates can be selected using `<c-n>` and `<c-p>`.
|
||||||
|
|
||||||
|
|
|
@ -1223,12 +1223,15 @@ public:
|
||||||
if (key.key == 'W')
|
if (key.key == 'W')
|
||||||
m_completer.explicit_word_all_complete();
|
m_completer.explicit_word_all_complete();
|
||||||
if (key.key == 'l')
|
if (key.key == 'l')
|
||||||
m_completer.explicit_line_complete();
|
m_completer.explicit_line_buffer_complete();
|
||||||
|
if (key.key == 'L')
|
||||||
|
m_completer.explicit_line_all_complete();
|
||||||
}, "enter completion type",
|
}, "enter completion type",
|
||||||
"f: filename\n"
|
"f: filename\n"
|
||||||
"w: word (current buffer)\n"
|
"w: word (current buffer)\n"
|
||||||
"W: word (all buffers)\n"
|
"W: word (all buffers)\n"
|
||||||
"l: line\n");
|
"l: line (current buffer)\n"
|
||||||
|
"L: line (all buffers)\n");
|
||||||
update_completions = false;
|
update_completions = false;
|
||||||
}
|
}
|
||||||
else if (key == ctrl('o'))
|
else if (key == ctrl('o'))
|
||||||
|
|
|
@ -33,7 +33,7 @@ String option_to_string(const InsertCompleterDesc& opt)
|
||||||
case InsertCompleterDesc::Option:
|
case InsertCompleterDesc::Option:
|
||||||
return "option=" + (opt.param ? *opt.param : "");
|
return "option=" + (opt.param ? *opt.param : "");
|
||||||
case InsertCompleterDesc::Line:
|
case InsertCompleterDesc::Line:
|
||||||
return "line";
|
return "line=" + (opt.param ? *opt.param : "");
|
||||||
}
|
}
|
||||||
kak_assert(false);
|
kak_assert(false);
|
||||||
return "";
|
return "";
|
||||||
|
@ -63,11 +63,15 @@ void option_from_string(StringView str, InsertCompleterDesc& opt)
|
||||||
opt.param = Optional<String>{};
|
opt.param = Optional<String>{};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (str == "line")
|
else if (str.substr(0_byte, 5_byte) == "line=")
|
||||||
{
|
{
|
||||||
opt.mode = InsertCompleterDesc::Line;
|
auto param = str.substr(5_byte);
|
||||||
opt.param = Optional<String>{};
|
if (param == "all" or param == "buffer")
|
||||||
return;
|
{
|
||||||
|
opt.mode = InsertCompleterDesc::Line;
|
||||||
|
opt.param = param.str();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw runtime_error(format("invalid completer description: '{}'", str));
|
throw runtime_error(format("invalid completer description: '{}'", str));
|
||||||
}
|
}
|
||||||
|
@ -342,6 +346,7 @@ InsertCompletion complete_option(const SelectionList& sels,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool other_buffers>
|
||||||
InsertCompletion complete_line(const SelectionList& sels, const OptionManager& options)
|
InsertCompletion complete_line(const SelectionList& sels, const OptionManager& options)
|
||||||
{
|
{
|
||||||
const Buffer& buffer = sels.buffer();
|
const Buffer& buffer = sels.buffer();
|
||||||
|
@ -352,18 +357,37 @@ InsertCompletion complete_line(const SelectionList& sels, const OptionManager& o
|
||||||
|
|
||||||
StringView prefix = buffer[cursor_pos.line].substr(0_byte, cursor_pos.column);
|
StringView prefix = buffer[cursor_pos.line].substr(0_byte, cursor_pos.column);
|
||||||
InsertCompletion::CandidateList candidates;
|
InsertCompletion::CandidateList candidates;
|
||||||
for (LineCount l = 0_line; l < buffer.line_count(); ++l)
|
|
||||||
{
|
auto add_candidates = [&](const Buffer& buf) {
|
||||||
if (l == cursor_pos.line)
|
for (LineCount l = 0_line; l < buf.line_count(); ++l)
|
||||||
continue;
|
|
||||||
ByteCount len = buffer[l].length();
|
|
||||||
if (len > cursor_pos.column and std::equal(prefix.begin(), prefix.end(), buffer[l].begin()))
|
|
||||||
{
|
{
|
||||||
StringView candidate = buffer[l].substr(0_byte, len-1);
|
// perf: it's unlikely the user intends to search among >10 candidates anyway
|
||||||
candidates.push_back({candidate.str(), "",
|
if (candidates.size() == 100)
|
||||||
expand_tabs(candidate, tabstop, column)});
|
break;
|
||||||
|
if (buf.name() == buffer.name() && l == cursor_pos.line)
|
||||||
|
continue;
|
||||||
|
ByteCount len = buf[l].length();
|
||||||
|
if (len > cursor_pos.column and std::equal(prefix.begin(), prefix.end(), buf[l].begin()))
|
||||||
|
{
|
||||||
|
StringView candidate = buf[l].substr(0_byte, len-1);
|
||||||
|
candidates.push_back({candidate.str(), "",
|
||||||
|
expand_tabs(candidate, tabstop, column)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
add_candidates(buffer);
|
||||||
|
|
||||||
|
if (other_buffers)
|
||||||
|
{
|
||||||
|
for (const auto& buf : BufferManager::instance())
|
||||||
|
{
|
||||||
|
if (buf.get() == &buffer or buf->flags() & Buffer::Flags::Debug)
|
||||||
|
continue;
|
||||||
|
add_candidates(*buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidates.empty())
|
if (candidates.empty())
|
||||||
return {};
|
return {};
|
||||||
std::sort(candidates.begin(), candidates.end());
|
std::sort(candidates.begin(), candidates.end());
|
||||||
|
@ -500,7 +524,12 @@ bool InsertCompleter::setup_ifn()
|
||||||
try_complete(complete_word<true>))
|
try_complete(complete_word<true>))
|
||||||
return true;
|
return true;
|
||||||
if (completer.mode == InsertCompleterDesc::Line and
|
if (completer.mode == InsertCompleterDesc::Line and
|
||||||
try_complete(complete_line))
|
*completer.param == "buffer" and
|
||||||
|
try_complete(complete_line<false>))
|
||||||
|
return true;
|
||||||
|
if (completer.mode == InsertCompleterDesc::Line and
|
||||||
|
*completer.param == "all" and
|
||||||
|
try_complete(complete_line<true>))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -584,10 +613,16 @@ void InsertCompleter::explicit_word_all_complete()
|
||||||
m_explicit_completer = complete_word<true>;
|
m_explicit_completer = complete_word<true>;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertCompleter::explicit_line_complete()
|
void InsertCompleter::explicit_line_buffer_complete()
|
||||||
{
|
{
|
||||||
try_complete(complete_line);
|
try_complete(complete_line<false>);
|
||||||
m_explicit_completer = complete_line;
|
m_explicit_completer = complete_line<false>;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertCompleter::explicit_line_all_complete()
|
||||||
|
{
|
||||||
|
try_complete(complete_line<true>);
|
||||||
|
m_explicit_completer = complete_line<true>;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,8 @@ public:
|
||||||
void explicit_file_complete();
|
void explicit_file_complete();
|
||||||
void explicit_word_buffer_complete();
|
void explicit_word_buffer_complete();
|
||||||
void explicit_word_all_complete();
|
void explicit_word_all_complete();
|
||||||
void explicit_line_complete();
|
void explicit_line_buffer_complete();
|
||||||
|
void explicit_line_all_complete();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool setup_ifn();
|
bool setup_ifn();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user