From 40e2fffab2c560eff06c96e1e102de9c3df6652f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Diego=20Aur=C3=A9lio=20Mesquita?= Date: Fri, 16 Feb 2018 20:47:06 -0300 Subject: [PATCH] Pipe slected text to external command. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When there is marked text and a command is executed, nano should pipe it to the external command and replace the text it by the command's output. Signed-off-by: Marco Diego Aurélio Mesquita --- src/text.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/text.c b/src/text.c index e80c09c9..6a8040e6 100644 --- a/src/text.c +++ b/src/text.c @@ -1082,10 +1082,33 @@ RETSIGTYPE cancel_command(int signal) nperror("kill"); } +/* Sends buffer pointed to by inptr to file descriptor fd. */ +void send_data(int fd, const filestruct *inptr) +{ + FILE *fp = fdopen(fd, "w"); + + if (fp == NULL) + return; + + while (inptr != NULL) { + /* If last line is empty, we should not send it. */ + if(inptr->next == NULL && inptr->data[0] == '\0') + break; + + fprintf(fp, "%s\n", inptr->data); + inptr = inptr->next; + } + + fclose(fp); +} + /* Execute command in a shell. Return TRUE on success. */ bool execute_command(const char *command) { int fd[2]; + int out_fd[2]; + /* Pipe through which text will be sent for external command. */ + const bool has_selection = openfile->mark; FILE *f; const char *shellenv; struct sigaction oldaction, newaction; @@ -1099,6 +1122,11 @@ bool execute_command(const char *command) return FALSE; } + if (has_selection && pipe(out_fd)) { + statusbar(_("Could not create outgoing pipe")); + return FALSE; + } + /* Check $SHELL for the shell to use. If it isn't set, use /bin/sh. * Note that $SHELL should contain only a path, with no arguments. */ shellenv = getenv("SHELL"); @@ -1111,6 +1139,11 @@ bool execute_command(const char *command) dup2(fd[1], fileno(stdout)); dup2(fd[1], fileno(stderr)); + if (has_selection) { + close(out_fd[1]); + dup2(out_fd[0], fileno(stdin)); + } + /* If execl() returns at all, there was an error. */ execl(shellenv, tail(shellenv), "-c", command, NULL); exit(0); @@ -1125,6 +1158,18 @@ bool execute_command(const char *command) return FALSE; } + /* If text was selected, pipe it to external command. */ + if (has_selection) { + filestruct *was_cutbuffer = cutbuffer; + close(out_fd[0]); + cutbuffer = NULL; + do_cut_text_void(); + send_data(out_fd[1], cutbuffer); + close(out_fd[1]); + free_filestruct(cutbuffer); + cutbuffer = was_cutbuffer; + } + /* Before we start reading the forked command's output, we set * things up so that Ctrl-C will cancel the new process. */ -- 2.11.0