]> git.mdlowis.com Git - projs/tide.git/commitdiff
added logic to highlight command output upon completion
authorMichael D. Lowis <mike@mdlowis.com>
Thu, 13 Jul 2017 01:05:18 +0000 (21:05 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Thu, 13 Jul 2017 01:05:18 +0000 (21:05 -0400)
inc/edit.h
lib/buf.c
lib/exec.c
lib/win.c
tide.c

index 01e535da0917427e258036a25479365552c2eb5f..da3cbc4235cb4b005b234691c144d0af87a2dc1a 100644 (file)
@@ -224,12 +224,12 @@ Rune view_getrune(View* view);
 
 /* Command Executions
  *****************************************************************************/
-void cmdreap(void);
 int cmdspawn(char** cmd, int* in, int* out);
 int cmdrun(char** cmd, char** err);
 char* cmdread(char** cmd, char** err);
 void cmdwrite(char** cmd, char* text, char** err);
 char* cmdwriteread(char** cmd, char* text, char** err);
+void exec_reap(void);
 void exec_job(char** cmd, char* data, size_t ndata, View* dest);
 
 /* Configuration Data
index bd21118f8019f17b18083219db043c5f1a61fb3b..51732b95bcc350caae48ab12a76781eff744c474 100644 (file)
--- a/lib/buf.c
+++ b/lib/buf.c
@@ -183,12 +183,12 @@ size_t buf_delete(Buf* buf, size_t beg, size_t end) {
 size_t buf_change(Buf* buf, size_t beg, size_t end) {
     /* delete the range first */
     size_t off = buf_delete(buf, beg, end);
-    /* now create a new insert item of length 0 withhe same transaction id as
+    /* now create a new insert item of length 0 with the same transaction id as
        the delete. This will cause subsequent inserts to be coalesced into the
        same transaction */
     Log* dellog = buf->undo;
     Log* inslog = (Log*)calloc(sizeof(Log), 1);
-    inslog->transid = dellog->transid;
+    inslog->transid = (dellog ? dellog->transid : buf->transid);
     inslog->insert = true;
     inslog->data.ins.beg = beg;
     inslog->data.ins.end = beg;
index 488fe1ce2ee978c8d225073037f28bf6399b5c7c..053d56e5a333f91a9f97c5af4b357c2857ec91f2 100644 (file)
@@ -54,11 +54,6 @@ static int execute(char** cmd, Proc* proc) {
     return proc->pid;
 }
 
-void cmdreap(void) {
-    while(NumChildren && (waitpid(-1, NULL, WNOHANG) > 0))
-        NumChildren--;
-}
-
 int cmdspawn(char** cmd, int* in, int* out) {
     Proc proc;
     if (execute(cmd, &proc) < 0) {
@@ -140,24 +135,71 @@ char* cmdwriteread(char** cmd, char* text, char** err) {
 typedef struct Job Job;
 
 typedef struct {
-    View* view;
-    char nbytes;
-    char bytes[6];
-} Recvr;
+    View* view;   /* destination view */
+    size_t count; /* number of bytes written */
+} Rcvr;
 
 struct Job {
-    Job* next;       /* Pointer to previous job in the job list */
-    Job* prev;       /* Pointer to next job in the job list */
-    size_t ndata;    /* number of bytes to write to stdout */
-    size_t nwrite;   /* number of bytes written to stdout so far */
-    char* data;      /* data to write to stdout */
-    Recvr err_recvr; /* view in which the error output will be placed */
-    Recvr out_recvr; /* view in which the output will be placed */
-    int pid;         /* process id of the running job */
+    Job* next;     /* Pointer to previous job in the job list */
+    Job* prev;     /* Pointer to next job in the job list */
+    int pid;       /* process id of the running job */
+    size_t ndata;  /* number of bytes to write to stdout */
+    size_t nwrite; /* number of bytes written to stdout so far */
+    char* data;    /* data to write to stdout */
+    Rcvr err_rcvr; /* reciever for the error output of the job */
+    Rcvr out_rcvr; /* receiver for the normal output of the job */
+    View* dest;    /* destination view where output will be placed */
 };
 
 static Job* JobList = NULL;
 
+static void send_data(int fd, void* data);
+static void recv_data(int fd, void* data);
+static void watch_or_close(bool valid, int dir, int fd, void* data);
+
+void exec_reap(void) {
+    int pid;
+    while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
+        Job* job = JobList;
+        for (; job && job->pid != pid; job = job->next);
+        if (job && job->pid == pid) {
+            if (job->prev) {
+                job->prev->next = job->next;
+                job->next->prev = job->prev;
+            } else {
+                JobList = job->next;
+            }
+            free(job);
+        }
+    }
+}
+
+void exec_job(char** cmd, char* data, size_t ndata, View* dest) {
+    Proc proc;
+    Job* job = calloc(1, sizeof(Job));
+    job->pid = execute(cmd, &proc);
+    if (job->pid < 0) {
+        die("job_start() :");
+    } else {
+        /* add the job to the job list */
+        job->err_rcvr.view = win_view(TAGS);
+        job->out_rcvr.view = dest;
+        job->ndata  = ndata;
+        job->nwrite = 0;
+        job->data   = data;
+        job->next   = JobList;
+        if (JobList) JobList->prev = job;
+        JobList = job;
+        /* register watch events for file descriptors */
+        bool need_in  = (job->data != NULL),
+             need_out = (dest != NULL),
+             need_err = (need_in || need_out);
+        watch_or_close(need_in,  OUTPUT, proc.in,  job);
+        watch_or_close(need_out, INPUT,  proc.out, &(job->out_rcvr));
+        watch_or_close(need_err, INPUT,  proc.err, &(job->err_rcvr));
+    }
+}
+
 static void send_data(int fd, void* data) {
     Job* job = data;
     long nwrite = write(fd, (job->data + job->nwrite), job->ndata);
@@ -170,13 +212,19 @@ static void send_data(int fd, void* data) {
 static void recv_data(int fd, void* data) {
     static char buf[4096];
     long i = 0, nread = read(fd, buf, sizeof(buf));
-    Recvr* rcvr = data;
-    if (nread <= 0) { close(fd); return; }
-    for (; i < nread;) {
-        Rune r;
-        size_t len = 0;
-        while (!utf8decode(&r, &len, buf[i++]));
-        view_insert(rcvr->view, false, r);
+    Rcvr* rcvr = data;
+    if (nread > 0) {
+        for (; i < nread;) {
+            Rune r;
+            size_t len = 0;
+            while (!utf8decode(&r, &len, buf[i++]));
+            view_insert(rcvr->view, false, r);
+            rcvr->count++;
+        }
+    } else {
+        close(fd);
+        if (rcvr->count)
+            view_selprev(rcvr->view);
     }
 }
 
@@ -187,26 +235,3 @@ static void watch_or_close(bool valid, int dir, int fd, void* data) {
     else
         close(fd);
 }
-
-void exec_job(char** cmd, char* data, size_t ndata, View* dest) {
-    Proc proc;
-    Job* job = calloc(1, sizeof(Job));
-    job->pid = execute(cmd, &proc);
-    if (job->pid < 0) {
-        die("job_start() :");
-    } else {
-        /* add the job to the job list */
-        job->err_recvr.view = win_view(TAGS);
-        job->out_recvr.view = dest;
-        job->ndata  = ndata;
-        job->nwrite = 0;
-        job->data   = data;
-        job->next   = JobList;
-        if (JobList) JobList->prev = job;
-        JobList = job;
-        /* register watch events for file descriptors */
-        watch_or_close((job->data != NULL), OUTPUT, proc.in, job);
-        watch_or_close((dest != NULL), INPUT, proc.out, &(job->out_recvr));
-        watch_or_close(true, INPUT, proc.err, &(job->err_recvr));
-    }
-}
index e103f3f469ec8d725debf4ecd8103f0fdd68d21a..73dd3997e76d4059a2549f998ada2204afd0359e 100644 (file)
--- a/lib/win.c
+++ b/lib/win.c
@@ -80,6 +80,7 @@ void win_loop(void) {
                 x11_flip();
         }
         x11_flush();
+        exec_reap();
     }
     x11_finish();
 }
diff --git a/tide.c b/tide.c
index 9617ae4ce2a6a46379fcc79d2624854ccfe940d0..60ef10d6e105ff16b3b4f7525d9bd1ee7287b900 100644 (file)
--- a/tide.c
+++ b/tide.c
@@ -84,18 +84,14 @@ static void cmd_exec(char* cmd) {
     View *tags = win_view(TAGS), *edit = win_view(EDIT), *curr = win_view(FOCUSED);
 
     /* execute the job */
-    printf("sigil: '%c'\n", op);
-    printf("data: %d '%s'\n", len, input);
-    if (op == '!') {
-        free(input);
-        exec_job(execcmd, NULL, 0, NULL);
-    } else if (op == '>') {
+    if (op == '!')
+        free(input), exec_job(execcmd, NULL, 0, NULL);
+    else if (op == '>')
         exec_job(execcmd, input, len, tags);
-    } else if (op == '|' || op == ':') {
+    else if (op == '|' || op == ':')
         exec_job(execcmd, input, len, edit);
-    } else {
+    else
         exec_job(execcmd, input, len, (op != '<' ? curr : edit));
-    }
 
 #else
     char op = '\0';