nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Nano-devel] [PATCH 1/2] new feature: pipe selected text to external com


From: Benno Schulenberg
Subject: [Nano-devel] [PATCH 1/2] new feature: pipe selected text to external command when executing one
Date: Tue, 1 May 2018 10:59:09 +0200

From: Marco Diego Aurélio Mesquita <address@hidden>

[Patch has been updated for current state of git master.]

When a region is marked and a command is executed (^R^X), nano now
pipes the marked text to the external command and replaces the text
with the command's output.

Signed-off-by: Marco Diego Aurélio Mesquita <address@hidden>
---
 src/text.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/src/text.c b/src/text.c
index 7f0bdb33..91b91603 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];
+               /* The pipe through which text will be sent to an 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,13 @@ bool execute_command(const char *command)
                dup2(fd[1], fileno(stdout));
                dup2(fd[1], fileno(stderr));
 
+               /* If the parent sends the selected text, connect the read end 
of
+                * the pipe to the child's input stream. */
+               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 +1161,18 @@ bool execute_command(const char *command)
                return FALSE;
        }
 
+       /* If text was selected, cut it and pipe it to the 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;
+       }
+
        /* Re-enable interpretation of the special control keys so that we get
         * SIGINT when Ctrl-C is pressed. */
        enable_signals();
-- 
2.17.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]