Ensure buffer create/close hooks are run at appropriate times

They used to be ran before the buffer was added to the buffer list
we now run them afterwards.
This commit is contained in:
Maxime Coste 2016-07-10 16:01:33 +01:00
parent 6bcfc7268f
commit 530ecf212e
4 changed files with 45 additions and 17 deletions

View File

@ -69,8 +69,6 @@ Buffer::Buffer(String name, Flags flags, StringView data,
m_last_save_undo_index(0),
m_fs_timestamp(fs_timestamp)
{
options().register_watcher(*this);
ParsedLines parsed_lines = parse_lines(data);
if (parsed_lines.lines.empty())
@ -87,9 +85,24 @@ Buffer::Buffer(String name, Flags flags, StringView data,
apply_options(options(), parsed_lines);
if (flags & Flags::File)
// now we may begin to record undo data
if (not (flags & Flags::NoUndo))
m_flags &= ~Flags::NoUndo;
}
void Buffer::on_registered()
{
// Ignore debug buffer, as it can be created in many
// corner cases (including while destroying the BufferManager
// if a BufClose hooks triggers writing to it.
if (m_flags & Flags::Debug)
return;
options().register_watcher(*this);
if (m_flags & Flags::File)
{
if (flags & Flags::New)
if (m_flags & Buffer::Flags::New)
run_hook_in_own_context("BufNew", m_name);
else
{
@ -100,19 +113,21 @@ Buffer::Buffer(String name, Flags flags, StringView data,
run_hook_in_own_context("BufCreate", m_name);
// now we may begin to record undo data
if (not (flags & Flags::NoUndo))
m_flags &= ~Flags::NoUndo;
for (auto& option : options().flatten_options())
on_option_changed(*option);
}
Buffer::~Buffer()
void Buffer::on_unregistered()
{
run_hook_in_own_context("BufClose", m_name);
if (m_flags & Flags::Debug)
return;
options().unregister_watcher(*this);
run_hook_in_own_context("BufClose", m_name);
}
Buffer::~Buffer()
{
m_values.clear();
}

View File

@ -200,6 +200,10 @@ public:
ConstArrayView<Change> changes_since(size_t timestamp) const;
String debug_description() const;
// Methods called by the buffer manager
void on_registered();
void on_unregistered();
private:
void on_option_changed(const Option& option) override;

View File

@ -22,6 +22,9 @@ BufferManager::~BufferManager()
// hook while clearing m_buffers
m_buffer_trash = std::move(m_buffers);
for (auto& buffer : m_buffer_trash)
buffer->on_unregistered();
// Make sure not clients exists
ClientManager::instance().clear();
}
@ -37,9 +40,12 @@ Buffer* BufferManager::create_buffer(String name, Buffer::Flags flags,
throw name_not_unique();
}
m_buffers.emplace(m_buffers.begin(), new Buffer{std::move(name), flags,
data, fs_timestamp});
return m_buffers.front().get();
m_buffers.emplace(m_buffers.begin(),
new Buffer{std::move(name), flags, data, fs_timestamp});
auto& buffer = *m_buffers.front();
buffer.on_registered();
return &buffer;
}
void BufferManager::delete_buffer(Buffer& buffer)
@ -48,10 +54,13 @@ void BufferManager::delete_buffer(Buffer& buffer)
{ return p.get() == &buffer; });
kak_assert(it != m_buffers.end());
ClientManager::instance().ensure_no_client_uses_buffer(buffer);
m_buffer_trash.emplace_back(std::move(*it));
m_buffers.erase(it);
buffer.on_unregistered();
}
Buffer* BufferManager::get_buffer_ifp(StringView name)

View File

@ -664,11 +664,11 @@ int run_filter(StringView keystr, StringView commands, ConstArrayView<StringView
}
if (not isatty(0))
{
Buffer* buffer = buffer_manager.create_buffer(
Buffer& buffer = *buffer_manager.create_buffer(
"*stdin*", Buffer::Flags::None, read_fd(0), InvalidTime);
apply_to_buffer(*buffer);
write_buffer_to_fd(*buffer, 1);
buffer_manager.delete_buffer(*buffer);
apply_to_buffer(buffer);
write_buffer_to_fd(buffer, 1);
buffer_manager.delete_buffer(buffer);
}
}
catch (Kakoune::runtime_error& err)