aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2017-04-14 11:15:17 +0200
committerMarc André Tanner <mat@brain-dump.org>2017-04-14 11:15:17 +0200
commit63ebc9dad10e1f31058b7b4148c00198b67928de (patch)
treebe6b05a2db8461cf7acc1aabbbc926b7bcc07398
parentc25e0c110430bd16056c6fe12e9e6676ebf1e5f5 (diff)
downloadvis-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.c1
-rw-r--r--sam.c8
-rw-r--r--ui-terminal-curses.c2
-rw-r--r--vis-core.h2
-rw-r--r--vis-motions.c2
-rw-r--r--vis.c14
6 files changed, 19 insertions, 10 deletions
diff --git a/main.c b/main.c
index fdd7841..96034b1 100644
--- a/main.c
+++ b/main.c
@@ -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);
diff --git a/sam.c b/sam.c
index f548744..c25bf4f 100644
--- a/sam.c
+++ b/sam.c
@@ -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);
diff --git a/vis-core.h b/vis-core.h
index fc9853c..654085d 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -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;
diff --git a/vis.c b/vis.c
index 82b47b9..8739cce 100644
--- a/vis.c
+++ b/vis.c
@@ -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;
}