From db98bcc278483499ef5cbabc6c317a038cd62a59 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Wed, 29 Aug 2012 00:17:37 +0200 Subject: [PATCH] Add an -fifo option to the 'edit' command In -fifo mode, the buffer's file is used as a fifo, writes are tracked and udpated in the buffer. This should be useful for grep and make commands. --- src/commands.cc | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/commands.cc b/src/commands.cc index 0fcffabc..ac0467a8 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -14,11 +14,16 @@ #include "register_manager.hh" #include "completion.hh" #include "shell_manager.hh" +#include "event_manager.hh" #if defined(__APPLE__) #include #endif +#include +#include +#include + namespace Kakoune { @@ -229,26 +234,55 @@ Buffer* open_or_create(const String& filename, Context& context) return buffer; } +Buffer* open_fifo(const String& name , const String& filename, Context& context) +{ + int fd = open(filename.c_str(), O_RDONLY); + if (fd < 0) + throw runtime_error("unable to open " + filename); + Buffer* buffer = new Buffer(name, Buffer::Type::Scratch); + + buffer->hook_manager().add_hook( + "BufClose", [=](const String&, const Context&) + { EventManager::instance().unwatch(fd); close(fd); } + ); + + EventManager::instance().watch(fd, [=, &context](int fd) { + char data[512]; + ssize_t count = read(fd, data, 512); + if (count > 0) + { + buffer->insert(buffer->end(), String(data, data + count)); + buffer->reset_undo_data(); + context.draw_ifn(); + } + }); + + return buffer; +} + template void edit(const CommandParameters& params, Context& context) { - ParametersParser parser(params, { { "scratch", false } }); + ParametersParser parser(params, { { "scratch", false }, + { "fifo", true } }); const size_t param_count = parser.positional_count(); if (param_count == 0 or param_count > 3) throw wrong_argument_count(); - const String& filename = parser[0]; + const String& name = parser[0]; Buffer* buffer = nullptr; if (not force_reload) - buffer = BufferManager::instance().get_buffer(filename); + buffer = BufferManager::instance().get_buffer(name); if (not buffer) { if (parser.has_option("scratch")) - buffer = new Buffer(filename, Buffer::Type::Scratch); + buffer = new Buffer(name, Buffer::Type::Scratch); + else if (parser.has_option("fifo")) + buffer = open_fifo(name, parser.option_value("fifo"), context); else - buffer = open_or_create(filename, context); + buffer = open_or_create(name, context); } Window& window = *buffer->get_or_create_window();