From: Pierre Habouzit Date: Sat, 10 Nov 2007 17:13:37 +0000 (+0100) Subject: Embed vim into madmutt. Yeah _IN_ madmutt. X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=952faeb1ad4196bcec00923254f41eb8a9fb5eae Embed vim into madmutt. Yeah _IN_ madmutt. Signed-off-by: Pierre Habouzit --- diff --git a/globals.h b/globals.h index f8c7a2f..3a96cae 100644 --- a/globals.h +++ b/globals.h @@ -131,6 +131,7 @@ WHERE short ImapBuffyTimeout; WHERE sig_atomic_t SigAlrm INITVAL (0); WHERE sig_atomic_t SigInt INITVAL (0); WHERE sig_atomic_t SigWinch INITVAL (0); +WHERE sig_atomic_t SigChild INITVAL (0); WHERE int CurrentMenu; diff --git a/lib-sys/mutt_signal.c b/lib-sys/mutt_signal.c index 0c53567..2728656 100644 --- a/lib-sys/mutt_signal.c +++ b/lib-sys/mutt_signal.c @@ -28,11 +28,6 @@ static void exit_handler (int sig) exit(0); } -static void chld_handler(int sig __attribute__((unused))) -{ - /* empty */ -} - static void sighandler (int sig) { int save_errno = errno; @@ -55,6 +50,10 @@ static void sighandler (int sig) SigWinch = 1; break; + case SIGCHLD: + SigChild = 1; + break; + case SIGINT: SigInt = 1; break; @@ -100,7 +99,6 @@ void mutt_signal_initialize (void) /* POSIX doesn't allow us to ignore SIGCHLD, * so we just install a dummy handler for it */ - act.sa_handler = chld_handler; /* don't need to block any other signals here */ sigemptyset (&act.sa_mask); /* we don't want to mess with stopped children */ diff --git a/lib-ui/curs_lib.c b/lib-ui/curs_lib.c index 5ac5dcb..619cb31 100644 --- a/lib-ui/curs_lib.c +++ b/lib-ui/curs_lib.c @@ -117,16 +117,80 @@ void mutt_clear_error (void) CLEARLINE(stdscr, LINES - 1); } +static struct timeval const slice = { 0, 1000 * 1000 / 100 }; +static struct timeval timeval_add(struct timeval a, struct timeval b) +{ + int usec = a.tv_usec + b.tv_usec; + a.tv_sec += b.tv_sec; + while (usec > 1000 * 1000) { + a.tv_sec += 1; + usec -= 1000 * 1000; + } + a.tv_usec = usec; + return a; +} + +static int is_expired(struct timeval now, struct timeval expiry) +{ + return now.tv_sec > expiry.tv_sec + || (now.tv_sec == expiry.tv_sec && now.tv_usec > expiry.tv_usec); +} + void mutt_edit_file(const char *data) { - char cmd[LONG_STRING]; - - mutt_endwin (NULL); - m_quotefile_fmt(cmd, sizeof (cmd), mod_core.editor, data); - if (mutt_system (cmd) == -1) - mutt_error (_("Error running \"%s\"!"), cmd); - keypad (stdscr, TRUE); - clearok (stdscr, TRUE); + char cmd[STRING]; + const char *args[] = { "/bin/sh", "-c", cmd, NULL }; + int dirty = 0, ch, res, mh, mw, pty, pid; + struct timeval next; + madtty_t *rt; + + m_quotefile_fmt(cmd, sizeof(cmd), mod_core.editor, data); + getmaxyx(main_w, mh, mw); + SigChild = 0; + + rt = madtty_create(mh - 2, mw); + pid = madtty_forkpty(rt, args[0], args, &pty); + if (pid < 0) { + madtty_destroy(rt); + mutt_error(_("unable to start editor")); + return; + } + + nodelay(stdscr, true); + gettimeofday(&next, NULL); + while (!SigChild) { + struct timeval tv = { 0, 1000 * 1000 / 100 }; + fd_set rfds; + + FD_ZERO(&rfds); + FD_SET(0, &rfds); + FD_SET(pty, &rfds); + + if (select(pty + 1, &rfds, NULL, NULL, &tv) < 0) + break; + + if (FD_ISSET(pty, &rfds)) { + madtty_process(rt); + dirty = 1; + } + + while ((ch = getch()) != ERR) { + madtty_keypress(rt, ch); /* pass the keypress for handling */ + dirty = 1; + } + + gettimeofday(&tv, NULL); + if (dirty && is_expired(tv, next)) { + madtty_draw(rt, main_w, 1, 0); + wrefresh(main_w); + dirty = 0; + next = timeval_add(tv, slice); + } + } + while (waitpid(pid, &res, 0) < 0 && errno == EINTR); + nodelay(stdscr, false); + close(pty); + madtty_destroy(rt); } int mutt_yesorno (const char *msg, int def)