]> git.mdlowis.com Git - projs/tide.git/commitdiff
move pty logic to pty.c and added shortcuts for ^c ^d and ^z
authorMichael D. Lowis <mike.lowis@gentex.com>
Tue, 18 Jul 2017 15:15:15 +0000 (11:15 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Tue, 18 Jul 2017 15:15:15 +0000 (11:15 -0400)
Makefile
inc/edit.h
lib/pty.c [new file with mode: 0644]
tide.c

index 2507e71a0d9e58a24068391c340f617c836ede5b..6793735a638dff321c8cb9bd2acb58b143b74b23 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,8 @@ LIBEDIT_OBJS =     \
        lib/win.o      \
        lib/colors.o   \
        lib/config.o   \
-       lib/event.o
+       lib/event.o    \
+       lib/pty.o
 
 TEST_BINS =     \
        tests/tide  \
index 36081f82cbe9efd2ceeedccdbd2ebb2f821f0a4c..d37e0df4942e8c7f946182f47da0b15be77afd18 100644 (file)
@@ -228,6 +228,15 @@ void exec_job(char** cmd, char* data, size_t ndata, View* dest);
 void exec_cmd(char** cmd, char* text, char** out, char** err);
 int exec_spawn(char** cmd, int* in, int* out);
 
+/* Pseudo-Terminal Handling
+ *****************************************************************************/
+bool pty_active(void);
+void pty_spawn(char** argv);
+void pty_send(char* cmd);
+void pty_send_intr(void);
+void pty_send_eof(void);
+void pty_send_susp(void);
+
 /* Configuration Data
  *****************************************************************************/
 enum { /* Configuration Variables */
diff --git a/lib/pty.c b/lib/pty.c
new file mode 100644 (file)
index 0000000..1a2ae27
--- /dev/null
+++ b/lib/pty.c
@@ -0,0 +1,71 @@
+#define _XOPEN_SOURCE 700
+#include <stdc.h>
+#include <x11.h>
+#include <utf.h>
+#include <edit.h>
+#include <win.h>
+#include <shortcuts.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/select.h>
+#ifdef __MACH__
+    #include <util.h>
+#else
+    #include <pty.h>
+#endif
+
+static int PtyFD = -1;
+
+static void update(int fd, void* data);
+
+bool pty_active(void) { return (PtyFD >= 0);}
+void pty_send_intr(void) { (void)write(PtyFD, "\x03", 1); }
+void pty_send_eof(void) { (void)write(PtyFD, "\x04", 1); }
+void pty_send_susp(void) { (void)write(PtyFD, "\x1A", 1); }
+
+void pty_spawn(char** argv) {
+    assert(!pty_active());
+    struct termios tio;
+    pid_t pid;
+    putenv("TERM=dumb");
+    switch ( (pid = forkpty(&PtyFD, NULL, NULL, NULL)) ) {
+        case -1: // Failed
+            die("forkpty() :");
+            break;
+
+        case 0: // Child Process
+            if (execvp(argv[0], argv) < 0)
+                die("execvp('%s', ...) :", argv[0]);
+            exit(EXIT_FAILURE);
+            break;
+
+        default: // Parent Process
+            tcgetattr(PtyFD, &tio);
+            tio.c_lflag      &= ~(ECHO | ECHONL);
+            tio.c_cc[ VMIN ]  = 1;
+            tio.c_cc[ VTIME ] = 0;
+            tcsetattr(PtyFD, TCSANOW, &tio);
+            break;
+    }
+    event_watchfd(PtyFD, INPUT, update, NULL);
+}
+
+void pty_send(char* str) {
+    if (write(PtyFD, str, strlen(str)-1) < 0)
+        PtyFD = -1;
+}
+
+static void update(int fd, void* data) {
+    /* Read from command if we have one */
+    long n = 0, i = 0;
+    static char cmdbuf[8192];
+    if ((n = read(PtyFD, cmdbuf, sizeof(cmdbuf))) < 0)
+        PtyFD = -1;
+    while (i < n) {
+        Rune rune = 0;
+        size_t length = 0;
+        while (!utf8decode(&rune, &length, cmdbuf[i++]));
+        view_insert(win_view(EDIT), false, rune);
+    }
+    win_buf(EDIT)->outpoint = win_view(EDIT)->selection.end;
+}
diff --git a/tide.c b/tide.c
index 47466df78ed608669f658f3e0cfc73a924028b73..10f1ec0c77a52bd9f0059641ca1a0968c9dbe9be 100644 (file)
--- a/tide.c
+++ b/tide.c
@@ -1,4 +1,3 @@
-#define _XOPEN_SOURCE 700
 #include <stdc.h>
 #include <x11.h>
 #include <utf.h>
@@ -7,12 +6,6 @@
 #include <shortcuts.h>
 #include <ctype.h>
 #include <unistd.h>
-#include <sys/select.h>
-#ifdef __MACH__
-    #include <util.h>
-#else
-    #include <pty.h>
-#endif
 
 typedef struct {
     char* tag;
@@ -22,7 +15,6 @@ typedef struct {
     } action;
 } Tag;
 
-static int CmdFD = -1;
 static Tag Builtins[];
 static int SearchDir = DOWN;
 static char* SearchTerm = NULL;
@@ -492,6 +484,12 @@ static KeyBinding Bindings[] = {
     { ModCtrl,      'n',        new_win      },
     { ModOneOrMore, '\n',       newline      },
     { ModCtrl,      ' ',        complete     },
+
+    /* Pseudo-terminal control shortcuts */
+    { ModCtrl|ModShift, 'c', pty_send_intr },
+    { ModCtrl|ModShift, 'd', pty_send_eof  },
+    { ModCtrl|ModShift, 'z', pty_send_susp },
+
     { 0, 0, 0 }
 };
 
@@ -548,62 +546,19 @@ bool update_needed(void) {
 }
 
 static void oninput(Rune rune) {
-    view_insert(win_view(FOCUSED), (CmdFD == -1), rune);
+    view_insert(win_view(FOCUSED), !pty_active(), rune);
     if (win_getregion() == EDIT) {
         size_t point = win_buf(EDIT)->outpoint;
         size_t pos   = win_view(EDIT)->selection.end;
         if ((rune == '\n' || rune == RUNE_CRLF) && pos > point) {
             Sel range = { .beg = point, .end = pos };
             char* str = view_getstr(win_view(EDIT), &range);
-            if (write(CmdFD, str, strlen(str)-1) < 0)
-                CmdFD = -1;
+            pty_send(str);
             free(str);
         }
     }
 }
 
-int pty_spawn(char** argv) {
-    int fd;
-    struct termios tio;
-    pid_t pid;
-    putenv("TERM=dumb");
-    switch ( (pid = forkpty(&fd, NULL, NULL, NULL)) ) {
-        case -1: // Failed
-            die("forkpty() :");
-            break;
-
-        case 0: // Child Process
-            if (execvp(argv[0], argv) < 0)
-                die("execvp('%s', ...) :", argv[0]);
-            exit(EXIT_FAILURE);
-            break;
-
-        default: // Parent Process
-            tcgetattr(fd, &tio);
-            tio.c_lflag      &= ~(ECHO | ECHONL);
-            tio.c_cc[ VMIN ]  = 1;
-            tio.c_cc[ VTIME ] = 0;
-            tcsetattr(fd, TCSANOW, &tio);
-            break;
-    }
-    return fd;
-}
-
-void pty_update(int fd, void* data) {
-    /* Read from command if we have one */
-    long n = 0, i = 0;
-    static char cmdbuf[8192];
-    if ((n = read(CmdFD, cmdbuf, sizeof(cmdbuf))) < 0)
-        CmdFD = -1;
-    while (i < n) {
-        Rune rune = 0;
-        size_t length = 0;
-        while (!utf8decode(&rune, &length, cmdbuf[i++]));
-        view_insert(win_view(EDIT), false, rune);
-    }
-    win_buf(EDIT)->outpoint = win_view(EDIT)->selection.end;
-}
-
 void edit_relative(char* path) {
     char *currdir = NULL, *currpath = NULL, *relpath = NULL;
     char* origdir = getcurrdir();
@@ -659,8 +614,7 @@ void edit_command(char** cmd) {
     config_set_int(TabWidth, 8);
     win_setlinenums(false);
     win_setruler(0);
-    CmdFD = pty_spawn(*cmd ? cmd : shellcmd);
-    event_watchfd(CmdFD, INPUT, pty_update, NULL);
+    pty_spawn(*cmd ? cmd : shellcmd);
 }
 
 #ifndef TEST