diff --git a/src/client.cc b/src/client.cc index 07a44df4..97ceb632 100644 --- a/src/client.cc +++ b/src/client.cc @@ -125,6 +125,9 @@ DisplayLine Client::generate_mode_line() const void Client::change_buffer(Buffer& buffer) { + if (m_buffer_reload_dialog_opened) + close_buffer_reload_dialog(); + auto& client_manager = ClientManager::instance(); m_window->options().unregister_watcher(*this); client_manager.add_free_window(std::move(m_window), @@ -166,21 +169,58 @@ void Client::redraw_ifn() context().ui().refresh(); } -static void reload_buffer(Context& context, StringView filename) +void Client::reload_buffer() { - CharCoord view_pos = context.window().position(); - ByteCoord cursor_pos = context.selections().main().cursor(); - Buffer* buf = create_buffer_from_file(filename); - if (not buf) - return; - context.change_buffer(*buf); - context.selections() = SelectionList{ *buf, buf->clamp(cursor_pos)}; - context.window().set_position(view_pos); - context.print_status({ "'" + buf->display_name() + "' reloaded", - get_face("Information") }); + auto& buffer = context().buffer(); + kak_assert(buffer.flags() & Buffer::Flags::File); + CharCoord view_pos = context().window().position(); + ByteCoord cursor_pos = context().selections().main().cursor(); + Buffer* buf = create_buffer_from_file(buffer.name()); + kak_assert(buf == &buffer); + context().selections() = SelectionList{buffer, buffer.clamp(cursor_pos)}; + context().window().set_position(view_pos); + context().print_status({ "'" + buffer.display_name() + "' reloaded", + 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(); auto reload = context().options()["autoreload"].get(); @@ -196,36 +236,14 @@ void Client::check_buffer_fs_timestamp() m_ui->info_show( "reload '" + buffer.display_name() + "' ?", "'" + buffer.display_name() + "' was modified externally\n" - "press , r or y to reload, , k or n to keep", + "press or y to reload, or n to keep", CharCoord{}, get_face("Information"), InfoStyle::Prompt); - m_input_handler.on_next_key(KeymapMode::None, - [this, filename](Key key, Context& context) { - 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 - { - print_status({ "'" + key_to_str(key) + "' is not a valid choice", - get_face("Error") }); - check_buffer_fs_timestamp(); - } - }); + m_buffer_reload_dialog_opened = true; + m_input_handler.on_next_key(KeymapMode::None, [this](Key key, Context&){ on_buffer_reload_key(key); }); } else - reload_buffer(context(), filename); + reload_buffer(); } StringView Client::get_env_var(const String& name) const diff --git a/src/client.hh b/src/client.hh index 85040ad4..0f7eeb40 100644 --- a/src/client.hh +++ b/src/client.hh @@ -40,7 +40,7 @@ public: UserInterface& ui() const { return *m_ui; } Window& window() const { return *m_window; } - void check_buffer_fs_timestamp(); + void check_if_buffer_needs_reloading(); Context& context() { return m_input_handler.context(); } const Context& context() const { return m_input_handler.context(); } @@ -55,6 +55,10 @@ public: private: void on_option_changed(const Option& option) override; + void on_buffer_reload_key(Key key); + void close_buffer_reload_dialog(); + void reload_buffer(); + Optional get_next_key(EventMode mode); DisplayLine generate_mode_line() const; @@ -71,6 +75,8 @@ private: DisplayLine m_mode_line; Vector m_pending_keys; + + bool m_buffer_reload_dialog_opened = false; }; } diff --git a/src/client_manager.hh b/src/client_manager.hh index fae31e00..2876667a 100644 --- a/src/client_manager.hh +++ b/src/client_manager.hh @@ -42,13 +42,19 @@ public: bool validate_client_name(StringView name) const; void remove_client(Client& client); + using ClientList = Vector, 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, ByteCount cursor_pos = -1) const; private: String generate_name() const; - Vector> m_clients; + ClientList m_clients; Vector m_free_windows; }; diff --git a/src/input_handler.cc b/src/input_handler.cc index 354fa973..c0d1c11f 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -64,7 +64,7 @@ public: Timer::Callback() : Timer::Callback([this](Timer& timer) { if (not context().has_client()) return; - context().client().check_buffer_fs_timestamp(); + context().client().check_if_buffer_needs_reloading(); timer.set_next_date(Clock::now() + fs_check_timeout); })} {}