From 8ce9e80a2a041c398ff650533fea7d7a70e44110 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 1/3] 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 | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/text.c b/src/text.c index 6d0cfac5..70e8f2ef 100644 --- a/src/text.c +++ b/src/text.c @@ -1079,10 +1079,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%s", inptr->data, inptr->next == NULL ? "" : "\n"); + 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 *stream; const char *shellenv; struct sigaction oldaction, newaction; @@ -1096,6 +1119,11 @@ bool execute_command(const char *command) return FALSE; } + if (has_selection && pipe(out_fd)) { + statusbar(_("Could not create outgoing pipe")); + return FALSE; + } + /* Check which shell to use. If none is specified, use /bin/sh. */ shellenv = getenv("SHELL"); if (shellenv == NULL) @@ -1110,6 +1138,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)); + } + /* Run the given command inside the preferred shell. */ execl(shellenv, tail(shellenv), "-c", command, NULL); @@ -1126,6 +1159,21 @@ 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. */ + /* Re-enable interpretation of the special control keys so that we get * SIGINT when Ctrl-C is pressed. */ enable_signals(); -- 2.11.0