aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sam.c32
-rw-r--r--vis-cmds.c59
-rw-r--r--vis.c4
3 files changed, 72 insertions, 23 deletions
diff --git a/sam.c b/sam.c
index 7227438..1f452d6 100644
--- a/sam.c
+++ b/sam.c
@@ -725,12 +725,16 @@ static Filerange address_evaluate(Address *addr, File *file, Filerange *range, i
static bool sam_execute(Vis *vis, Win *win, Command *cmd, Cursor *cur, Filerange *range) {
bool ret = true;
- if (cmd->address)
+ if (cmd->address && win)
*range = address_evaluate(cmd->address, win->file, range, 0);
switch (cmd->argv[0][0]) {
case '{':
{
+ if (!win) {
+ ret = false;
+ break;
+ }
Text *txt = win->file->text;
Mark start, end;
Filerange group = *range;
@@ -790,6 +794,8 @@ enum SamError sam_cmd(Vis *vis, const char *s) {
}
static bool cmd_insert(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
size_t len = strlen(argv[1]);
bool ret = text_insert(win->file->text, range->start, argv[1], len);
if (ret)
@@ -798,6 +804,8 @@ static bool cmd_insert(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
}
static bool cmd_append(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
size_t len = strlen(argv[1]);
bool ret = text_insert(win->file->text, range->end, argv[1], len);
if (ret)
@@ -806,6 +814,8 @@ static bool cmd_append(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
}
static bool cmd_change(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
Text *txt = win->file->text;
size_t len = strlen(argv[1]);
bool ret = text_delete(txt, range->start, text_range_size(range)) &&
@@ -816,6 +826,8 @@ static bool cmd_change(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
}
static bool cmd_delete(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
bool ret = text_delete(win->file->text, range->start, text_range_size(range));
if (ret)
*range = text_range_new(range->start, range->start);
@@ -823,6 +835,8 @@ static bool cmd_delete(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
}
static bool cmd_guard(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
bool match = !text_search_range_forward(win->file->text, range->start,
text_range_size(range), cmd->regex, 0, NULL, 0);
if (match ^ (argv[0][0] == 'v'))
@@ -832,6 +846,8 @@ static bool cmd_guard(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs
}
static bool cmd_extract(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
bool ret = true;
Text *txt = win->file->text;
@@ -911,6 +927,9 @@ static bool cmd_extract(Vis *vis, Win *win, Command *cmd, const char *argv[], Cu
}
static bool cmd_select(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ Filerange sel = text_range_empty();
+ if (!win)
+ return sam_execute(vis, NULL, cmd->cmd, NULL, &sel);
bool ret = true;
View *view = win->view;
Text *txt = win->file->text;
@@ -919,7 +938,6 @@ static bool cmd_select(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
for (Cursor *c = view_cursors(view), *next; c && ret; c = next) {
next = view_cursors_next(c);
- Filerange sel;
size_t pos = view_cursors_pos(c);
if (vis->mode->visual) {
sel = view_cursors_selection_get(c);
@@ -963,7 +981,7 @@ static bool cmd_select(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
}
static bool cmd_print(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
- if (!text_range_valid(range))
+ if (!win || !text_range_valid(range))
return false;
View *view = win->view;
Text *txt = win->file->text;
@@ -1007,6 +1025,8 @@ static bool cmd_substitute(Vis *vis, Win *win, Command *cmd, const char *argv[],
}
static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *r) {
+ if (!win)
+ return false;
File *file = win->file;
Text *text = file->text;
bool noname = !argv[1];
@@ -1117,6 +1137,8 @@ static ssize_t read_buffer(void *context, char *data, size_t len) {
}
static bool cmd_filter(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
Text *txt = win->file->text;
/* The general idea is the following:
@@ -1174,6 +1196,8 @@ static bool cmd_launch(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
}
static bool cmd_pipein(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
Filerange filter_range = text_range_new(range->end, range->end);
bool ret = cmd_filter(vis, win, cmd, (const char*[]){ argv[0], argv[1], NULL }, cur, &filter_range);
if (ret) {
@@ -1186,6 +1210,8 @@ static bool cmd_pipein(Vis *vis, Win *win, Command *cmd, const char *argv[], Cur
}
static bool cmd_pipeout(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
Buffer buferr;
buffer_init(&buferr);
diff --git a/vis-cmds.c b/vis-cmds.c
index c43f9cd..e52072d 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -91,7 +91,10 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
OPTION_TYPE_NUMBER,
OPTION_TYPE_UNSIGNED,
} type;
- bool optional;
+ enum {
+ OPTION_FLAG_OPTIONAL = 1 << 0,
+ OPTION_FLAG_WINDOW = 1 << 1,
+ } flags;
int index;
} OptionDef;
@@ -99,29 +102,29 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
OPTION_AUTOINDENT,
OPTION_EXPANDTAB,
OPTION_TABWIDTH,
+ OPTION_THEME,
OPTION_SYNTAX,
OPTION_SHOW,
OPTION_NUMBER,
OPTION_NUMBER_RELATIVE,
OPTION_CURSOR_LINE,
- OPTION_THEME,
OPTION_COLOR_COLUMN,
OPTION_HORIZON,
};
/* definitions have to be in the same order as the enum above */
static OptionDef options[] = {
- [OPTION_AUTOINDENT] = { { "autoindent", "ai" }, OPTION_TYPE_BOOL },
- [OPTION_EXPANDTAB] = { { "expandtab", "et" }, OPTION_TYPE_BOOL },
- [OPTION_TABWIDTH] = { { "tabwidth", "tw" }, OPTION_TYPE_NUMBER },
- [OPTION_SYNTAX] = { { "syntax" }, OPTION_TYPE_STRING, true },
- [OPTION_SHOW] = { { "show" }, OPTION_TYPE_STRING },
- [OPTION_NUMBER] = { { "numbers", "nu" }, OPTION_TYPE_BOOL },
- [OPTION_NUMBER_RELATIVE] = { { "relativenumbers", "rnu" }, OPTION_TYPE_BOOL },
- [OPTION_CURSOR_LINE] = { { "cursorline", "cul" }, OPTION_TYPE_BOOL },
- [OPTION_THEME] = { { "theme" }, OPTION_TYPE_STRING },
- [OPTION_COLOR_COLUMN] = { { "colorcolumn", "cc" }, OPTION_TYPE_NUMBER },
- [OPTION_HORIZON] = { { "horizon" }, OPTION_TYPE_UNSIGNED },
+ [OPTION_AUTOINDENT] = { { "autoindent", "ai" }, OPTION_TYPE_BOOL },
+ [OPTION_EXPANDTAB] = { { "expandtab", "et" }, OPTION_TYPE_BOOL },
+ [OPTION_TABWIDTH] = { { "tabwidth", "tw" }, OPTION_TYPE_NUMBER },
+ [OPTION_THEME] = { { "theme" }, OPTION_TYPE_STRING, },
+ [OPTION_SYNTAX] = { { "syntax" }, OPTION_TYPE_STRING, OPTION_FLAG_WINDOW|OPTION_FLAG_OPTIONAL },
+ [OPTION_SHOW] = { { "show" }, OPTION_TYPE_STRING, OPTION_FLAG_WINDOW },
+ [OPTION_NUMBER] = { { "numbers", "nu" }, OPTION_TYPE_BOOL, OPTION_FLAG_WINDOW },
+ [OPTION_NUMBER_RELATIVE] = { { "relativenumbers", "rnu" }, OPTION_TYPE_BOOL, OPTION_FLAG_WINDOW },
+ [OPTION_CURSOR_LINE] = { { "cursorline", "cul" }, OPTION_TYPE_BOOL, OPTION_FLAG_WINDOW },
+ [OPTION_COLOR_COLUMN] = { { "colorcolumn", "cc" }, OPTION_TYPE_NUMBER, OPTION_FLAG_WINDOW },
+ [OPTION_HORIZON] = { { "horizon" }, OPTION_TYPE_UNSIGNED, OPTION_FLAG_WINDOW },
};
if (!vis->options) {
@@ -141,11 +144,6 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
return false;
}
- if (!win) {
- vis_info_show(vis, "Need active window for :set command");
- return false;
- }
-
Arg arg;
bool invert = false;
OptionDef *opt = NULL;
@@ -165,9 +163,14 @@ static bool cmd_set(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
return false;
}
+ if (!win && (opt->flags & OPTION_FLAG_WINDOW)) {
+ vis_info_show(vis, "Need active window for :set command");
+ return false;
+ }
+
switch (opt->type) {
case OPTION_TYPE_STRING:
- if (!opt->optional && !argv[2]) {
+ if (!(opt->flags & OPTION_FLAG_OPTIONAL) && !argv[2]) {
vis_info_show(vis, "Expecting string option value");
return false;
}
@@ -373,6 +376,8 @@ static void info_unsaved_changes(Vis *vis) {
static bool cmd_edit(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
Win *oldwin = win;
+ if (!oldwin)
+ return false;
if (cmd->flags != '!' && !vis_window_closable(oldwin)) {
info_unsaved_changes(vis);
return false;
@@ -410,6 +415,8 @@ static bool cmd_quit(Vis *vis, Win *win, Command *cmd, const char *argv[], Curso
}
static bool cmd_bdelete(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
Text *txt = win->file->text;
if (text_modified(txt) && cmd->flags != '!') {
info_unsaved_changes(vis);
@@ -441,6 +448,8 @@ static bool cmd_qall(Vis *vis, Win *win, Command *cmd, const char *argv[], Curso
}
static bool cmd_split(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
enum UiOption options = view_options_get(win->view);
windows_arrange(vis, UI_LAYOUT_HORIZONTAL);
if (!argv[1])
@@ -452,6 +461,8 @@ static bool cmd_split(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs
}
static bool cmd_vsplit(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
enum UiOption options = view_options_get(win->view);
windows_arrange(vis, UI_LAYOUT_VERTICAL);
if (!argv[1])
@@ -473,6 +484,8 @@ static bool cmd_vnew(Vis *vis, Win *win, Command *cmd, const char *argv[], Curso
}
static bool cmd_wq(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
File *file = win->file;
bool unmodified = !file->is_stdin && !file->name && !text_modified(file->text);
if (unmodified || cmd_write(vis, win, cmd, argv, cur, range))
@@ -481,6 +494,8 @@ static bool cmd_wq(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
}
static bool cmd_earlier_later(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ if (!win)
+ return false;
Text *txt = win->file->text;
char *unit = "";
long count = 1;
@@ -732,6 +747,9 @@ static bool cmd_map(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor
bool local = strstr(argv[0], "-") != NULL;
enum VisMode mode = str2vismode(argv[1]);
+ if (local && !win)
+ return false;
+
if (mode == VIS_MODE_INVALID || !argv[2] || !argv[3]) {
vis_info_show(vis, "usage: map mode lhs rhs\n");
return false;
@@ -779,6 +797,9 @@ static bool cmd_unmap(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs
enum VisMode mode = str2vismode(argv[1]);
const char *lhs = argv[2];
+ if (local && !win)
+ return false;
+
if (mode == VIS_MODE_INVALID || !lhs) {
vis_info_show(vis, "usage: unmap mode lhs\n");
return false;
diff --git a/vis.c b/vis.c
index b22ad41..1397263 100644
--- a/vis.c
+++ b/vis.c
@@ -286,7 +286,7 @@ bool vis_window_new(Vis *vis, const char *filename) {
}
bool vis_window_closable(Win *win) {
- if (!text_modified(win->file->text))
+ if (!win || !text_modified(win->file->text))
return true;
return win->file->refcount > 1;
}
@@ -321,6 +321,8 @@ void vis_window_swap(Win *a, Win *b) {
}
void vis_window_close(Win *win) {
+ if (!win)
+ return;
Vis *vis = win->vis;
if (!win->file->internal && vis->event && vis->event->win_close)
vis->event->win_close(vis, win);