Extract InputHandler from Client
This commit is contained in:
parent
fe55d51e9f
commit
ad275d1d1c
|
@ -6,6 +6,7 @@
|
||||||
#include "file.hh"
|
#include "file.hh"
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
#include "window.hh"
|
#include "window.hh"
|
||||||
|
#include "client.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -40,19 +41,19 @@ Buffer::Buffer(String name, Flags flags, std::vector<String> lines,
|
||||||
}
|
}
|
||||||
|
|
||||||
Editor editor_for_hooks(*this);
|
Editor editor_for_hooks(*this);
|
||||||
Context context(editor_for_hooks);
|
InputHandler hook_handler(editor_for_hooks);
|
||||||
if (flags & Flags::File)
|
if (flags & Flags::File)
|
||||||
{
|
{
|
||||||
if (flags & Flags::New)
|
if (flags & Flags::New)
|
||||||
m_hooks.run_hook("BufNew", m_name, context);
|
m_hooks.run_hook("BufNew", m_name, hook_handler.context());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
kak_assert(m_fs_timestamp != InvalidTime);
|
kak_assert(m_fs_timestamp != InvalidTime);
|
||||||
m_hooks.run_hook("BufOpen", m_name, context);
|
m_hooks.run_hook("BufOpen", m_name, hook_handler.context());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hooks.run_hook("BufCreate", m_name, context);
|
m_hooks.run_hook("BufCreate", m_name, hook_handler.context());
|
||||||
|
|
||||||
// now we may begin to record undo data
|
// now we may begin to record undo data
|
||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
|
@ -65,8 +66,8 @@ Buffer::~Buffer()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Editor hook_editor{*this};
|
Editor hook_editor{*this};
|
||||||
Context hook_context{hook_editor};
|
InputHandler hook_handler(hook_editor);
|
||||||
m_hooks.run_hook("BufClose", m_name, hook_context);
|
m_hooks.run_hook("BufClose", m_name, hook_handler.context());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_options.unregister_watcher(*this);
|
m_options.unregister_watcher(*this);
|
||||||
|
@ -763,7 +764,7 @@ void Buffer::on_option_changed(const Option& option)
|
||||||
{
|
{
|
||||||
String desc = option.name() + "=" + option.get_as_string();
|
String desc = option.name() + "=" + option.get_as_string();
|
||||||
Editor hook_editor{*this};
|
Editor hook_editor{*this};
|
||||||
Context hook_context{hook_editor};
|
InputHandler hook_handler(hook_editor);
|
||||||
m_hooks.run_hook("BufSetOption", desc, hook_context);
|
m_hooks.run_hook("BufSetOption", desc, hook_handler.context());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
171
src/client.cc
171
src/client.cc
|
@ -22,26 +22,26 @@ namespace Kakoune
|
||||||
class InputMode
|
class InputMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputMode(Client& client) : m_client(client) {}
|
InputMode(InputHandler& input_handler) : m_input_handler(input_handler) {}
|
||||||
virtual ~InputMode() {}
|
virtual ~InputMode() {}
|
||||||
InputMode(const InputMode&) = delete;
|
InputMode(const InputMode&) = delete;
|
||||||
InputMode& operator=(const InputMode&) = delete;
|
InputMode& operator=(const InputMode&) = delete;
|
||||||
|
|
||||||
virtual void on_key(Key key) = 0;
|
virtual void on_key(Key key) = 0;
|
||||||
virtual void on_replaced() {}
|
virtual void on_replaced() {}
|
||||||
Context& context() const { return m_client.context(); }
|
Context& context() const { return m_input_handler.context(); }
|
||||||
|
|
||||||
virtual String description() const = 0;
|
virtual String description() const = 0;
|
||||||
|
|
||||||
virtual KeymapMode keymap_mode() const = 0;
|
virtual KeymapMode keymap_mode() const = 0;
|
||||||
|
|
||||||
using Insertion = Client::Insertion;
|
using Insertion = InputHandler::Insertion;
|
||||||
Insertion& last_insert() { return m_client.m_last_insert; }
|
Insertion& last_insert() { return m_input_handler.m_last_insert; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void reset_normal_mode();
|
void reset_normal_mode();
|
||||||
private:
|
private:
|
||||||
Client& m_client;
|
InputHandler& m_input_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace InputModes
|
namespace InputModes
|
||||||
|
@ -53,17 +53,18 @@ static constexpr std::chrono::milliseconds fs_check_timeout{500};
|
||||||
class Normal : public InputMode
|
class Normal : public InputMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Normal(Client& client)
|
Normal(InputHandler& input_handler)
|
||||||
: InputMode(client),
|
: InputMode(input_handler),
|
||||||
m_idle_timer{Clock::now() + idle_timeout, [this](Timer& timer) {
|
m_idle_timer{Clock::now() + idle_timeout, [this](Timer& timer) {
|
||||||
context().hooks().run_hook("NormalIdle", "", context());
|
context().hooks().run_hook("NormalIdle", "", context());
|
||||||
}},
|
}},
|
||||||
m_fs_check_timer{Clock::now() + fs_check_timeout, [this](Timer& timer) {
|
m_fs_check_timer{Clock::now() + fs_check_timeout, [this](Timer& timer) {
|
||||||
|
if (not context().has_client())
|
||||||
|
return;
|
||||||
context().client().check_buffer_fs_timestamp();
|
context().client().check_buffer_fs_timestamp();
|
||||||
timer.set_next_date(Clock::now() + fs_check_timeout);
|
timer.set_next_date(Clock::now() + fs_check_timeout);
|
||||||
}}
|
}}
|
||||||
{
|
{
|
||||||
context().client().check_buffer_fs_timestamp();
|
|
||||||
context().hooks().run_hook("NormalBegin", "", context());
|
context().hooks().run_hook("NormalBegin", "", context());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,12 +180,14 @@ private:
|
||||||
class Menu : public InputMode
|
class Menu : public InputMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Menu(Client& client, memoryview<String> choices,
|
Menu(InputHandler& input_handler, memoryview<String> choices,
|
||||||
MenuCallback callback)
|
MenuCallback callback)
|
||||||
: InputMode(client),
|
: InputMode(input_handler),
|
||||||
m_callback(callback), m_choices(choices.begin(), choices.end()),
|
m_callback(callback), m_choices(choices.begin(), choices.end()),
|
||||||
m_selected(m_choices.begin())
|
m_selected(m_choices.begin())
|
||||||
{
|
{
|
||||||
|
if (not context().has_ui())
|
||||||
|
return;
|
||||||
DisplayCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
DisplayCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
||||||
context().ui().menu_show(choices, menu_pos, get_color("MenuForeground"),
|
context().ui().menu_show(choices, menu_pos, get_color("MenuForeground"),
|
||||||
get_color("MenuBackground"), MenuStyle::Prompt);
|
get_color("MenuBackground"), MenuStyle::Prompt);
|
||||||
|
@ -198,7 +201,8 @@ public:
|
||||||
|
|
||||||
if (key == ctrl('m'))
|
if (key == ctrl('m'))
|
||||||
{
|
{
|
||||||
context().ui().menu_hide();
|
if (context().has_ui())
|
||||||
|
context().ui().menu_hide();
|
||||||
context().print_status(DisplayLine{});
|
context().print_status(DisplayLine{});
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
int selected = m_selected - m_choices.begin();
|
int selected = m_selected - m_choices.begin();
|
||||||
|
@ -216,7 +220,8 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context().ui().menu_hide();
|
if (context().has_ui())
|
||||||
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
int selected = m_selected - m_choices.begin();
|
int selected = m_selected - m_choices.begin();
|
||||||
m_callback(selected, MenuEvent::Abort, context());
|
m_callback(selected, MenuEvent::Abort, context());
|
||||||
|
@ -281,7 +286,8 @@ private:
|
||||||
{
|
{
|
||||||
m_selected = it;
|
m_selected = it;
|
||||||
int selected = m_selected - m_choices.begin();
|
int selected = m_selected - m_choices.begin();
|
||||||
context().ui().menu_select(selected);
|
if (context().has_ui())
|
||||||
|
context().ui().menu_select(selected);
|
||||||
m_callback(selected, MenuEvent::Select, context());
|
m_callback(selected, MenuEvent::Select, context());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,9 +317,9 @@ String common_prefix(memoryview<String> strings)
|
||||||
class Prompt : public InputMode
|
class Prompt : public InputMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Prompt(Client& client, const String& prompt,
|
Prompt(InputHandler& input_handler, const String& prompt,
|
||||||
ColorPair colors, Completer completer, PromptCallback callback)
|
ColorPair colors, Completer completer, PromptCallback callback)
|
||||||
: InputMode(client), m_prompt(prompt), m_prompt_colors(colors),
|
: InputMode(input_handler), m_prompt(prompt), m_prompt_colors(colors),
|
||||||
m_completer(completer), m_callback(callback)
|
m_completer(completer), m_callback(callback)
|
||||||
{
|
{
|
||||||
m_history_it = ms_history[m_prompt].end();
|
m_history_it = ms_history[m_prompt].end();
|
||||||
|
@ -344,7 +350,8 @@ public:
|
||||||
history.push_back(line);
|
history.push_back(line);
|
||||||
}
|
}
|
||||||
context().print_status(DisplayLine{});
|
context().print_status(DisplayLine{});
|
||||||
context().ui().menu_hide();
|
if (context().has_ui())
|
||||||
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
// call callback after reset_normal_mode so that callback
|
// call callback after reset_normal_mode so that callback
|
||||||
// may change the mode
|
// may change the mode
|
||||||
|
@ -354,7 +361,8 @@ public:
|
||||||
else if (key == Key::Escape or key == ctrl('c'))
|
else if (key == Key::Escape or key == ctrl('c'))
|
||||||
{
|
{
|
||||||
context().print_status(DisplayLine{});
|
context().print_status(DisplayLine{});
|
||||||
context().ui().menu_hide();
|
if (context().has_ui())
|
||||||
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
reset_normal_mode();
|
||||||
m_callback(line, PromptEvent::Abort, context());
|
m_callback(line, PromptEvent::Abort, context());
|
||||||
return;
|
return;
|
||||||
|
@ -432,7 +440,8 @@ public:
|
||||||
m_current_completion = candidates.size()-1;
|
m_current_completion = candidates.size()-1;
|
||||||
|
|
||||||
const String& completion = candidates[m_current_completion];
|
const String& completion = candidates[m_current_completion];
|
||||||
context().ui().menu_select(m_current_completion);
|
if (context().has_ui())
|
||||||
|
context().ui().menu_select(m_current_completion);
|
||||||
|
|
||||||
m_line_editor.insert_from(line.char_count_to(m_completions.start),
|
m_line_editor.insert_from(line.char_count_to(m_completions.start),
|
||||||
completion);
|
completion);
|
||||||
|
@ -450,7 +459,8 @@ public:
|
||||||
{
|
{
|
||||||
m_line_editor.handle_key(key);
|
m_line_editor.handle_key(key);
|
||||||
m_current_completion = -1;
|
m_current_completion = -1;
|
||||||
context().ui().menu_hide();
|
if (context().has_ui())
|
||||||
|
context().ui().menu_hide();
|
||||||
showcompl = true;
|
showcompl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,7 +496,7 @@ private:
|
||||||
m_completions = m_completer(context(), CompletionFlags::Fast, line,
|
m_completions = m_completer(context(), CompletionFlags::Fast, line,
|
||||||
line.byte_count_to(m_line_editor.cursor_pos()));
|
line.byte_count_to(m_line_editor.cursor_pos()));
|
||||||
CandidateList& candidates = m_completions.candidates;
|
CandidateList& candidates = m_completions.candidates;
|
||||||
if (not candidates.empty())
|
if (context().has_ui() and not candidates.empty())
|
||||||
{
|
{
|
||||||
DisplayCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
DisplayCoord menu_pos{ context().ui().dimensions().line, 0_char };
|
||||||
context().ui().menu_show(candidates, menu_pos, get_color("MenuForeground"),
|
context().ui().menu_show(candidates, menu_pos, get_color("MenuForeground"),
|
||||||
|
@ -522,8 +532,8 @@ std::unordered_map<String, std::vector<String>> Prompt::ms_history;
|
||||||
class NextKey : public InputMode
|
class NextKey : public InputMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NextKey(Client& client, KeyCallback callback)
|
NextKey(InputHandler& input_handler, KeyCallback callback)
|
||||||
: InputMode(client), m_callback(callback) {}
|
: InputMode(input_handler), m_callback(callback) {}
|
||||||
|
|
||||||
void on_key(Key key) override
|
void on_key(Key key) override
|
||||||
{
|
{
|
||||||
|
@ -592,7 +602,8 @@ public:
|
||||||
m_completions.end = cursor_pos;
|
m_completions.end = cursor_pos;
|
||||||
m_completions.begin = buffer.advance(m_completions.end, -candidate.length());
|
m_completions.begin = buffer.advance(m_completions.end, -candidate.length());
|
||||||
m_completions.timestamp = m_context.buffer().timestamp();
|
m_completions.timestamp = m_context.buffer().timestamp();
|
||||||
m_context.ui().menu_select(m_current_candidate);
|
if (m_context.has_ui())
|
||||||
|
m_context.ui().menu_select(m_current_candidate);
|
||||||
|
|
||||||
// when we select a match, remove non displayed matches from the candidates
|
// when we select a match, remove non displayed matches from the candidates
|
||||||
// which are considered as invalid with the new completion timestamp
|
// which are considered as invalid with the new completion timestamp
|
||||||
|
@ -630,7 +641,6 @@ public:
|
||||||
}
|
}
|
||||||
if (not m_matching_candidates.empty())
|
if (not m_matching_candidates.empty())
|
||||||
{
|
{
|
||||||
m_context.ui().menu_hide();
|
|
||||||
m_current_candidate = m_matching_candidates.size();
|
m_current_candidate = m_matching_candidates.size();
|
||||||
m_completions.end = cursor;
|
m_completions.end = cursor;
|
||||||
menu_show();
|
menu_show();
|
||||||
|
@ -646,7 +656,8 @@ public:
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
m_completions = BufferCompletion{};
|
m_completions = BufferCompletion{};
|
||||||
m_context.ui().menu_hide();
|
if (m_context.has_ui())
|
||||||
|
m_context.ui().menu_hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<BufferCompletion (BufferCompleter::*complete_func)(const Buffer&, BufferCoord)>
|
template<BufferCompletion (BufferCompleter::*complete_func)(const Buffer&, BufferCoord)>
|
||||||
|
@ -661,7 +672,6 @@ public:
|
||||||
kak_assert(cursor_pos >= m_completions.begin);
|
kak_assert(cursor_pos >= m_completions.begin);
|
||||||
m_matching_candidates = m_completions.candidates;
|
m_matching_candidates = m_completions.candidates;
|
||||||
m_current_candidate = m_matching_candidates.size();
|
m_current_candidate = m_matching_candidates.size();
|
||||||
m_context.ui().menu_hide();
|
|
||||||
menu_show();
|
menu_show();
|
||||||
m_matching_candidates.push_back(buffer.string(m_completions.begin, m_completions.end));
|
m_matching_candidates.push_back(buffer.string(m_completions.begin, m_completions.end));
|
||||||
return true;
|
return true;
|
||||||
|
@ -814,6 +824,8 @@ private:
|
||||||
|
|
||||||
void menu_show()
|
void menu_show()
|
||||||
{
|
{
|
||||||
|
if (m_context.has_ui())
|
||||||
|
return;
|
||||||
DisplayCoord menu_pos = m_context.window().display_position(m_completions.begin);
|
DisplayCoord menu_pos = m_context.window().display_position(m_completions.begin);
|
||||||
m_context.ui().menu_show(m_matching_candidates, menu_pos,
|
m_context.ui().menu_show(m_matching_candidates, menu_pos,
|
||||||
get_color("MenuForeground"),
|
get_color("MenuForeground"),
|
||||||
|
@ -850,8 +862,8 @@ private:
|
||||||
class Insert : public InputMode
|
class Insert : public InputMode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Insert(Client& client, InsertMode mode)
|
Insert(InputHandler& input_handler, InsertMode mode)
|
||||||
: InputMode(client),
|
: InputMode(input_handler),
|
||||||
m_insert_mode(mode),
|
m_insert_mode(mode),
|
||||||
m_edition(context().editor()),
|
m_edition(context().editor()),
|
||||||
m_completer(context()),
|
m_completer(context()),
|
||||||
|
@ -1088,31 +1100,31 @@ private:
|
||||||
|
|
||||||
void InputMode::reset_normal_mode()
|
void InputMode::reset_normal_mode()
|
||||||
{
|
{
|
||||||
m_client.reset_normal_mode();
|
m_input_handler.reset_normal_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name)
|
InputHandler::InputHandler(Editor& editor)
|
||||||
: m_ui(std::move(ui)), m_context(*this, editor), m_mode(new InputModes::Normal(*this)), m_name(name)
|
: m_mode(new InputModes::Normal(*this)),
|
||||||
|
m_context(*this, editor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client()
|
InputHandler::~InputHandler()
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
void Client::change_input_mode(InputMode* new_mode)
|
void InputHandler::change_input_mode(InputMode* new_mode)
|
||||||
{
|
{
|
||||||
m_mode->on_replaced();
|
m_mode->on_replaced();
|
||||||
m_mode_trash.emplace_back(std::move(m_mode));
|
m_mode_trash.emplace_back(std::move(m_mode));
|
||||||
m_mode.reset(new_mode);
|
m_mode.reset(new_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::insert(InsertMode mode)
|
void InputHandler::insert(InsertMode mode)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::Insert(*this, mode));
|
change_input_mode(new InputModes::Insert(*this, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::repeat_last_insert()
|
void InputHandler::repeat_last_insert()
|
||||||
{
|
{
|
||||||
if (m_last_insert.second.empty())
|
if (m_last_insert.second.empty())
|
||||||
return;
|
return;
|
||||||
|
@ -1127,27 +1139,27 @@ void Client::repeat_last_insert()
|
||||||
kak_assert(dynamic_cast<InputModes::Normal*>(m_mode.get()) != nullptr);
|
kak_assert(dynamic_cast<InputModes::Normal*>(m_mode.get()) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::prompt(const String& prompt, ColorPair prompt_colors,
|
void InputHandler::prompt(const String& prompt, ColorPair prompt_colors,
|
||||||
Completer completer, PromptCallback callback)
|
Completer completer, PromptCallback callback)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::Prompt(*this, prompt, prompt_colors,
|
change_input_mode(new InputModes::Prompt(*this, prompt, prompt_colors,
|
||||||
completer, callback));
|
completer, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::set_prompt_colors(ColorPair prompt_colors)
|
void InputHandler::set_prompt_colors(ColorPair prompt_colors)
|
||||||
{
|
{
|
||||||
InputModes::Prompt* prompt = dynamic_cast<InputModes::Prompt*>(m_mode.get());
|
InputModes::Prompt* prompt = dynamic_cast<InputModes::Prompt*>(m_mode.get());
|
||||||
if (prompt)
|
if (prompt)
|
||||||
prompt->set_prompt_colors(prompt_colors);
|
prompt->set_prompt_colors(prompt_colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::menu(memoryview<String> choices,
|
void InputHandler::menu(memoryview<String> choices,
|
||||||
MenuCallback callback)
|
MenuCallback callback)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::Menu(*this, choices, callback));
|
change_input_mode(new InputModes::Menu(*this, choices, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::on_next_key(KeyCallback callback)
|
void InputHandler::on_next_key(KeyCallback callback)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::NextKey(*this, callback));
|
change_input_mode(new InputModes::NextKey(*this, callback));
|
||||||
}
|
}
|
||||||
|
@ -1157,17 +1169,7 @@ static bool is_valid(Key key)
|
||||||
return key != Key::Invalid and key.key <= 0x10FFFF;
|
return key != Key::Invalid and key.key <= 0x10FFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::handle_available_input()
|
void InputHandler::handle_key(Key key)
|
||||||
{
|
|
||||||
while (m_ui->is_key_available())
|
|
||||||
{
|
|
||||||
handle_key(m_ui->get_key());
|
|
||||||
m_mode_trash.clear();
|
|
||||||
}
|
|
||||||
m_context.window().forget_timestamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::handle_key(Key key)
|
|
||||||
{
|
{
|
||||||
if (is_valid(key))
|
if (is_valid(key))
|
||||||
{
|
{
|
||||||
|
@ -1189,29 +1191,59 @@ void Client::handle_key(Key key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::start_recording(char reg)
|
void InputHandler::start_recording(char reg)
|
||||||
{
|
{
|
||||||
kak_assert(m_recording_reg == 0);
|
kak_assert(m_recording_reg == 0);
|
||||||
m_recorded_keys = "";
|
m_recorded_keys = "";
|
||||||
m_recording_reg = reg;
|
m_recording_reg = reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::is_recording() const
|
bool InputHandler::is_recording() const
|
||||||
{
|
{
|
||||||
return m_recording_reg != 0;
|
return m_recording_reg != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::stop_recording()
|
void InputHandler::stop_recording()
|
||||||
{
|
{
|
||||||
kak_assert(m_recording_reg != 0);
|
kak_assert(m_recording_reg != 0);
|
||||||
RegisterManager::instance()[m_recording_reg] = memoryview<String>(m_recorded_keys);
|
RegisterManager::instance()[m_recording_reg] = memoryview<String>(m_recorded_keys);
|
||||||
m_recording_reg = 0;
|
m_recording_reg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputHandler::reset_normal_mode()
|
||||||
|
{
|
||||||
|
change_input_mode(new InputModes::Normal(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHandler::clear_mode_trash()
|
||||||
|
{
|
||||||
|
m_mode_trash.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Client::Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name)
|
||||||
|
: m_input_handler(editor), m_ui(std::move(ui)), m_name(name)
|
||||||
|
{
|
||||||
|
context().set_client(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Client::~Client()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::handle_available_input()
|
||||||
|
{
|
||||||
|
while (m_ui->is_key_available())
|
||||||
|
{
|
||||||
|
m_input_handler.handle_key(m_ui->get_key());
|
||||||
|
m_input_handler.clear_mode_trash();
|
||||||
|
}
|
||||||
|
context().window().forget_timestamp();
|
||||||
|
}
|
||||||
|
|
||||||
void Client::print_status(DisplayLine status_line)
|
void Client::print_status(DisplayLine status_line)
|
||||||
{
|
{
|
||||||
m_status_line = std::move(status_line);
|
m_status_line = std::move(status_line);
|
||||||
m_context.window().forget_timestamp();
|
context().window().forget_timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayLine Client::generate_mode_line() const
|
DisplayLine Client::generate_mode_line() const
|
||||||
|
@ -1224,35 +1256,30 @@ DisplayLine Client::generate_mode_line() const
|
||||||
<< " " << (int)pos.line+1 << ":" << (int)col+1;
|
<< " " << (int)pos.line+1 << ":" << (int)col+1;
|
||||||
if (context().buffer().is_modified())
|
if (context().buffer().is_modified())
|
||||||
oss << " [+]";
|
oss << " [+]";
|
||||||
if (is_recording())
|
if (m_input_handler.is_recording())
|
||||||
oss << " [recording (" << m_recording_reg << ")]";
|
oss << " [recording (" << m_input_handler.recording_reg() << ")]";
|
||||||
if (context().buffer().flags() & Buffer::Flags::New)
|
if (context().buffer().flags() & Buffer::Flags::New)
|
||||||
oss << " [new file]";
|
oss << " [new file]";
|
||||||
oss << " [" << m_mode->description() << "]" << " - " << name()
|
oss << " [" << m_input_handler.mode().description() << "]" << " - " << name()
|
||||||
<< "@[" << Server::instance().session() << "]";
|
<< "@[" << Server::instance().session() << "]";
|
||||||
return { oss.str(), get_color("StatusLine") };
|
return { oss.str(), get_color("StatusLine") };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::redraw_ifn()
|
void Client::redraw_ifn()
|
||||||
{
|
{
|
||||||
if (m_context.window().timestamp() != m_context.buffer().timestamp())
|
if (context().window().timestamp() != context().buffer().timestamp())
|
||||||
{
|
{
|
||||||
DisplayCoord dimensions = m_context.ui().dimensions();
|
DisplayCoord dimensions = context().ui().dimensions();
|
||||||
if (dimensions == DisplayCoord{0,0})
|
if (dimensions == DisplayCoord{0,0})
|
||||||
return;
|
return;
|
||||||
m_context.window().set_dimensions(dimensions);
|
context().window().set_dimensions(dimensions);
|
||||||
m_context.window().update_display_buffer();;
|
context().window().update_display_buffer();;
|
||||||
|
|
||||||
m_context.ui().draw(m_context.window().display_buffer(),
|
context().ui().draw(context().window().display_buffer(),
|
||||||
m_status_line, generate_mode_line());
|
m_status_line, generate_mode_line());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::reset_normal_mode()
|
|
||||||
{
|
|
||||||
change_input_mode(new InputModes::Normal(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reload_buffer(Context& context, const String& filename)
|
static void reload_buffer(Context& context, const String& filename)
|
||||||
{
|
{
|
||||||
DisplayCoord view_pos = context.window().position();
|
DisplayCoord view_pos = context.window().position();
|
||||||
|
@ -1270,7 +1297,7 @@ static void reload_buffer(Context& context, const String& filename)
|
||||||
|
|
||||||
void Client::check_buffer_fs_timestamp()
|
void Client::check_buffer_fs_timestamp()
|
||||||
{
|
{
|
||||||
Buffer& buffer = m_context.buffer();
|
Buffer& buffer = context().buffer();
|
||||||
auto reload = context().options()["autoreload"].get<YesNoAsk>();
|
auto reload = context().options()["autoreload"].get<YesNoAsk>();
|
||||||
if (not (buffer.flags() & Buffer::Flags::File) or reload == No)
|
if (not (buffer.flags() & Buffer::Flags::File) or reload == No)
|
||||||
return;
|
return;
|
||||||
|
@ -1282,7 +1309,7 @@ void Client::check_buffer_fs_timestamp()
|
||||||
if (reload == Ask)
|
if (reload == Ask)
|
||||||
{
|
{
|
||||||
print_status({"'" + buffer.display_name() + "' was modified externally, press r or y to reload, k or n to keep", get_color("Prompt")});
|
print_status({"'" + buffer.display_name() + "' was modified externally, press r or y to reload, k or n to keep", get_color("Prompt")});
|
||||||
on_next_key([this, ts, filename](Key key, Context& context) {
|
m_input_handler.on_next_key([this, ts, filename](Key key, Context& context) {
|
||||||
Buffer* buf = BufferManager::instance().get_buffer_ifp(filename);
|
Buffer* buf = BufferManager::instance().get_buffer_ifp(filename);
|
||||||
// buffer got deleted while waiting for the key, do nothing
|
// buffer got deleted while waiting for the key, do nothing
|
||||||
if (not buf)
|
if (not buf)
|
||||||
|
|
|
@ -35,11 +35,11 @@ using KeyCallback = std::function<void (Key, Context&)>;
|
||||||
class InputMode;
|
class InputMode;
|
||||||
enum class InsertMode : unsigned;
|
enum class InsertMode : unsigned;
|
||||||
|
|
||||||
class Client : public SafeCountable
|
class InputHandler : public SafeCountable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name);
|
InputHandler(Editor& editor);
|
||||||
~Client();
|
~InputHandler();
|
||||||
|
|
||||||
// switch to insert mode
|
// switch to insert mode
|
||||||
void insert(InsertMode mode);
|
void insert(InsertMode mode);
|
||||||
|
@ -65,18 +65,46 @@ public:
|
||||||
// if callback does not change the mode itself
|
// if callback does not change the mode itself
|
||||||
void on_next_key(KeyCallback callback);
|
void on_next_key(KeyCallback callback);
|
||||||
|
|
||||||
|
|
||||||
// handle all the keys currently available in the user interface
|
|
||||||
void handle_available_input();
|
|
||||||
// process the given key
|
// process the given key
|
||||||
void handle_key(Key key);
|
void handle_key(Key key);
|
||||||
|
|
||||||
void start_recording(char reg);
|
void start_recording(char reg);
|
||||||
bool is_recording() const;
|
bool is_recording() const;
|
||||||
void stop_recording();
|
void stop_recording();
|
||||||
|
char recording_reg() const { return m_recording_reg; }
|
||||||
|
|
||||||
|
void reset_normal_mode();
|
||||||
|
|
||||||
Context& context() { return m_context; }
|
Context& context() { return m_context; }
|
||||||
const Context& context() const { return m_context; }
|
const Context& context() const { return m_context; }
|
||||||
|
|
||||||
|
const InputMode& mode() const { return *m_mode; }
|
||||||
|
void clear_mode_trash();
|
||||||
|
private:
|
||||||
|
Context m_context;
|
||||||
|
|
||||||
|
friend class InputMode;
|
||||||
|
std::unique_ptr<InputMode> m_mode;
|
||||||
|
std::vector<std::unique_ptr<InputMode>> m_mode_trash;
|
||||||
|
|
||||||
|
void change_input_mode(InputMode* new_mode);
|
||||||
|
|
||||||
|
using Insertion = std::pair<InsertMode, std::vector<Key>>;
|
||||||
|
Insertion m_last_insert = {InsertMode::Insert, {}};
|
||||||
|
|
||||||
|
char m_recording_reg = 0;
|
||||||
|
String m_recorded_keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Client : public SafeCountable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Client(std::unique_ptr<UserInterface>&& ui, Editor& editor, String name);
|
||||||
|
~Client();
|
||||||
|
|
||||||
|
// handle all the keys currently available in the user interface
|
||||||
|
void handle_available_input();
|
||||||
|
|
||||||
const String& name() const { return m_name; }
|
const String& name() const { return m_name; }
|
||||||
void set_name(String name) { m_name = std::move(name); }
|
void set_name(String name) { m_name = std::move(name); }
|
||||||
|
|
||||||
|
@ -88,26 +116,18 @@ public:
|
||||||
|
|
||||||
void check_buffer_fs_timestamp();
|
void check_buffer_fs_timestamp();
|
||||||
|
|
||||||
void reset_normal_mode();
|
Context& context() { return m_input_handler.context(); }
|
||||||
|
const Context& context() const { return m_input_handler.context(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void change_input_mode(InputMode* new_mode);
|
InputHandler m_input_handler;
|
||||||
|
|
||||||
DisplayLine generate_mode_line() const;
|
DisplayLine generate_mode_line() const;
|
||||||
|
|
||||||
Context m_context;
|
|
||||||
friend class InputMode;
|
|
||||||
std::unique_ptr<UserInterface> m_ui;
|
std::unique_ptr<UserInterface> m_ui;
|
||||||
std::unique_ptr<InputMode> m_mode;
|
|
||||||
std::vector<std::unique_ptr<InputMode>> m_mode_trash;
|
|
||||||
|
|
||||||
String m_name;
|
String m_name;
|
||||||
DisplayLine m_status_line;
|
DisplayLine m_status_line;
|
||||||
|
|
||||||
using Insertion = std::pair<InsertMode, std::vector<Key>>;
|
|
||||||
Insertion m_last_insert = {InsertMode::Insert, {}};
|
|
||||||
|
|
||||||
char m_recording_reg = 0;
|
|
||||||
String m_recorded_keys;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef client_manager_hh_INCLUDED
|
#ifndef client_manager_hh_INCLUDED
|
||||||
#define client_manager_hh_INCLUDED
|
#define client_manager_hh_INCLUDED
|
||||||
|
|
||||||
#include "context.hh"
|
|
||||||
#include "client.hh"
|
#include "client.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
|
|
|
@ -642,7 +642,7 @@ void menu(CommandParameters params, Context& context)
|
||||||
select_cmds.push_back(parser[i+2]);
|
select_cmds.push_back(parser[i+2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.client().menu(choices,
|
context.input_handler().menu(choices,
|
||||||
[=](int choice, MenuEvent event, Context& context) {
|
[=](int choice, MenuEvent event, Context& context) {
|
||||||
if (event == MenuEvent::Validate and choice >= 0 and choice < commands.size())
|
if (event == MenuEvent::Validate and choice >= 0 and choice < commands.size())
|
||||||
CommandManager::instance().execute(commands[choice], context);
|
CommandManager::instance().execute(commands[choice], context);
|
||||||
|
@ -801,7 +801,7 @@ void exec_keys(const KeyList& keys, Context& context)
|
||||||
scoped_edition edition(context.editor());
|
scoped_edition edition(context.editor());
|
||||||
|
|
||||||
for (auto& key : keys)
|
for (auto& key : keys)
|
||||||
context.client().handle_key(key);
|
context.input_handler().handle_key(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_commands()
|
void register_commands()
|
||||||
|
|
|
@ -9,11 +9,8 @@ namespace Kakoune
|
||||||
|
|
||||||
Context::Context() = default;
|
Context::Context() = default;
|
||||||
|
|
||||||
Context::Context(Editor& editor)
|
Context::Context(InputHandler& input_handler, Editor& editor)
|
||||||
: m_editor(&editor) {}
|
: m_input_handler(&input_handler), m_editor(&editor) {}
|
||||||
|
|
||||||
Context::Context(Client& client, Editor& editor)
|
|
||||||
: m_client(&client), m_editor(&editor) {}
|
|
||||||
|
|
||||||
Context::~Context() = default;
|
Context::~Context() = default;
|
||||||
|
|
||||||
|
@ -43,10 +40,17 @@ bool Context::has_window() const
|
||||||
return (bool)m_editor and dynamic_cast<Window*>(m_editor.get());
|
return (bool)m_editor and dynamic_cast<Window*>(m_editor.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputHandler& Context::input_handler() const
|
||||||
|
{
|
||||||
|
if (not has_input_handler())
|
||||||
|
throw runtime_error("no input handler in context");
|
||||||
|
return *m_input_handler;
|
||||||
|
}
|
||||||
|
|
||||||
Client& Context::client() const
|
Client& Context::client() const
|
||||||
{
|
{
|
||||||
if (not has_client())
|
if (not has_client())
|
||||||
throw runtime_error("no input handler in context");
|
throw runtime_error("no client in context");
|
||||||
return *m_client;
|
return *m_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +58,7 @@ UserInterface& Context::ui() const
|
||||||
{
|
{
|
||||||
if (not has_ui())
|
if (not has_ui())
|
||||||
throw runtime_error("no user interface in context");
|
throw runtime_error("no user interface in context");
|
||||||
return m_client->ui();
|
return client().ui();
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionManager& Context::options() const
|
OptionManager& Context::options() const
|
||||||
|
@ -84,6 +88,12 @@ KeymapManager& Context::keymaps() const
|
||||||
return GlobalKeymaps::instance();
|
return GlobalKeymaps::instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::set_client(Client& client)
|
||||||
|
{
|
||||||
|
kak_assert(not has_client());
|
||||||
|
m_client.reset(&client);
|
||||||
|
}
|
||||||
|
|
||||||
void Context::print_status(DisplayLine status) const
|
void Context::print_status(DisplayLine status) const
|
||||||
{
|
{
|
||||||
if (has_client())
|
if (has_client())
|
||||||
|
@ -162,8 +172,8 @@ void Context::change_editor(Editor& editor)
|
||||||
window().set_dimensions(ui().dimensions());
|
window().set_dimensions(ui().dimensions());
|
||||||
window().hooks().run_hook("WinDisplay", buffer().name(), *this);
|
window().hooks().run_hook("WinDisplay", buffer().name(), *this);
|
||||||
}
|
}
|
||||||
if (has_client())
|
if (has_input_handler())
|
||||||
client().reset_normal_mode();
|
input_handler().reset_normal_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ class Editor;
|
||||||
class Window;
|
class Window;
|
||||||
class Buffer;
|
class Buffer;
|
||||||
class Client;
|
class Client;
|
||||||
|
class InputHandler;
|
||||||
class UserInterface;
|
class UserInterface;
|
||||||
class DisplayLine;
|
class DisplayLine;
|
||||||
class KeymapManager;
|
class KeymapManager;
|
||||||
|
@ -24,8 +25,7 @@ class Context
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Context();
|
Context();
|
||||||
explicit Context(Editor& editor);
|
Context(InputHandler& input_handler, Editor& editor);
|
||||||
Context(Client& client, Editor& editor);
|
|
||||||
~Context();
|
~Context();
|
||||||
|
|
||||||
Context(const Context&) = delete;
|
Context(const Context&) = delete;
|
||||||
|
@ -43,11 +43,16 @@ public:
|
||||||
Client& client() const;
|
Client& client() const;
|
||||||
bool has_client() const { return (bool)m_client; }
|
bool has_client() const { return (bool)m_client; }
|
||||||
|
|
||||||
|
InputHandler& input_handler() const;
|
||||||
|
bool has_input_handler() const { return (bool)m_input_handler; }
|
||||||
|
|
||||||
UserInterface& ui() const;
|
UserInterface& ui() const;
|
||||||
bool has_ui() const { return (bool)m_client; }
|
bool has_ui() const { return has_client(); }
|
||||||
|
|
||||||
void change_editor(Editor& editor);
|
void change_editor(Editor& editor);
|
||||||
|
|
||||||
|
void set_client(Client& client);
|
||||||
|
|
||||||
OptionManager& options() const;
|
OptionManager& options() const;
|
||||||
HookManager& hooks() const;
|
HookManager& hooks() const;
|
||||||
KeymapManager& keymaps() const;
|
KeymapManager& keymaps() const;
|
||||||
|
@ -60,8 +65,9 @@ public:
|
||||||
void forget_jumps_to_buffer(Buffer& buffer);
|
void forget_jumps_to_buffer(Buffer& buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
safe_ptr<Editor> m_editor;
|
safe_ptr<Editor> m_editor;
|
||||||
safe_ptr<Client> m_client;
|
safe_ptr<InputHandler> m_input_handler;
|
||||||
|
safe_ptr<Client> m_client;
|
||||||
|
|
||||||
using JumpList = std::vector<DynamicSelectionList>;
|
using JumpList = std::vector<DynamicSelectionList>;
|
||||||
JumpList m_jump_list;
|
JumpList m_jump_list;
|
||||||
|
|
|
@ -25,12 +25,12 @@ using namespace std::placeholders;
|
||||||
template<InsertMode mode>
|
template<InsertMode mode>
|
||||||
void insert(Context& context, int)
|
void insert(Context& context, int)
|
||||||
{
|
{
|
||||||
context.client().insert(mode);
|
context.input_handler().insert(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void repeat_insert(Context& context, int)
|
void repeat_insert(Context& context, int)
|
||||||
{
|
{
|
||||||
context.client().repeat_last_insert();
|
context.input_handler().repeat_last_insert();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool show_auto_info_ifn(const String& title, const String& info,
|
bool show_auto_info_ifn(const String& title, const String& info,
|
||||||
|
@ -50,7 +50,7 @@ void on_next_key_with_autoinfo(const Context& context, Cmd cmd,
|
||||||
const String& title, const String& info)
|
const String& title, const String& info)
|
||||||
{
|
{
|
||||||
const bool hide = show_auto_info_ifn(title, info, context);
|
const bool hide = show_auto_info_ifn(title, info, context);
|
||||||
context.client().on_next_key([hide,cmd](Key key, Context& context) mutable {
|
context.input_handler().on_next_key([hide,cmd](Key key, Context& context) mutable {
|
||||||
if (hide)
|
if (hide)
|
||||||
context.ui().info_hide();
|
context.ui().info_hide();
|
||||||
cmd(key, context);
|
cmd(key, context);
|
||||||
|
@ -247,7 +247,7 @@ void for_each_char(Context& context, int)
|
||||||
|
|
||||||
void command(Context& context, int)
|
void command(Context& context, int)
|
||||||
{
|
{
|
||||||
context.client().prompt(
|
context.input_handler().prompt(
|
||||||
":", get_color("Prompt"),
|
":", get_color("Prompt"),
|
||||||
std::bind(&CommandManager::complete, &CommandManager::instance(), _1, _2, _3, _4),
|
std::bind(&CommandManager::complete, &CommandManager::instance(), _1, _2, _3, _4),
|
||||||
[](const String& cmdline, PromptEvent event, Context& context) {
|
[](const String& cmdline, PromptEvent event, Context& context) {
|
||||||
|
@ -258,7 +258,7 @@ void command(Context& context, int)
|
||||||
|
|
||||||
void pipe(Context& context, int)
|
void pipe(Context& context, int)
|
||||||
{
|
{
|
||||||
context.client().prompt("pipe:", get_color("Prompt"), complete_nothing,
|
context.input_handler().prompt("pipe:", get_color("Prompt"), complete_nothing,
|
||||||
[](const String& cmdline, PromptEvent event, Context& context)
|
[](const String& cmdline, PromptEvent event, Context& context)
|
||||||
{
|
{
|
||||||
if (event != PromptEvent::Validate)
|
if (event != PromptEvent::Validate)
|
||||||
|
@ -299,7 +299,7 @@ void search(Context& context, int)
|
||||||
{
|
{
|
||||||
const char* prompt = direction == Forward ? "search:" : "reverse search:";
|
const char* prompt = direction == Forward ? "search:" : "reverse search:";
|
||||||
DynamicSelectionList selections{context.buffer(), context.editor().selections()};
|
DynamicSelectionList selections{context.buffer(), context.editor().selections()};
|
||||||
context.client().prompt(prompt, get_color("Prompt"), complete_nothing,
|
context.input_handler().prompt(prompt, get_color("Prompt"), complete_nothing,
|
||||||
[selections](const String& str, PromptEvent event, Context& context) {
|
[selections](const String& str, PromptEvent event, Context& context) {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -309,7 +309,7 @@ void search(Context& context, int)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Regex ex{str};
|
Regex ex{str};
|
||||||
context.client().set_prompt_colors(get_color("Prompt"));
|
context.input_handler().set_prompt_colors(get_color("Prompt"));
|
||||||
if (event == PromptEvent::Validate)
|
if (event == PromptEvent::Validate)
|
||||||
{
|
{
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
|
@ -328,7 +328,7 @@ void search(Context& context, int)
|
||||||
if (event == PromptEvent::Validate)
|
if (event == PromptEvent::Validate)
|
||||||
throw runtime_error("regex error: "_str + err.what());
|
throw runtime_error("regex error: "_str + err.what());
|
||||||
else
|
else
|
||||||
context.client().set_prompt_colors(get_color("Error"));
|
context.input_handler().set_prompt_colors(get_color("Error"));
|
||||||
}
|
}
|
||||||
catch (runtime_error&)
|
catch (runtime_error&)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +449,7 @@ void paste(Context& context, int)
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void regex_prompt(Context& context, const String prompt, T on_validate)
|
void regex_prompt(Context& context, const String prompt, T on_validate)
|
||||||
{
|
{
|
||||||
context.client().prompt(prompt, get_color("Prompt"), complete_nothing,
|
context.input_handler().prompt(prompt, get_color("Prompt"), complete_nothing,
|
||||||
[=](const String& str, PromptEvent event, Context& context) {
|
[=](const String& str, PromptEvent event, Context& context) {
|
||||||
if (event == PromptEvent::Validate)
|
if (event == PromptEvent::Validate)
|
||||||
{
|
{
|
||||||
|
@ -465,7 +465,7 @@ void regex_prompt(Context& context, const String prompt, T on_validate)
|
||||||
else if (event == PromptEvent::Change)
|
else if (event == PromptEvent::Change)
|
||||||
{
|
{
|
||||||
const bool ok = Regex{str, boost::regex_constants::no_except}.status() == 0;
|
const bool ok = Regex{str, boost::regex_constants::no_except}.status() == 0;
|
||||||
context.client().set_prompt_colors(get_color(ok ? "Prompt" : "Error"));
|
context.input_handler().set_prompt_colors(get_color(ok ? "Prompt" : "Error"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -755,13 +755,13 @@ void select_to_next_char(Context& context, int param)
|
||||||
|
|
||||||
void start_or_end_macro_recording(Context& context, int)
|
void start_or_end_macro_recording(Context& context, int)
|
||||||
{
|
{
|
||||||
if (context.client().is_recording())
|
if (context.input_handler().is_recording())
|
||||||
context.client().stop_recording();
|
context.input_handler().stop_recording();
|
||||||
else
|
else
|
||||||
on_next_key_with_autoinfo(context, [](Key key, Context& context) {
|
on_next_key_with_autoinfo(context, [](Key key, Context& context) {
|
||||||
if (key.modifiers == Key::Modifiers::None and
|
if (key.modifiers == Key::Modifiers::None and
|
||||||
key.key >= 'a' and key.key <= 'z')
|
key.key >= 'a' and key.key <= 'z')
|
||||||
context.client().start_recording(key.key);
|
context.input_handler().start_recording(key.key);
|
||||||
}, "record macro", "enter macro name ");
|
}, "record macro", "enter macro name ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "context.hh"
|
#include "context.hh"
|
||||||
#include "highlighter.hh"
|
#include "highlighter.hh"
|
||||||
#include "hook_manager.hh"
|
#include "hook_manager.hh"
|
||||||
|
#include "client.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -22,8 +23,8 @@ Window::Window(Buffer& buffer)
|
||||||
m_options(buffer.options()),
|
m_options(buffer.options()),
|
||||||
m_keymaps(buffer.keymaps())
|
m_keymaps(buffer.keymaps())
|
||||||
{
|
{
|
||||||
Context hook_context{*this};
|
InputHandler hook_handler{*this};
|
||||||
m_hooks.run_hook("WinCreate", buffer.name(), hook_context);
|
m_hooks.run_hook("WinCreate", buffer.name(), hook_handler.context());
|
||||||
m_options.register_watcher(*this);
|
m_options.register_watcher(*this);
|
||||||
|
|
||||||
m_builtin_highlighters.append({"tabulations", expand_tabulations});
|
m_builtin_highlighters.append({"tabulations", expand_tabulations});
|
||||||
|
@ -36,8 +37,8 @@ Window::Window(Buffer& buffer)
|
||||||
|
|
||||||
Window::~Window()
|
Window::~Window()
|
||||||
{
|
{
|
||||||
Context hook_context{*this};
|
InputHandler hook_handler{*this};
|
||||||
m_hooks.run_hook("WinClose", buffer().name(), hook_context);
|
m_hooks.run_hook("WinClose", buffer().name(), hook_handler.context());
|
||||||
m_options.unregister_watcher(*this);
|
m_options.unregister_watcher(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +251,8 @@ BufferCoord Window::offset_coord(BufferCoord coord, LineCount offset)
|
||||||
void Window::on_option_changed(const Option& option)
|
void Window::on_option_changed(const Option& option)
|
||||||
{
|
{
|
||||||
String desc = option.name() + "=" + option.get_as_string();
|
String desc = option.name() + "=" + option.get_as_string();
|
||||||
Context hook_context{*this};
|
InputHandler hook_handler{*this};
|
||||||
m_hooks.run_hook("WinSetOption", desc, hook_context);
|
m_hooks.run_hook("WinSetOption", desc, hook_handler.context());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user