From c8ea2e78f9a926268836d5a1830cf7f39a1943d8 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 4 Nov 2014 13:55:56 +0000 Subject: [PATCH] Reuse existing buffer when creating a fifo one That way, client having this buffer already visible wont switch to another one due to previous buffer getting deleted --- src/buffer_utils.cc | 48 +++++++++++++++++++++++++-------------------- src/commands.cc | 2 -- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc index c3dd755c..12ffae19 100644 --- a/src/buffer_utils.cc +++ b/src/buffer_utils.cc @@ -82,9 +82,30 @@ Buffer* create_buffer_from_data(StringView data, StringView name, Buffer* create_fifo_buffer(String name, int fd, bool scroll) { - Buffer* buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo); + static ValueId s_fifo_watcher_id = ValueId::get_free_id(); - auto watcher = new FDWatcher(fd, [buffer, scroll](FDWatcher& watcher) { + Buffer* buffer = BufferManager::instance().get_buffer_ifp(name); + if (buffer) + { + buffer->flags() |= Buffer::Flags::NoUndo; + buffer->reload(std::vector({"\n"_str}), 0); + } + else + buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo); + + auto watcher_deleter = [buffer](FDWatcher* watcher) { + kak_assert(buffer->flags() & Buffer::Flags::Fifo); + close(watcher->fd()); + buffer->run_hook_in_own_context("BufCloseFifo", ""); + buffer->flags() &= ~Buffer::Flags::Fifo; + watcher->~FDWatcher(); + }; + + // capture a non static one to silence a warning. + ValueId fifo_watcher_id = s_fifo_watcher_id; + + std::unique_ptr watcher( + new FDWatcher(fd, [buffer, scroll, fifo_watcher_id](FDWatcher& watcher) { constexpr size_t buffer_size = 2048; // if we read data slower than it arrives in the fifo, limiting the // iteration number allows us to go back go back to the event loop and @@ -122,26 +143,11 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll) select(fifo+1, &rfds, nullptr, nullptr, &tv) == 1); if (count <= 0) - { - kak_assert(buffer->flags() & Buffer::Flags::Fifo); - buffer->flags() &= ~Buffer::Flags::Fifo; - buffer->flags() &= ~Buffer::Flags::NoUndo; - close(fifo); - buffer->run_hook_in_own_context("BufCloseFifo", ""); - delete &watcher; - } - }); + buffer->values().erase(fifo_watcher_id); // will delete this + }), std::move(watcher_deleter)); - buffer->hooks().add_hook("BufClose", "", - [buffer, watcher](StringView, const Context&) { - // Check if fifo is still alive, else watcher is already dead - if (buffer->flags() & Buffer::Flags::Fifo) - { - close(watcher->fd()); - buffer->run_hook_in_own_context("BufCloseFifo", ""); - delete watcher; - } - }); + buffer->values()[fifo_watcher_id] = Value(std::move(watcher)); + buffer->flags() = Buffer::Flags::Fifo | Buffer::Flags::NoUndo; return buffer; } diff --git a/src/commands.cc b/src/commands.cc index c17c5593..46dbd650 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -42,8 +42,6 @@ Buffer* open_fifo(StringView name, StringView filename, bool scroll) if (fd < 0) throw runtime_error("unable to open " + filename); - BufferManager::instance().delete_buffer_if_exists(name); - return create_fifo_buffer(name, fd, scroll); }