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)