diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2011-12-28 19:04:06 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2011-12-28 19:04:06 +0000 |
| commit | 4de41197c0ae01c8bdce0c4099fa28abbe7197c8 (patch) | |
| tree | 2cbb4c96a71314c0af5f096af1ee65c92436532c /src | |
| parent | c9ac4d615d5a52b07c3bdacac3e1a3c2fe6c48b5 (diff) | |
Add a | key that pipes each selection through an external filter
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cc | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/main.cc b/src/main.cc index b8e0ff2b..11a317d2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -19,6 +19,8 @@ #include <sstream> #include <boost/regex.hpp> #include <ncurses.h> +#include <sys/types.h> +#include <sys/wait.h> using namespace Kakoune; using namespace std::placeholders; @@ -574,6 +576,58 @@ void do_command() catch (prompt_aborted&) {} } +void do_pipe(Window& window, int count) +{ + try + { + auto cmdline = prompt("|", complete_nothing); + + window.buffer().begin_undo_group(); + for (auto& sel : const_cast<const Window&>(window).selections()) + { + int write_pipe[2]; + int read_pipe[2]; + + pipe(write_pipe); + pipe(read_pipe); + + if (pid_t pid = fork()) + { + close(write_pipe[0]); + close(read_pipe[1]); + + std::string content = window.buffer().string(sel.begin(), sel.end()); + write(write_pipe[1], content.c_str(), content.size()); + close(write_pipe[1]); + + std::string new_content; + char buffer[1024]; + while (size_t size = read(read_pipe[0], buffer, 1024)) + { + new_content += std::string(buffer, buffer+size); + } + close(read_pipe[0]); + waitpid(pid, NULL, 0); + + window.buffer().modify(Modification::make_erase(sel.begin(), sel.end())); + window.buffer().modify(Modification::make_insert(sel.begin(), new_content)); + } + else + { + close(write_pipe[1]); + close(read_pipe[0]); + + dup2(read_pipe[1], 1); + dup2(write_pipe[0], 0); + + execlp("sh", "sh", "-c", cmdline.c_str(), NULL); + } + } + window.buffer().end_undo_group(); + } + catch (prompt_aborted&) {} +} + void do_search(Window& window) { try @@ -696,6 +750,7 @@ std::unordered_map<Key, std::function<void (Window& window, int count)>> keymap { return Selection(cursor.buffer().begin(), cursor.buffer().end()-1); }); } }, { { Key::Modifiers::None, ':' }, [](Window& window, int count) { do_command(); } }, + { { Key::Modifiers::None, '|' }, do_pipe }, { { Key::Modifiers::None, ' ' }, [](Window& window, int count) { window.clear_selections(); } }, { { Key::Modifiers::None, 'w' }, [](Window& window, int count) { do { window.select(select_to_next_word); } while(--count > 0); } }, { { Key::Modifiers::None, 'e' }, [](Window& window, int count) { do { window.select(select_to_next_word_end); } while(--count > 0); } }, |
