diff options
| author | Maxime Coste <mawww@kakoune.org> | 2025-06-27 11:12:14 +1000 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2025-06-27 12:04:37 +1000 |
| commit | 5201a12010ee9ad91c99559b1756d59fdbb283d9 (patch) | |
| tree | 376c9bb99fdbc9d4bf7d74753ea3db13d85911a1 /src | |
| parent | ba41928aa7b052b037092c38a7cd6a3c05bb928e (diff) | |
Prevent changing Client's buffer while locked
If the current buffer is locked, it means we are in the middle of
creating the client or already changing the buffer, error out in this
case instead of getting into an inconsistent state.
Fixes #5338
Diffstat (limited to 'src')
| -rw-r--r-- | src/client.cc | 3 | ||||
| -rw-r--r-- | src/client_manager.cc | 10 |
2 files changed, 8 insertions, 5 deletions
diff --git a/src/client.cc b/src/client.cc index 2cb1c973..14b7b7bc 100644 --- a/src/client.cc +++ b/src/client.cc @@ -194,6 +194,9 @@ void Client::change_buffer(Buffer& buffer, Optional<FunctionRef<void()>> set_sel if (m_buffer_reload_dialog_opened) close_buffer_reload_dialog(); + if (context().buffer().flags() & Buffer::Flags::Locked) + throw runtime_error("Changing buffer is not allowed while current buffer is locked"); + buffer.flags() |= Buffer::Flags::Locked; OnScopeEnd unlock{[&] { buffer.flags() &= ~Buffer::Flags::Locked; }}; diff --git a/src/client_manager.cc b/src/client_manager.cc index 2e7d76e7..6798864e 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -67,17 +67,18 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui, int pi m_clients.emplace_back(client); auto& context = client->context(); - if (buffer->name() == "*scratch*") + if (context.buffer().name() == "*scratch*") context.print_status({"This *scratch* buffer won't be automatically saved", context.faces()["Information"]}); if (init_coord) { - auto& selections = context.selections_write_only(); - selections = SelectionList(*buffer, buffer->clamp(*init_coord)); + context.selections_write_only() = SelectionList(*buffer, context.buffer().clamp(*init_coord)); context.window().center_line(init_coord->line); } + auto(std::move(unlock)); // unlock now + try { context.hooks().run_hook(Hook::ClientCreate, context.name(), context); @@ -86,8 +87,7 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui, int pi catch (Kakoune::runtime_error& error) { context.print_status({error.what().str(), context.faces()["Error"]}); - context.hooks().run_hook(Hook::RuntimeError, error.what(), - context); + context.hooks().run_hook(Hook::RuntimeError, error.what(), context); } // Do not return the client if it already got moved to the trash |
