+++ /dev/null
-#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 send_string(char* str) {
- size_t sz = strlen(str);
- if (str[sz-1] == '\n') str[sz-1] = '\0';
- while (*str) {
- Rune rune = 0;
- size_t length = 0;
- while (!utf8decode(&rune, &length, *str++));
- pty_send_rune(rune);
- }
-}
-
-void pty_send(char* cmd, char* arg) {
- if (!cmd) return;
- view_eof(win_view(EDIT), false);
- send_string(cmd);
- if (arg) {
- pty_send_rune(' ');
- send_string(arg);
- }
- pty_send_rune('\n');
-}
-
-void pty_send_rune(Rune rune) {
- view_insert(win_view(EDIT), false, rune);
- 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(PtyFD, str, strlen(str)-1) < 0)
- PtyFD = -1;
- free(str);
- win_buf(EDIT)->outpoint = pos;
- }
-}
-
-static void read_escape(char* data, long* i, long n) {
- /* only one escape code supported and that is to change the working dir */
- if (data[*i] != 'P') return;
- for (long x = *i; x < n && data[x]; x++)
- if (data[x] == '\a') data[x] = '\0';
- size_t sz = strlen(&data[*i + 1]);
- chdir(&data[*i + 1]);
- *i = *i + 1 + sz;
-}
-
-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)-1)) < 0)
- PtyFD = -1;
- cmdbuf[n] = '\0';
- while (i < n) {
- Rune rune = 0;
- size_t length = 0;
- while (!utf8decode(&rune, &length, cmdbuf[i++]));
- if (rune == '\033')
- read_escape(cmdbuf, &i, n);
- else
- view_insert(win_view(EDIT), false, rune);
- }
- win_buf(EDIT)->outpoint = win_view(EDIT)->selection.end;
-}
if (tag) {
while (*cmd && !isspace(*cmd++));
tag_exec(tag, (*cmd ? stringdup(cmd) : NULL));
- } else if (pty_active() && !rissigil(*cmd)) {
- pty_send(cmd, NULL);
} else {
cmd_exec(cmd);
}
view_jumpto(win_view(FOCUSED), false, Marks[mark]);
}
-static void tag_send(char* cmd) {
- pty_send(cmd, NULL);
-}
-
/* Main Routine
******************************************************************************/
static Tag Builtins[] = {
{ .tag = "Reload", .action.noarg = reload },
{ .tag = "Save", .action.noarg = save },
{ .tag = "SaveAs", .action.arg = saveas },
- { .tag = "Send", .action.arg = tag_send },
{ .tag = "Tabs", .action.noarg = tabs },
{ .tag = "Undo", .action.noarg = tag_undo },
{ .tag = "LineNums", .action.noarg = tag_lnnum },
{ 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 }
};
}
static void oninput(Rune rune) {
- if (win_getregion() == EDIT && pty_active())
- pty_send_rune(rune);
- else
- view_insert(win_view(FOCUSED), true, rune);
+ view_insert(win_view(FOCUSED), true, rune);
}
void edit_relative(char* path) {
free(origdir);
}
-void edit_command(char** cmd) {
- char* shellcmd[] = { ShellCmd[0], NULL };
- win_buf(EDIT)->crlf = 1;
- config_set_int(TabWidth, 8);
- pty_spawn(*cmd ? cmd : shellcmd);
-}
-
#ifndef TEST
int main(int argc, char** argv) {
/* setup the shell */
}
/* if we still have args left we're going to open it in this instance */
- if (*argv) {
- /* if it's a command we treat that specially */
- if (!strcmp(*argv, "--"))
- edit_command(argv+1);
- else
- edit_relative(*argv);
- }
+ if (*argv) edit_relative(*argv);
/* now create the window and start the event loop */
- if (!pty_active()) {
- win_settext(TAGS, config_get_str(EditTagString));
- win_setruler(config_get_int(RulerColumn));
- win_setlinenums(config_get_bool(LineNumbers));
- } else {
- win_settext(TAGS, config_get_str(CmdTagString));
- win_setruler(0);
- win_setlinenums(false);
- }
+ win_settext(TAGS, config_get_str(EditTagString));
+ win_setruler(config_get_int(RulerColumn));
+ win_setlinenums(config_get_bool(LineNumbers));
win_setkeys(Bindings, oninput);
win_loop();
return 0;