BufferCompleter: watch 'completions' option, and update completions when it changes
This commit is contained in:
parent
2440a7e82e
commit
09e30c40e3
|
@ -504,32 +504,53 @@ static std::pair<CandidateList, BufferIterator> complete_opt(const BufferIterato
|
||||||
return { {}, pos };
|
return { {}, pos };
|
||||||
}
|
}
|
||||||
|
|
||||||
class BufferCompleter
|
class BufferCompleter : public OptionManagerWatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void select(const Context& context, int offset)
|
BufferCompleter(const Context& context)
|
||||||
|
: m_context(context)
|
||||||
{
|
{
|
||||||
if (not setup_ifn(context))
|
m_context.options().register_watcher(*this);
|
||||||
|
}
|
||||||
|
~BufferCompleter()
|
||||||
|
{
|
||||||
|
m_context.options().unregister_watcher(*this);
|
||||||
|
}
|
||||||
|
BufferCompleter(const BufferCompleter&) = delete;
|
||||||
|
BufferCompleter operator=(const BufferCompleter&) = delete;
|
||||||
|
|
||||||
|
void select(int offset)
|
||||||
|
{
|
||||||
|
if (not setup_ifn())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
context.buffer().erase(m_position, m_position + m_completions[m_current_completion].length());
|
m_context.buffer().erase(m_position, m_position + m_completions[m_current_completion].length());
|
||||||
m_current_completion = (m_current_completion + offset) % m_completions.size();
|
m_current_completion = (m_current_completion + offset) % m_completions.size();
|
||||||
context.buffer().insert(m_position, m_completions[m_current_completion]);
|
m_context.buffer().insert(m_position, m_completions[m_current_completion]);
|
||||||
context.ui().menu_select(m_current_completion);
|
m_context.ui().menu_select(m_current_completion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(const Context& context)
|
void reset()
|
||||||
{
|
{
|
||||||
m_position = BufferIterator();
|
m_position = BufferIterator();
|
||||||
context.ui().menu_hide();
|
m_context.ui().menu_hide();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
bool setup_ifn(const Context& context)
|
void on_option_changed(const Option& opt) override
|
||||||
|
{
|
||||||
|
if (opt.name() == "completions")
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
select(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setup_ifn()
|
||||||
{
|
{
|
||||||
if (not m_position.is_valid())
|
if (not m_position.is_valid())
|
||||||
{
|
{
|
||||||
BufferIterator cursor = context.editor().selections().back().last();
|
BufferIterator cursor = m_context.editor().selections().back().last();
|
||||||
auto completions = complete_opt(cursor, context.options());
|
auto completions = complete_opt(cursor, m_context.options());
|
||||||
if (completions.first.empty())
|
if (completions.first.empty())
|
||||||
completions = complete_word(cursor);
|
completions = complete_word(cursor);
|
||||||
m_completions = std::move(completions.first);
|
m_completions = std::move(completions.first);
|
||||||
|
@ -538,15 +559,16 @@ private:
|
||||||
|
|
||||||
assert(cursor >= completions.second);
|
assert(cursor >= completions.second);
|
||||||
m_position = completions.second;
|
m_position = completions.second;
|
||||||
DisplayCoord menu_pos = context.window().display_position(m_position);
|
DisplayCoord menu_pos = m_context.window().display_position(m_position);
|
||||||
context.ui().menu_show(m_completions, menu_pos, MenuStyle::Inline);
|
m_context.ui().menu_show(m_completions, menu_pos, MenuStyle::Inline);
|
||||||
|
|
||||||
m_completions.push_back(context.buffer().string(m_position, cursor));
|
m_completions.push_back(m_context.buffer().string(m_position, cursor));
|
||||||
m_current_completion = m_completions.size() - 1;
|
m_current_completion = m_completions.size() - 1;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Context& m_context;
|
||||||
BufferIterator m_position;
|
BufferIterator m_position;
|
||||||
CandidateList m_completions;
|
CandidateList m_completions;
|
||||||
int m_current_completion = -1;
|
int m_current_completion = -1;
|
||||||
|
@ -558,12 +580,13 @@ public:
|
||||||
Insert(InputHandler& input_handler, InsertMode mode)
|
Insert(InputHandler& input_handler, InsertMode mode)
|
||||||
: InputMode(input_handler),
|
: InputMode(input_handler),
|
||||||
m_inserter(context().editor(), mode),
|
m_inserter(context().editor(), mode),
|
||||||
|
m_completer(context()),
|
||||||
m_idle_timer{Clock::now() + idle_timeout,
|
m_idle_timer{Clock::now() + idle_timeout,
|
||||||
[this](Timer& timer) {
|
[this](Timer& timer) {
|
||||||
context().hooks().run_hook("InsertIdle", "", context());
|
context().hooks().run_hook("InsertIdle", "", context());
|
||||||
m_completer.reset(context());
|
m_completer.reset();
|
||||||
if (context().editor().selections().size() == 1)
|
if (context().editor().selections().size() == 1)
|
||||||
m_completer.select(context(), 0);
|
m_completer.select(0);
|
||||||
}}
|
}}
|
||||||
{
|
{
|
||||||
last_insert().first = mode;
|
last_insert().first = mode;
|
||||||
|
@ -586,7 +609,7 @@ public:
|
||||||
if (key == Key::Escape or key == Key{ Key::Modifiers::Control, 'c' })
|
if (key == Key::Escape or key == Key{ Key::Modifiers::Control, 'c' })
|
||||||
{
|
{
|
||||||
context().hooks().run_hook("InsertEnd", "", context());
|
context().hooks().run_hook("InsertEnd", "", context());
|
||||||
m_completer.reset(context());
|
m_completer.reset();
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
}
|
}
|
||||||
else if (key == Key::Backspace)
|
else if (key == Key::Backspace)
|
||||||
|
@ -624,12 +647,12 @@ public:
|
||||||
m_inserter.insert(String() + '\t');
|
m_inserter.insert(String() + '\t');
|
||||||
else if ( key == Key{ Key::Modifiers::Control, 'n' })
|
else if ( key == Key{ Key::Modifiers::Control, 'n' })
|
||||||
{
|
{
|
||||||
m_completer.select(context(), 1);
|
m_completer.select(1);
|
||||||
update_completions = false;
|
update_completions = false;
|
||||||
}
|
}
|
||||||
else if ( key == Key{ Key::Modifiers::Control, 'p' })
|
else if ( key == Key{ Key::Modifiers::Control, 'p' })
|
||||||
{
|
{
|
||||||
m_completer.select(context(), -1);
|
m_completer.select(-1);
|
||||||
update_completions = false;
|
update_completions = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,8 +664,8 @@ public:
|
||||||
private:
|
private:
|
||||||
bool m_insert_reg = false;
|
bool m_insert_reg = false;
|
||||||
IncrementalInserter m_inserter;
|
IncrementalInserter m_inserter;
|
||||||
Timer m_idle_timer;
|
|
||||||
BufferCompleter m_completer;
|
BufferCompleter m_completer;
|
||||||
|
Timer m_idle_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user