summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2014-04-29 21:37:11 +0100
committerMaxime Coste <frrrwww@gmail.com>2014-04-29 21:37:11 +0100
commit479c067a4096f440398f531c11e4eae802ffe7c9 (patch)
tree438cccc0a9b173e039bae5da34468135ad09f43e /src
parentf68394668174492caa599442e9f7bd344a84d9d8 (diff)
Add support for running Kakoune with redirected stdin
Will read to a *stdin* fifo buffer
Diffstat (limited to 'src')
-rw-r--r--src/buffer_utils.cc35
-rw-r--r--src/buffer_utils.hh2
-rw-r--r--src/commands.cc35
-rw-r--r--src/main.cc17
4 files changed, 58 insertions, 31 deletions
diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc
index af61cb19..7e8f3da4 100644
--- a/src/buffer_utils.cc
+++ b/src/buffer_utils.cc
@@ -1,5 +1,7 @@
#include "buffer_utils.hh"
+#include "event_manager.hh"
+
namespace Kakoune
{
@@ -20,4 +22,37 @@ CharCount get_column(const Buffer& buffer,
return col;
}
+Buffer* create_fifo_buffer(String name, int fd)
+{
+ Buffer* buffer = new Buffer(std::move(name), Buffer::Flags::Fifo | Buffer::Flags::NoUndo);
+
+ auto watcher = new FDWatcher(fd, [buffer](FDWatcher& watcher) {
+ constexpr size_t buffer_size = 1024 * 16;
+ char data[buffer_size];
+ ssize_t count = read(watcher.fd(), data, buffer_size);
+ buffer->insert(buffer->end()-1, count > 0 ? String(data, data+count)
+ : "*** kak: fifo closed ***\n");
+ if (count <= 0)
+ {
+ kak_assert(buffer->flags() & Buffer::Flags::Fifo);
+ buffer->flags() &= ~Buffer::Flags::Fifo;
+ buffer->flags() &= ~Buffer::Flags::NoUndo;
+ close(watcher.fd());
+ delete &watcher;
+ }
+ });
+
+ buffer->hooks().add_hook("BufClose", "",
+ [buffer, watcher](const String&, const Context&) {
+ // Check if fifo is still alive, else watcher is already dead
+ if (buffer->flags() & Buffer::Flags::Fifo)
+ {
+ close(watcher->fd());
+ delete watcher;
+ }
+ });
+
+ return buffer;
+}
+
}
diff --git a/src/buffer_utils.hh b/src/buffer_utils.hh
index 16e2c764..bd08d9b3 100644
--- a/src/buffer_utils.hh
+++ b/src/buffer_utils.hh
@@ -41,6 +41,8 @@ inline void avoid_eol(const Buffer& buffer, Selection& sel)
CharCount get_column(const Buffer& buffer,
CharCount tabstop, BufferCoord coord);
+Buffer* create_fifo_buffer(String name, int fd);
+
}
#endif // buffer_utils_hh_INCLUDED
diff --git a/src/commands.cc b/src/commands.cc
index ae0115a7..d06f75b8 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -2,6 +2,7 @@
#include "buffer.hh"
#include "buffer_manager.hh"
+#include "buffer_utils.hh"
#include "client.hh"
#include "client_manager.hh"
#include "color_registry.hh"
@@ -45,7 +46,7 @@ Buffer* open_or_create(const String& filename, Context& context)
return buffer;
}
-Buffer* open_fifo(const String& name , const String& filename, Context& context)
+Buffer* open_fifo(const String& name , const String& filename)
{
int fd = open(parse_filename(filename).c_str(), O_RDONLY);
fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -54,35 +55,7 @@ Buffer* open_fifo(const String& name , const String& filename, Context& context)
BufferManager::instance().delete_buffer_if_exists(name);
- Buffer* buffer = new Buffer(name, Buffer::Flags::Fifo | Buffer::Flags::NoUndo);
-
- auto watcher = new FDWatcher(fd, [buffer](FDWatcher& watcher) {
- constexpr size_t buffer_size = 1024 * 16;
- char data[buffer_size];
- ssize_t count = read(watcher.fd(), data, buffer_size);
- buffer->insert(buffer->end()-1, count > 0 ? String(data, data+count)
- : "*** kak: fifo closed ***\n");
- if (count <= 0)
- {
- kak_assert(buffer->flags() & Buffer::Flags::Fifo);
- buffer->flags() &= ~Buffer::Flags::Fifo;
- buffer->flags() &= ~Buffer::Flags::NoUndo;
- close(watcher.fd());
- delete &watcher;
- }
- });
-
- buffer->hooks().add_hook("BufClose", "",
- [buffer, watcher](const String&, const Context&) {
- // Check if fifo is still alive, else watcher is already dead
- if (buffer->flags() & Buffer::Flags::Fifo)
- {
- close(watcher->fd());
- delete watcher;
- }
- });
-
- return buffer;
+ return create_fifo_buffer(std::move(name), fd);
}
const PerArgumentCommandCompleter filename_completer({
@@ -138,7 +111,7 @@ void edit(const ParametersParser& parser, Context& context)
buffer = new Buffer(name, Buffer::Flags::None);
}
else if (parser.has_option("fifo"))
- buffer = open_fifo(name, parser.option_value("fifo"), context);
+ buffer = open_fifo(name, parser.option_value("fifo"));
else
buffer = open_or_create(name, context);
}
diff --git a/src/main.cc b/src/main.cc
index d23f8091..b240842e 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -30,6 +30,10 @@
#include <locale>
#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
using namespace Kakoune;
void run_unit_tests();
@@ -192,6 +196,19 @@ void create_local_client(const String& init_command)
}
};
+ if (not isatty(1))
+ throw runtime_error("stdout is not a tty");
+
+ if (not isatty(0))
+ {
+ // move stdin to another fd, and restore tty as stdin
+ int fd = dup(0);
+ int tty = open("/dev/tty", O_RDONLY);
+ dup2(tty, 0);
+ close(tty);
+ create_fifo_buffer("*stdin*", fd);
+ }
+
UserInterface* ui = new LocalNCursesUI{};
static Client* client = ClientManager::instance().create_client(
std::unique_ptr<UserInterface>{ui}, get_env_vars(), init_command);