Cleanup and refactor externally modified buffer reloading
* Correctly hide the reload dialog in every client. * Correctly handle buffer being deleted.
This commit is contained in:
parent
6658d15741
commit
224f73d72a
|
@ -125,6 +125,9 @@ DisplayLine Client::generate_mode_line() const
|
||||||
|
|
||||||
void Client::change_buffer(Buffer& buffer)
|
void Client::change_buffer(Buffer& buffer)
|
||||||
{
|
{
|
||||||
|
if (m_buffer_reload_dialog_opened)
|
||||||
|
close_buffer_reload_dialog();
|
||||||
|
|
||||||
auto& client_manager = ClientManager::instance();
|
auto& client_manager = ClientManager::instance();
|
||||||
m_window->options().unregister_watcher(*this);
|
m_window->options().unregister_watcher(*this);
|
||||||
client_manager.add_free_window(std::move(m_window),
|
client_manager.add_free_window(std::move(m_window),
|
||||||
|
@ -166,21 +169,58 @@ void Client::redraw_ifn()
|
||||||
context().ui().refresh();
|
context().ui().refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reload_buffer(Context& context, StringView filename)
|
void Client::reload_buffer()
|
||||||
{
|
{
|
||||||
CharCoord view_pos = context.window().position();
|
auto& buffer = context().buffer();
|
||||||
ByteCoord cursor_pos = context.selections().main().cursor();
|
kak_assert(buffer.flags() & Buffer::Flags::File);
|
||||||
Buffer* buf = create_buffer_from_file(filename);
|
CharCoord view_pos = context().window().position();
|
||||||
if (not buf)
|
ByteCoord cursor_pos = context().selections().main().cursor();
|
||||||
return;
|
Buffer* buf = create_buffer_from_file(buffer.name());
|
||||||
context.change_buffer(*buf);
|
kak_assert(buf == &buffer);
|
||||||
context.selections() = SelectionList{ *buf, buf->clamp(cursor_pos)};
|
context().selections() = SelectionList{buffer, buffer.clamp(cursor_pos)};
|
||||||
context.window().set_position(view_pos);
|
context().window().set_position(view_pos);
|
||||||
context.print_status({ "'" + buf->display_name() + "' reloaded",
|
context().print_status({ "'" + buffer.display_name() + "' reloaded",
|
||||||
get_face("Information") });
|
get_face("Information") });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::check_buffer_fs_timestamp()
|
void Client::on_buffer_reload_key(Key key)
|
||||||
|
{
|
||||||
|
auto& buffer = context().buffer();
|
||||||
|
|
||||||
|
if (key == 'y' or key == ctrl('m'))
|
||||||
|
reload_buffer();
|
||||||
|
else if (key == 'n' or key == Key::Escape)
|
||||||
|
{
|
||||||
|
// reread timestamp in case the file was modified again
|
||||||
|
buffer.set_fs_timestamp(get_fs_timestamp(buffer.name()));
|
||||||
|
print_status({ "'" + buffer.display_name() + "' kept",
|
||||||
|
get_face("Information") });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_status({ "'" + key_to_str(key) + "' is not a valid choice",
|
||||||
|
get_face("Error") });
|
||||||
|
m_input_handler.on_next_key(KeymapMode::None, [this](Key key, Context&){ on_buffer_reload_key(key); });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& client : ClientManager::instance())
|
||||||
|
{
|
||||||
|
if (&client->context().buffer() == &buffer and
|
||||||
|
client->m_buffer_reload_dialog_opened)
|
||||||
|
client->close_buffer_reload_dialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::close_buffer_reload_dialog()
|
||||||
|
{
|
||||||
|
kak_assert(m_buffer_reload_dialog_opened);
|
||||||
|
m_buffer_reload_dialog_opened = false;
|
||||||
|
m_ui->info_hide();
|
||||||
|
m_input_handler.reset_normal_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::check_if_buffer_needs_reloading()
|
||||||
{
|
{
|
||||||
Buffer& buffer = context().buffer();
|
Buffer& buffer = context().buffer();
|
||||||
auto reload = context().options()["autoreload"].get<YesNoAsk>();
|
auto reload = context().options()["autoreload"].get<YesNoAsk>();
|
||||||
|
@ -196,36 +236,14 @@ void Client::check_buffer_fs_timestamp()
|
||||||
m_ui->info_show(
|
m_ui->info_show(
|
||||||
"reload '" + buffer.display_name() + "' ?",
|
"reload '" + buffer.display_name() + "' ?",
|
||||||
"'" + buffer.display_name() + "' was modified externally\n"
|
"'" + buffer.display_name() + "' was modified externally\n"
|
||||||
"press <ret>, r or y to reload, <esc>, k or n to keep",
|
"press <ret> or y to reload, <esc> or n to keep",
|
||||||
CharCoord{}, get_face("Information"), InfoStyle::Prompt);
|
CharCoord{}, get_face("Information"), InfoStyle::Prompt);
|
||||||
|
|
||||||
m_input_handler.on_next_key(KeymapMode::None,
|
m_buffer_reload_dialog_opened = true;
|
||||||
[this, filename](Key key, Context& context) {
|
m_input_handler.on_next_key(KeymapMode::None, [this](Key key, Context&){ on_buffer_reload_key(key); });
|
||||||
m_ui->info_hide();
|
|
||||||
|
|
||||||
Buffer* buf = BufferManager::instance().get_buffer_ifp(filename);
|
|
||||||
// buffer got deleted while waiting for the key, do nothing
|
|
||||||
if (not buf)
|
|
||||||
return;
|
|
||||||
if (key == 'r' or key == 'y' or key == ctrl('m'))
|
|
||||||
reload_buffer(context, filename);
|
|
||||||
else if (key == 'k' or key == 'n' or key == Key::Escape)
|
|
||||||
{
|
|
||||||
// reread timestamp in case the file was modified again
|
|
||||||
buf->set_fs_timestamp(get_fs_timestamp(filename));
|
|
||||||
print_status({ "'" + buf->display_name() + "' kept",
|
|
||||||
get_face("Information") });
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
reload_buffer();
|
||||||
print_status({ "'" + key_to_str(key) + "' is not a valid choice",
|
|
||||||
get_face("Error") });
|
|
||||||
check_buffer_fs_timestamp();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reload_buffer(context(), filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView Client::get_env_var(const String& name) const
|
StringView Client::get_env_var(const String& name) const
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
UserInterface& ui() const { return *m_ui; }
|
UserInterface& ui() const { return *m_ui; }
|
||||||
Window& window() const { return *m_window; }
|
Window& window() const { return *m_window; }
|
||||||
|
|
||||||
void check_buffer_fs_timestamp();
|
void check_if_buffer_needs_reloading();
|
||||||
|
|
||||||
Context& context() { return m_input_handler.context(); }
|
Context& context() { return m_input_handler.context(); }
|
||||||
const Context& context() const { return m_input_handler.context(); }
|
const Context& context() const { return m_input_handler.context(); }
|
||||||
|
@ -55,6 +55,10 @@ public:
|
||||||
private:
|
private:
|
||||||
void on_option_changed(const Option& option) override;
|
void on_option_changed(const Option& option) override;
|
||||||
|
|
||||||
|
void on_buffer_reload_key(Key key);
|
||||||
|
void close_buffer_reload_dialog();
|
||||||
|
void reload_buffer();
|
||||||
|
|
||||||
Optional<Key> get_next_key(EventMode mode);
|
Optional<Key> get_next_key(EventMode mode);
|
||||||
|
|
||||||
DisplayLine generate_mode_line() const;
|
DisplayLine generate_mode_line() const;
|
||||||
|
@ -71,6 +75,8 @@ private:
|
||||||
DisplayLine m_mode_line;
|
DisplayLine m_mode_line;
|
||||||
|
|
||||||
Vector<Key, MemoryDomain::Client> m_pending_keys;
|
Vector<Key, MemoryDomain::Client> m_pending_keys;
|
||||||
|
|
||||||
|
bool m_buffer_reload_dialog_opened = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,13 +42,19 @@ public:
|
||||||
bool validate_client_name(StringView name) const;
|
bool validate_client_name(StringView name) const;
|
||||||
void remove_client(Client& client);
|
void remove_client(Client& client);
|
||||||
|
|
||||||
|
using ClientList = Vector<std::unique_ptr<Client>, MemoryDomain::Client>;
|
||||||
|
using iterator = ClientList::const_iterator;
|
||||||
|
|
||||||
|
iterator begin() const { return m_clients.begin(); }
|
||||||
|
iterator end() const { return m_clients.end(); }
|
||||||
|
|
||||||
CandidateList complete_client_name(StringView name,
|
CandidateList complete_client_name(StringView name,
|
||||||
ByteCount cursor_pos = -1) const;
|
ByteCount cursor_pos = -1) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String generate_name() const;
|
String generate_name() const;
|
||||||
|
|
||||||
Vector<std::unique_ptr<Client>> m_clients;
|
ClientList m_clients;
|
||||||
Vector<WindowAndSelections, MemoryDomain::Client> m_free_windows;
|
Vector<WindowAndSelections, MemoryDomain::Client> m_free_windows;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
Timer::Callback() : Timer::Callback([this](Timer& timer) {
|
Timer::Callback() : Timer::Callback([this](Timer& timer) {
|
||||||
if (not context().has_client())
|
if (not context().has_client())
|
||||||
return;
|
return;
|
||||||
context().client().check_buffer_fs_timestamp();
|
context().client().check_if_buffer_needs_reloading();
|
||||||
timer.set_next_date(Clock::now() + fs_check_timeout);
|
timer.set_next_date(Clock::now() + fs_check_timeout);
|
||||||
})}
|
})}
|
||||||
{}
|
{}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user