aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c64
-rw-r--r--ui-curses.c56
-rw-r--r--ui.h1
-rw-r--r--vis-core.h1
-rw-r--r--vis.c67
5 files changed, 98 insertions, 91 deletions
diff --git a/main.c b/main.c
index 3b3689b..d1c346e 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,9 @@
#include <wchar.h>
#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include "ui-curses.h"
#include "vis.h"
@@ -2242,6 +2245,67 @@ int main(int argc, char *argv[]) {
sigprocmask(SIG_BLOCK, &blockset, NULL);
signal(SIGPIPE, SIG_IGN);
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] != '-') {
+ continue;
+ } else if (strcmp(argv[i], "-") == 0) {
+ continue;
+ } else if (strcmp(argv[i], "--") == 0) {
+ break;
+ } else if (strcmp(argv[i], "-v") == 0) {
+ puts("vis " VERSION);
+ return 0;
+ } else {
+ fprintf(stderr, "Unknown command option: %s\n", argv[i]);
+ return 1;
+ }
+ }
+
+ char *cmd = NULL;
+ bool end_of_options = false, win_created = false;
+
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] == '-' && !end_of_options) {
+ if (strcmp(argv[i], "-") == 0) {
+ if (!vis_window_new_fd(vis, STDOUT_FILENO))
+ vis_die(vis, "Can not create empty buffer\n");
+ ssize_t len = 0;
+ char buf[PIPE_BUF];
+ Text *txt = vis_text(vis);
+ while ((len = read(STDIN_FILENO, buf, sizeof buf)) > 0)
+ text_insert(txt, text_size(txt), buf, len);
+ if (len == -1)
+ vis_die(vis, "Can not read from stdin\n");
+ text_snapshot(txt);
+ int fd = open("/dev/tty", O_RDONLY);
+ if (fd == -1)
+ vis_die(vis, "Can not reopen stdin\n");
+ dup2(fd, STDIN_FILENO);
+ close(fd);
+ } else if (strcmp(argv[i], "--") == 0) {
+ end_of_options = true;
+ }
+ end_of_options = !strcmp(argv[i], "--");
+ } else if (argv[i][0] == '+' && !end_of_options) {
+ cmd = argv[i] + (argv[i][1] == '/' || argv[i][1] == '?');
+ } else if (!vis_window_new(vis, argv[i])) {
+ vis_die(vis, "Can not load `%s': %s\n", argv[i], strerror(errno));
+ } else {
+ win_created = true;
+ if (cmd) {
+ vis_prompt_cmd(vis, cmd);
+ cmd = NULL;
+ }
+ }
+ }
+
+ if (!vis_window(vis) && !win_created) {
+ if (!vis_window_new(vis, NULL))
+ vis_die(vis, "Can not create empty buffer\n");
+ if (cmd)
+ vis_prompt_cmd(vis, cmd);
+ }
+
int status = vis_run(vis, argc, argv);
vis_free(vis);
return status;
diff --git a/ui-curses.c b/ui-curses.c
index b8f1e05..b1972da 100644
--- a/ui-curses.c
+++ b/ui-curses.c
@@ -1048,16 +1048,6 @@ static void ui_info_hide(Ui *ui) {
}
}
-static bool ui_init(Ui *ui, Vis *vis) {
- UiCurses *uic = (UiCurses*)ui;
- uic->vis = vis;
- return true;
-}
-
-static bool ui_start(Ui *ui) {
- return true;
-}
-
static TermKey *ui_termkey_new(int fd) {
TermKey *termkey = termkey_new(fd, TERMKEY_FLAG_UTF8);
if (termkey)
@@ -1127,12 +1117,9 @@ static int ui_colors(Ui *ui) {
return COLORS;
}
-Ui *ui_curses_new(void) {
-
- UiCurses *uic = calloc(1, sizeof(UiCurses));
- Ui *ui = (Ui*)uic;
- if (!uic)
- return NULL;
+static bool ui_init(Ui *ui, Vis *vis) {
+ UiCurses *uic = (UiCurses*)ui;
+ uic->vis = vis;
tcgetattr(STDERR_FILENO, &uic->tio);
if (!(uic->termkey = ui_termkey_new(STDIN_FILENO)))
goto err;
@@ -1155,13 +1142,30 @@ Ui *ui_curses_new(void) {
keypad(stdscr, TRUE);
meta(stdscr, TRUE);
curs_set(0);
- /* needed because we use getch() which implicitly calls refresh() which
- would clear the screen (overwrite it with an empty / unused stdscr */
- refresh();
+
+ struct sigaction sa;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = sigwinch_handler;
+ sigaction(SIGWINCH, &sa, NULL);
+ sigaction(SIGCONT, &sa, NULL);
+
+ ui_resize(ui);
+
+ return true;
+err:
+ ui_die_msg(ui, "Failed to start curses interface\n");
+ return false;
+}
+
+Ui *ui_curses_new(void) {
+
+ Ui *ui = calloc(1, sizeof(UiCurses));
+ if (!ui)
+ return NULL;
*ui = (Ui) {
.init = ui_init,
- .start = ui_start,
.free = ui_curses_free,
.termkey_get = ui_termkey_get,
.suspend = ui_suspend,
@@ -1183,19 +1187,7 @@ Ui *ui_curses_new(void) {
.colors = ui_colors,
};
- struct sigaction sa;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = sigwinch_handler;
- sigaction(SIGWINCH, &sa, NULL);
- sigaction(SIGCONT, &sa, NULL);
-
- ui_resize(ui);
-
return ui;
-err:
- ui_curses_free(ui);
- return NULL;
}
void ui_curses_free(Ui *ui) {
diff --git a/ui.h b/ui.h
index 26d9050..dd663b8 100644
--- a/ui.h
+++ b/ui.h
@@ -51,7 +51,6 @@ enum UiStyle {
struct Ui {
bool (*init)(Ui*, Vis*);
- bool (*start)(Ui*);
void (*free)(Ui*);
void (*resize)(Ui*);
UiWin* (*window_new)(Ui*, View*, File*, enum UiOption);
diff --git a/vis-core.h b/vis-core.h
index 5dc2a64..6d5d022 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -172,6 +172,7 @@ struct Vis {
Action action_prev; /* last operator action used by the repeat (dot) command */
Mode *mode; /* currently active mode, used to search for keybindings */
Mode *mode_prev; /* previsouly active user mode */
+ bool initialized; /* whether UI and Lua integration has been initialized */
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) */
diff --git a/vis.c b/vis.c
index d74ecf3..e3ad87e 100644
--- a/vis.c
+++ b/vis.c
@@ -37,6 +37,13 @@ bool vis_event_emit(Vis *vis, enum VisEvents id, ...) {
if (!vis->event)
return true;
+ if (!vis->initialized) {
+ vis->initialized = true;
+ vis->ui->init(vis->ui, vis);
+ if (vis->event && vis->event->vis_init)
+ vis->event->vis_init(vis);
+ }
+
va_list ap;
va_start(ap, id);
bool ret = true;
@@ -493,7 +500,6 @@ Vis *vis_new(Ui *ui, VisEvent *event) {
if (!vis)
return NULL;
vis->ui = ui;
- vis->ui->init(vis->ui, vis);
vis->tabwidth = 8;
vis->expandtab = false;
vis->registers[VIS_REG_BLACKHOLE].type = REGISTER_BLACKHOLE;
@@ -525,9 +531,6 @@ Vis *vis_new(Ui *ui, VisEvent *event) {
goto err;
vis->mode_prev = vis->mode = &vis_modes[VIS_MODE_NORMAL];
vis->event = event;
- if (event && event->vis_init)
- event->vis_init(vis);
- vis->ui->start(vis->ui);
return vis;
err:
vis_free(vis);
@@ -982,62 +985,10 @@ bool vis_signal_handler(Vis *vis, int signum, const siginfo_t *siginfo, const vo
return false;
}
-static void vis_args(Vis *vis, int argc, char *argv[]) {
- char *cmd = NULL;
- bool end_of_options = false;
- for (int i = 1; i < argc; i++) {
- if (argv[i][0] == '-' && !end_of_options) {
- switch (argv[i][1]) {
- case '-':
- end_of_options = true;
- break;
- case 'v':
- vis_die(vis, "vis %s\n", VERSION);
- break;
- case '\0':
- break;
- default:
- vis_die(vis, "Unknown command option: %s\n", argv[i]);
- break;
- }
- } else if (argv[i][0] == '+') {
- cmd = argv[i] + (argv[i][1] == '/' || argv[i][1] == '?');
- } else if (!vis_window_new(vis, argv[i])) {
- vis_die(vis, "Can not load `%s': %s\n", argv[i], strerror(errno));
- } else if (cmd) {
- vis_prompt_cmd(vis, cmd);
- cmd = NULL;
- }
- }
-
- if (!vis->windows && vis->running) {
- if (!strcmp(argv[argc-1], "-")) {
- if (!vis_window_new_fd(vis, STDOUT_FILENO))
- vis_die(vis, "Can not create empty buffer\n");
- ssize_t len = 0;
- char buf[PIPE_BUF];
- Text *txt = vis_text(vis);
- while ((len = read(STDIN_FILENO, buf, sizeof buf)) > 0)
- text_insert(txt, text_size(txt), buf, len);
- if (len == -1)
- vis_die(vis, "Can not read from stdin\n");
- text_snapshot(txt);
- int fd = open("/dev/tty", O_RDONLY);
- if (fd == -1)
- vis_die(vis, "Can not reopen stdin\n");
- dup2(fd, STDIN_FILENO);
- close(fd);
- } else if (!vis_window_new(vis, NULL)) {
- vis_die(vis, "Can not create empty buffer\n");
- }
- if (cmd)
- vis_prompt_cmd(vis, cmd);
- }
-}
-
int vis_run(Vis *vis, int argc, char *argv[]) {
+ if (!vis->windows)
+ return EXIT_SUCCESS;
vis->running = true;
- vis_args(vis, argc, argv);
vis_event_emit(vis, VIS_EVENT_START);