diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2017-04-14 11:15:17 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2017-04-14 11:15:17 +0200 |
| commit | 63ebc9dad10e1f31058b7b4148c00198b67928de (patch) | |
| tree | be6b05a2db8461cf7acc1aabbbc926b7bcc07398 | |
| parent | c25e0c110430bd16056c6fe12e9e6676ebf1e5f5 (diff) | |
| download | vis-63ebc9dad10e1f31058b7b4148c00198b67928de.tar.gz vis-63ebc9dad10e1f31058b7b4148c00198b67928de.tar.xz | |
vis: make certain operations interruptible with <C-c>
As currently implemented this will only work for operations which are
individually fast, but repeated many times (e.g. `1000000itext<Escape>`).
| -rw-r--r-- | main.c | 1 | ||||
| -rw-r--r-- | sam.c | 8 | ||||
| -rw-r--r-- | ui-terminal-curses.c | 2 | ||||
| -rw-r--r-- | vis-core.h | 2 | ||||
| -rw-r--r-- | vis-motions.c | 2 | ||||
| -rw-r--r-- | vis.c | 14 |
6 files changed, 19 insertions, 10 deletions
@@ -2083,7 +2083,6 @@ int main(int argc, char *argv[]) { sigset_t blockset; sigemptyset(&blockset); sigaddset(&blockset, SIGBUS); - sigaddset(&blockset, SIGINT); sigaddset(&blockset, SIGCONT); sigaddset(&blockset, SIGWINCH); sigaddset(&blockset, SIGTERM); @@ -1657,7 +1657,7 @@ static bool cmd_filter(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur int status = vis_pipe(vis, win->file, range, &argv[1], &bufout, read_buffer, &buferr, read_buffer); - if (vis->cancel_filter) { + if (vis->interrupted) { vis_info_show(vis, "Command cancelled"); } else if (status == 0) { size_t len = buffer_length(&bufout); @@ -1671,7 +1671,7 @@ static bool cmd_filter(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur buffer_release(&bufout); buffer_release(&buferr); - return !vis->cancel_filter && status == 0; + return !vis->interrupted && status == 0; } static bool cmd_launch(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) { @@ -1700,14 +1700,14 @@ static bool cmd_pipeout(Vis *vis, Win *win, Command *cmd, const char *argv[], Cu if (status == 0 && cur) view_cursors_to(cur, range->start); - if (vis->cancel_filter) + if (vis->interrupted) vis_info_show(vis, "Command cancelled"); else if (status != 0) vis_info_show(vis, "Command failed %s", buffer_content0(&buferr)); buffer_release(&buferr); - return !vis->cancel_filter && status == 0; + return !vis->interrupted && status == 0; } static bool cmd_cd(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) { diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c index 0d39306..744cbb4 100644 --- a/ui-terminal-curses.c +++ b/ui-terminal-curses.c @@ -265,7 +265,7 @@ static bool ui_curses_init(UiTerm *tui, char *term) { } start_color(); use_default_colors(); - raw(); + cbreak(); noecho(); nonl(); keypad(stdscr, TRUE); @@ -192,7 +192,7 @@ struct Vis { int nesting_level; /* parsing state to hold keep track of { } nesting level */ volatile bool running; /* exit main loop once this becomes false */ int exit_status; /* exit status when terminating main loop */ - volatile sig_atomic_t cancel_filter; /* abort external command/filter (SIGINT occured) */ + volatile sig_atomic_t interrupted; /* abort command (SIGINT occured) */ volatile sig_atomic_t sigbus; /* one of the memory mapped region became unavailable (SIGBUS) */ volatile sig_atomic_t need_resize; /* need to resize UI (SIGWINCH occured) */ volatile sig_atomic_t resume; /* need to resume UI (SIGCONT occured) */ diff --git a/vis-motions.c b/vis-motions.c index 0166117..c3afe16 100644 --- a/vis-motions.c +++ b/vis-motions.c @@ -85,6 +85,8 @@ static size_t common_word_next(Vis *vis, Text *txt, size_t pos, enum VisMotion e } while (count--) { + if (vis->interrupted) + return pos; size_t newpos = motion->txt(txt, pos); if (newpos == pos) break; @@ -835,6 +835,8 @@ void vis_do(Vis *vis) { vis->mode == &vis_modes[VIS_MODE_VISUAL_LINE]); for (Cursor *cursor = view_cursors(view), *next; cursor; cursor = next) { + if (vis->interrupted) + break; next = view_cursors_next(cursor); @@ -1283,7 +1285,7 @@ bool vis_signal_handler(Vis *vis, int signum, const siginfo_t *siginfo, const vo siglongjmp(vis->sigbus_jmpbuf, 1); return true; case SIGINT: - vis->cancel_filter = true; + vis->interrupted = true; return true; case SIGCONT: vis->resume = true; @@ -1342,6 +1344,10 @@ int vis_run(Vis *vis, int argc, char *argv[]) { if (vis->terminate) vis_die(vis, "Killed by SIGTERM\n"); + if (vis->interrupted) { + vis->interrupted = false; + vis_keys_feed(vis, "<C-c>"); + } if (vis->resume) { vis->ui->resume(vis->ui); @@ -1501,6 +1507,8 @@ void vis_repeat(Vis *vis) { if (vis->action_prev.op == &vis_operators[VIS_OP_MODESWITCH]) vis->action_prev.count = 1; for (int i = 0; i < count; i++) { + if (vis->interrupted) + break; mode_set(vis, mode); macro_replay(vis, macro); } @@ -1752,7 +1760,7 @@ int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[], exit(EXIT_FAILURE); } - vis->cancel_filter = false; + vis->interrupted = false; close(pin[0]); close(pout[1]); @@ -1765,7 +1773,7 @@ int vis_pipe(Vis *vis, File *file, Filerange *range, const char *argv[], fd_set rfds, wfds; do { - if (vis->cancel_filter) { + if (vis->interrupted) { kill(-pid, SIGTERM); break; } |
