Merge branch 'mode-stack'
This commit is contained in:
commit
7bff1b782e
|
@ -72,7 +72,6 @@ void Client::handle_available_input(EventMode mode)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_input_handler.handle_key(*key);
|
m_input_handler.handle_key(*key);
|
||||||
m_input_handler.clear_mode_trash();
|
|
||||||
context().window().forget_timestamp();
|
context().window().forget_timestamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,12 +160,6 @@ void ClientManager::redraw_clients() const
|
||||||
client->redraw_ifn();
|
client->redraw_ifn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::clear_mode_trashes() const
|
|
||||||
{
|
|
||||||
for (auto& client : m_clients)
|
|
||||||
client->input_handler().clear_mode_trash();
|
|
||||||
}
|
|
||||||
|
|
||||||
CandidateList ClientManager::complete_client_name(StringView prefix,
|
CandidateList ClientManager::complete_client_name(StringView prefix,
|
||||||
ByteCount cursor_pos) const
|
ByteCount cursor_pos) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,6 @@ public:
|
||||||
void add_free_window(std::unique_ptr<Window>&& window, SelectionList selections);
|
void add_free_window(std::unique_ptr<Window>&& window, SelectionList selections);
|
||||||
|
|
||||||
void redraw_clients() const;
|
void redraw_clients() const;
|
||||||
void clear_mode_trashes() const;
|
|
||||||
void handle_pending_inputs() const;
|
void handle_pending_inputs() const;
|
||||||
|
|
||||||
Client* get_client_ifp(StringView name);
|
Client* get_client_ifp(StringView name);
|
||||||
|
|
|
@ -25,7 +25,8 @@ public:
|
||||||
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;
|
void handle_key(Key key) { on_key(key, {}); }
|
||||||
|
|
||||||
virtual void on_enabled() {}
|
virtual void on_enabled() {}
|
||||||
virtual void on_disabled() {}
|
virtual void on_disabled() {}
|
||||||
Context& context() const { return m_input_handler.context(); }
|
Context& context() const { return m_input_handler.context(); }
|
||||||
|
@ -38,7 +39,17 @@ public:
|
||||||
Insertion& last_insert() { return m_input_handler.m_last_insert; }
|
Insertion& last_insert() { return m_input_handler.m_last_insert; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void reset_normal_mode();
|
// KeepAlive is usedto make sure the current InputMode
|
||||||
|
// stays alive until the end of the on_key method
|
||||||
|
struct KeepAlive { std::shared_ptr<InputMode> ptr; };
|
||||||
|
|
||||||
|
virtual void on_key(Key key, KeepAlive keep_alive) = 0;
|
||||||
|
|
||||||
|
void pop_mode(KeepAlive& keep_alive)
|
||||||
|
{
|
||||||
|
kak_assert(not keep_alive.ptr);
|
||||||
|
keep_alive.ptr = m_input_handler.pop_mode(this);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
InputHandler& m_input_handler;
|
InputHandler& m_input_handler;
|
||||||
};
|
};
|
||||||
|
@ -130,12 +141,12 @@ class Normal : public InputMode
|
||||||
public:
|
public:
|
||||||
Normal(InputHandler& input_handler)
|
Normal(InputHandler& input_handler)
|
||||||
: InputMode(input_handler),
|
: InputMode(input_handler),
|
||||||
m_idle_timer{Clock::now() + idle_timeout,
|
m_idle_timer{TimePoint::max(),
|
||||||
context().flags() & Context::Flags::Transient ?
|
context().flags() & Context::Flags::Transient ?
|
||||||
Timer::Callback() : Timer::Callback([this](Timer& timer) {
|
Timer::Callback() : Timer::Callback([this](Timer& timer) {
|
||||||
context().hooks().run_hook("NormalIdle", "", context());
|
context().hooks().run_hook("NormalIdle", "", context());
|
||||||
})},
|
})},
|
||||||
m_fs_check_timer{Clock::now() + fs_check_timeout,
|
m_fs_check_timer{TimePoint::max(),
|
||||||
context().flags() & Context::Flags::Transient ?
|
context().flags() & Context::Flags::Transient ?
|
||||||
Timer::Callback() : Timer::Callback([this](Timer& timer) {
|
Timer::Callback() : Timer::Callback([this](Timer& timer) {
|
||||||
if (not context().has_client())
|
if (not context().has_client())
|
||||||
|
@ -153,15 +164,20 @@ public:
|
||||||
m_fs_check_timer.set_next_date(Clock::now() + fs_check_timeout);
|
m_fs_check_timer.set_next_date(Clock::now() + fs_check_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_idle_timer.set_next_date(Clock::now() + idle_timeout);
|
||||||
|
|
||||||
context().hooks().run_hook("NormalBegin", "", context());
|
context().hooks().run_hook("NormalBegin", "", context());
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_disabled() override
|
void on_disabled() override
|
||||||
{
|
{
|
||||||
|
m_idle_timer.set_next_date(TimePoint::max());
|
||||||
|
m_fs_check_timer.set_next_date(TimePoint::max());
|
||||||
|
|
||||||
context().hooks().run_hook("NormalEnd", "", context());
|
context().hooks().run_hook("NormalEnd", "", context());
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_key(Key key) override
|
void on_key(Key key, KeepAlive keep_alive) override
|
||||||
{
|
{
|
||||||
if (m_mouse_handler.handle_key(key, context()))
|
if (m_mouse_handler.handle_key(key, context()))
|
||||||
return;
|
return;
|
||||||
|
@ -436,7 +452,7 @@ public:
|
||||||
context().ui().menu_select(0);
|
context().ui().menu_select(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_key(Key key) override
|
void on_key(Key key, KeepAlive keep_alive) override
|
||||||
{
|
{
|
||||||
auto match_filter = [this](const String& str) {
|
auto match_filter = [this](const String& str) {
|
||||||
return regex_match(str.begin(), str.end(), m_filter);
|
return regex_match(str.begin(), str.end(), m_filter);
|
||||||
|
@ -447,7 +463,7 @@ public:
|
||||||
if (context().has_ui())
|
if (context().has_ui())
|
||||||
context().ui().menu_hide();
|
context().ui().menu_hide();
|
||||||
context().print_status(DisplayLine{});
|
context().print_status(DisplayLine{});
|
||||||
reset_normal_mode();
|
pop_mode(keep_alive);
|
||||||
int selected = m_selected - m_choices.begin();
|
int selected = m_selected - m_choices.begin();
|
||||||
m_callback(selected, MenuEvent::Validate, context());
|
m_callback(selected, MenuEvent::Validate, context());
|
||||||
return;
|
return;
|
||||||
|
@ -465,7 +481,7 @@ public:
|
||||||
{
|
{
|
||||||
if (context().has_ui())
|
if (context().has_ui())
|
||||||
context().ui().menu_hide();
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
pop_mode(keep_alive);
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
@ -576,7 +592,7 @@ public:
|
||||||
display();
|
display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_key(Key key) override
|
void on_key(Key key, KeepAlive keep_alive) override
|
||||||
{
|
{
|
||||||
History& history = ms_history[m_prompt];
|
History& history = ms_history[m_prompt];
|
||||||
const String& line = m_line_editor.line();
|
const String& line = m_line_editor.line();
|
||||||
|
@ -595,8 +611,8 @@ public:
|
||||||
context().print_status(DisplayLine{});
|
context().print_status(DisplayLine{});
|
||||||
if (context().has_ui())
|
if (context().has_ui())
|
||||||
context().ui().menu_hide();
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
pop_mode(keep_alive);
|
||||||
// call callback after reset_normal_mode so that callback
|
// call callback after pop_mode so that callback
|
||||||
// may change the mode
|
// may change the mode
|
||||||
m_callback(line, PromptEvent::Validate, context());
|
m_callback(line, PromptEvent::Validate, context());
|
||||||
return;
|
return;
|
||||||
|
@ -608,7 +624,7 @@ public:
|
||||||
context().print_status(DisplayLine{});
|
context().print_status(DisplayLine{});
|
||||||
if (context().has_ui())
|
if (context().has_ui())
|
||||||
context().ui().menu_hide();
|
context().ui().menu_hide();
|
||||||
reset_normal_mode();
|
pop_mode(keep_alive);
|
||||||
m_callback(line, PromptEvent::Abort, context());
|
m_callback(line, PromptEvent::Abort, context());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -834,9 +850,9 @@ public:
|
||||||
NextKey(InputHandler& input_handler, KeymapMode keymap_mode, KeyCallback callback)
|
NextKey(InputHandler& input_handler, KeymapMode keymap_mode, KeyCallback callback)
|
||||||
: InputMode(input_handler), m_keymap_mode(keymap_mode), m_callback(callback) {}
|
: InputMode(input_handler), m_keymap_mode(keymap_mode), m_callback(callback) {}
|
||||||
|
|
||||||
void on_key(Key key) override
|
void on_key(Key key, KeepAlive keep_alive) override
|
||||||
{
|
{
|
||||||
reset_normal_mode();
|
pop_mode(keep_alive);
|
||||||
m_callback(key, context());
|
m_callback(key, context());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,7 +877,7 @@ public:
|
||||||
m_edition(context()),
|
m_edition(context()),
|
||||||
m_completer(context()),
|
m_completer(context()),
|
||||||
m_autoshowcompl(true),
|
m_autoshowcompl(true),
|
||||||
m_idle_timer{Clock::now() + idle_timeout,
|
m_idle_timer{TimePoint::max(),
|
||||||
[this](Timer& timer) {
|
[this](Timer& timer) {
|
||||||
context().hooks().run_hook("InsertIdle", "", context());
|
context().hooks().run_hook("InsertIdle", "", context());
|
||||||
if (m_autoshowcompl)
|
if (m_autoshowcompl)
|
||||||
|
@ -879,7 +895,31 @@ public:
|
||||||
prepare(m_insert_mode);
|
prepare(m_insert_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_key(Key key) override
|
~Insert()
|
||||||
|
{
|
||||||
|
auto& selections = context().selections();
|
||||||
|
for (auto& sel : selections)
|
||||||
|
{
|
||||||
|
if (m_insert_mode == InsertMode::Append and sel.cursor().column > 0)
|
||||||
|
sel.cursor() = context().buffer().char_prev(sel.cursor());
|
||||||
|
}
|
||||||
|
selections.avoid_eol();
|
||||||
|
|
||||||
|
if (m_disable_hooks)
|
||||||
|
context().user_hooks_support().enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_enabled() override
|
||||||
|
{
|
||||||
|
m_idle_timer.set_next_date(Clock::now() + idle_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_disabled() override
|
||||||
|
{
|
||||||
|
m_idle_timer.set_next_date(TimePoint::max());
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_key(Key key, KeepAlive keep_alive) override
|
||||||
{
|
{
|
||||||
auto& buffer = context().buffer();
|
auto& buffer = context().buffer();
|
||||||
last_insert().second.push_back(key);
|
last_insert().second.push_back(key);
|
||||||
|
@ -908,7 +948,7 @@ public:
|
||||||
{
|
{
|
||||||
context().hooks().run_hook("InsertEnd", "", context());
|
context().hooks().run_hook("InsertEnd", "", context());
|
||||||
m_completer.reset();
|
m_completer.reset();
|
||||||
reset_normal_mode();
|
pop_mode(keep_alive);
|
||||||
}
|
}
|
||||||
else if (key == Key::Backspace)
|
else if (key == Key::Backspace)
|
||||||
{
|
{
|
||||||
|
@ -1112,20 +1152,6 @@ private:
|
||||||
buffer.check_invariant();
|
buffer.check_invariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_disabled() override
|
|
||||||
{
|
|
||||||
auto& selections = context().selections();
|
|
||||||
for (auto& sel : selections)
|
|
||||||
{
|
|
||||||
if (m_insert_mode == InsertMode::Append and sel.cursor().column > 0)
|
|
||||||
sel.cursor() = context().buffer().char_prev(sel.cursor());
|
|
||||||
}
|
|
||||||
selections.avoid_eol();
|
|
||||||
|
|
||||||
if (m_disable_hooks)
|
|
||||||
context().user_hooks_support().enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Mode { Default, Complete, InsertReg };
|
enum class Mode { Default, Complete, InsertReg };
|
||||||
Mode m_mode = Mode::Default;
|
Mode m_mode = Mode::Default;
|
||||||
InsertMode m_insert_mode;
|
InsertMode m_insert_mode;
|
||||||
|
@ -1138,30 +1164,48 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputMode::reset_normal_mode()
|
|
||||||
{
|
|
||||||
m_input_handler.reset_normal_mode();
|
|
||||||
}
|
|
||||||
|
|
||||||
InputHandler::InputHandler(SelectionList selections, Context::Flags flags, String name)
|
InputHandler::InputHandler(SelectionList selections, Context::Flags flags, String name)
|
||||||
: m_context(*this, std::move(selections), flags, std::move(name)),
|
: m_context(*this, std::move(selections), flags, std::move(name))
|
||||||
m_mode(new InputModes::Normal(*this))
|
{
|
||||||
{}
|
m_mode_stack.emplace_back(new InputModes::Normal(*this));
|
||||||
|
}
|
||||||
|
|
||||||
InputHandler::~InputHandler()
|
InputHandler::~InputHandler()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void InputHandler::change_input_mode(InputMode* new_mode)
|
void InputHandler::push_mode(InputMode* new_mode)
|
||||||
{
|
{
|
||||||
m_mode->on_disabled();
|
current_mode().on_disabled();
|
||||||
m_mode_trash.emplace_back(std::move(m_mode));
|
m_mode_stack.emplace_back(new_mode);
|
||||||
m_mode.reset(new_mode);
|
|
||||||
new_mode->on_enabled();
|
new_mode->on_enabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<InputMode> InputHandler::pop_mode(InputMode* mode)
|
||||||
|
{
|
||||||
|
kak_assert(m_mode_stack.back() == mode);
|
||||||
|
kak_assert(m_mode_stack.size() > 1);
|
||||||
|
|
||||||
|
current_mode().on_disabled();
|
||||||
|
std::unique_ptr<InputMode> res = std::move(m_mode_stack.back());
|
||||||
|
m_mode_stack.pop_back();
|
||||||
|
current_mode().on_enabled();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputHandler::reset_normal_mode()
|
||||||
|
{
|
||||||
|
if (m_mode_stack.size() > 1)
|
||||||
|
{
|
||||||
|
current_mode().on_disabled();
|
||||||
|
m_mode_stack.resize(1);
|
||||||
|
}
|
||||||
|
kak_assert(dynamic_cast<InputModes::Normal*>(¤t_mode()) != nullptr);
|
||||||
|
current_mode().on_enabled();
|
||||||
|
}
|
||||||
|
|
||||||
void InputHandler::insert(InsertMode mode)
|
void InputHandler::insert(InsertMode mode)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::Insert(*this, mode));
|
push_mode(new InputModes::Insert(*this, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputHandler::repeat_last_insert()
|
void InputHandler::repeat_last_insert()
|
||||||
|
@ -1173,24 +1217,24 @@ void InputHandler::repeat_last_insert()
|
||||||
swap(keys, m_last_insert.second);
|
swap(keys, m_last_insert.second);
|
||||||
// context.last_insert will be refilled by the new Insert
|
// context.last_insert will be refilled by the new Insert
|
||||||
// this is very inefficient.
|
// this is very inefficient.
|
||||||
change_input_mode(new InputModes::Insert(*this, m_last_insert.first));
|
push_mode(new InputModes::Insert(*this, m_last_insert.first));
|
||||||
for (auto& key : keys)
|
for (auto& key : keys)
|
||||||
m_mode->on_key(key);
|
current_mode().handle_key(key);
|
||||||
kak_assert(dynamic_cast<InputModes::Normal*>(m_mode.get()) != nullptr);
|
kak_assert(dynamic_cast<InputModes::Normal*>(¤t_mode()) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputHandler::prompt(StringView prompt, String initstr,
|
void InputHandler::prompt(StringView prompt, String initstr,
|
||||||
Face prompt_face, Completer completer,
|
Face prompt_face, Completer completer,
|
||||||
PromptCallback callback)
|
PromptCallback callback)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::Prompt(*this, prompt, initstr,
|
push_mode(new InputModes::Prompt(*this, prompt, initstr,
|
||||||
prompt_face, completer,
|
prompt_face, completer,
|
||||||
callback));
|
callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputHandler::set_prompt_face(Face prompt_face)
|
void InputHandler::set_prompt_face(Face prompt_face)
|
||||||
{
|
{
|
||||||
InputModes::Prompt* prompt = dynamic_cast<InputModes::Prompt*>(m_mode.get());
|
InputModes::Prompt* prompt = dynamic_cast<InputModes::Prompt*>(¤t_mode());
|
||||||
if (prompt)
|
if (prompt)
|
||||||
prompt->set_prompt_face(prompt_face);
|
prompt->set_prompt_face(prompt_face);
|
||||||
}
|
}
|
||||||
|
@ -1198,12 +1242,12 @@ void InputHandler::set_prompt_face(Face prompt_face)
|
||||||
void InputHandler::menu(ConstArrayView<String> choices,
|
void InputHandler::menu(ConstArrayView<String> choices,
|
||||||
MenuCallback callback)
|
MenuCallback callback)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::Menu(*this, choices, callback));
|
push_mode(new InputModes::Menu(*this, choices, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputHandler::on_next_key(KeymapMode keymap_mode, KeyCallback callback)
|
void InputHandler::on_next_key(KeymapMode keymap_mode, KeyCallback callback)
|
||||||
{
|
{
|
||||||
change_input_mode(new InputModes::NextKey(*this, keymap_mode, callback));
|
push_mode(new InputModes::NextKey(*this, keymap_mode, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_valid(Key key)
|
static bool is_valid(Key key)
|
||||||
|
@ -1220,16 +1264,16 @@ void InputHandler::handle_key(Key key)
|
||||||
++m_handle_key_level;
|
++m_handle_key_level;
|
||||||
auto dec = on_scope_end([&]{ --m_handle_key_level; });
|
auto dec = on_scope_end([&]{ --m_handle_key_level; });
|
||||||
|
|
||||||
auto keymap_mode = m_mode->keymap_mode();
|
auto keymap_mode = current_mode().keymap_mode();
|
||||||
KeymapManager& keymaps = m_context.keymaps();
|
KeymapManager& keymaps = m_context.keymaps();
|
||||||
if (keymaps.is_mapped(key, keymap_mode) and
|
if (keymaps.is_mapped(key, keymap_mode) and
|
||||||
m_context.keymaps_support().is_enabled())
|
m_context.keymaps_support().is_enabled())
|
||||||
{
|
{
|
||||||
for (auto& k : keymaps.get_mapping(key, keymap_mode))
|
for (auto& k : keymaps.get_mapping(key, keymap_mode))
|
||||||
m_mode->on_key(k);
|
current_mode().handle_key(k);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_mode->on_key(key);
|
current_mode().handle_key(key);
|
||||||
|
|
||||||
// do not record the key that made us enter or leave recording mode,
|
// do not record the key that made us enter or leave recording mode,
|
||||||
// and the ones that are triggered recursively by previous keys.
|
// and the ones that are triggered recursively by previous keys.
|
||||||
|
@ -1257,19 +1301,9 @@ void InputHandler::stop_recording()
|
||||||
m_recording_reg = 0;
|
m_recording_reg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputHandler::reset_normal_mode()
|
|
||||||
{
|
|
||||||
change_input_mode(new InputModes::Normal(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayLine InputHandler::mode_line() const
|
DisplayLine InputHandler::mode_line() const
|
||||||
{
|
{
|
||||||
return m_mode->mode_line();
|
return current_mode().mode_line();
|
||||||
}
|
|
||||||
|
|
||||||
void InputHandler::clear_mode_trash()
|
|
||||||
{
|
|
||||||
m_mode_trash.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,16 +81,17 @@ public:
|
||||||
const Context& context() const { return m_context; }
|
const Context& context() const { return m_context; }
|
||||||
|
|
||||||
DisplayLine mode_line() const;
|
DisplayLine mode_line() const;
|
||||||
void clear_mode_trash();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Context m_context;
|
Context m_context;
|
||||||
|
|
||||||
friend class InputMode;
|
friend class InputMode;
|
||||||
std::unique_ptr<InputMode> m_mode;
|
Vector<std::unique_ptr<InputMode>> m_mode_stack;
|
||||||
Vector<std::unique_ptr<InputMode>> m_mode_trash;
|
|
||||||
|
|
||||||
void change_input_mode(InputMode* new_mode);
|
InputMode& current_mode() const { return *m_mode_stack.back(); }
|
||||||
|
|
||||||
|
void push_mode(InputMode* new_mode);
|
||||||
|
std::unique_ptr<InputMode> pop_mode(InputMode* current_mode);
|
||||||
|
|
||||||
using Insertion = std::pair<InsertMode, Vector<Key>>;
|
using Insertion = std::pair<InsertMode, Vector<Key>>;
|
||||||
Insertion m_last_insert = {InsertMode::Insert, {}};
|
Insertion m_last_insert = {InsertMode::Insert, {}};
|
||||||
|
|
|
@ -437,7 +437,6 @@ int run_server(StringView session, StringView init_command,
|
||||||
client_manager.redraw_clients();
|
client_manager.redraw_clients();
|
||||||
event_manager.handle_next_events(EventMode::Normal);
|
event_manager.handle_next_events(EventMode::Normal);
|
||||||
client_manager.handle_pending_inputs();
|
client_manager.handle_pending_inputs();
|
||||||
client_manager.clear_mode_trashes();
|
|
||||||
buffer_manager.clear_buffer_trash();
|
buffer_manager.clear_buffer_trash();
|
||||||
string_registry.purge_unused();
|
string_registry.purge_unused();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user