Beispiel #1
0
static const char *cursors_select_next(Vis *vis, const char *keys, const Arg *arg) {
	Text *txt = vis_text(vis);
	View *view = vis_view(vis);
	Cursor *cursor = view_cursor(view);
	Filerange sel = view_cursors_selection_get(cursor);
	if (!text_range_valid(&sel))
		return keys;

	size_t len = text_range_size(&sel);
	char *buf = malloc(len+1);
	if (!buf)
		return keys;
	len = text_bytes_get(txt, sel.start, len, buf);
	buf[len] = '\0';
	Filerange word = text_object_word_find_next(txt, sel.end, buf);
	free(buf);

	if (text_range_valid(&word)) {
		cursor = view_cursors_new(view);
		if (!cursor)
			return keys;
		view_cursors_selection_set(cursor, &word);
		view_cursors_to(cursor, text_char_prev(txt, word.end));
	}
	return keys;
}
Beispiel #2
0
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);
	return ret;
}
Beispiel #3
0
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'))
		return sam_execute(vis, win, cmd->cmd, cur, range);
	view_cursors_dispose(cur);
	return true;
}
Beispiel #4
0
static size_t op_put(Vis *vis, Text *txt, OperatorContext *c) {
	size_t pos = c->pos;
	bool sel = text_range_size(&c->range) > 0;
	bool sel_linewise = sel && text_range_is_linewise(txt, &c->range);
	if (sel) {
		text_delete_range(txt, &c->range);
		pos = c->pos = c->range.start;
	}
	switch (c->arg->i) {
	case VIS_OP_PUT_AFTER:
	case VIS_OP_PUT_AFTER_END:
		if (c->reg->linewise && !sel_linewise)
			pos = text_line_next(txt, pos);
		else if (!sel)
			pos = text_char_next(txt, pos);
		break;
	case VIS_OP_PUT_BEFORE:
	case VIS_OP_PUT_BEFORE_END:
		if (c->reg->linewise)
			pos = text_line_begin(txt, pos);
		break;
	}

	size_t len;
	const char *data = register_get(vis, c->reg, &len);

	for (int i = 0; i < c->count; i++) {
		text_insert(txt, pos, data, len);
		pos += len;
	}

	if (c->reg->linewise) {
		switch (c->arg->i) {
		case VIS_OP_PUT_BEFORE_END:
		case VIS_OP_PUT_AFTER_END:
			pos = text_line_start(txt, pos);
			break;
		case VIS_OP_PUT_AFTER:
			pos = text_line_start(txt, text_line_next(txt, c->pos));
			break;
		case VIS_OP_PUT_BEFORE:
			pos = text_line_start(txt, c->pos);
			break;
		}
	} else {
		switch (c->arg->i) {
		case VIS_OP_PUT_AFTER:
		case VIS_OP_PUT_BEFORE:
			pos = text_char_prev(txt, pos);
			break;
		}
	}

	return pos;
}
Beispiel #5
0
static const char *prompt_enter(Vis *vis, const char *keys, const Arg *arg) {
	Win *prompt = vis->win;
	View *view = prompt->view;
	Text *txt = prompt->file->text;
	Win *win = prompt->parent;
	char *cmd = NULL;

	Filerange range = view_selection_get(view);
	if (!text_range_valid(&range))
		range = text_object_line(txt, view_cursor_get(view));
	if (text_range_valid(&range))
		cmd = text_bytes_alloc0(txt, range.start, text_range_size(&range));

	if (!win || !cmd) {
		vis_info_show(vis, "Prompt window invalid\n");
		prompt_restore(prompt);
		prompt_hide(prompt);
		free(cmd);
		return keys;
	}

	size_t len = strlen(cmd);
	if (len > 0 && cmd[len-1] == '\n')
		cmd[len-1] = '\0';

	bool lastline = (range.end == text_size(txt));

	prompt_restore(prompt);
	if (vis_prompt_cmd(vis, cmd)) {
		prompt_hide(prompt);
		if (!lastline) {
			text_delete(txt, range.start, text_range_size(&range));
			text_appendf(txt, "%s\n", cmd);
		}
	} else {
		vis->win = prompt;
		vis->mode = &vis_modes[VIS_MODE_INSERT];
	}
	free(cmd);
	vis_draw(vis);
	return keys;
}
Beispiel #6
0
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)) &&
	      text_insert(txt, range->start, argv[1], len);
	if (ret)
		*range = text_range_new(range->start, range->start + len);
	return ret;
}
Beispiel #7
0
Filerange text_object_word_find_prev(Text *txt, size_t pos, const char *word) {
	size_t len = strlen(word);
	for (;;) {
		size_t match_pos = text_find_prev(txt, pos, word);
		if (match_pos != pos) {
			Filerange match_word = text_object_word(txt, match_pos);
			if (text_range_size(&match_word) == len)
				return match_word;
			pos = match_pos;
		} else {
			return text_range_empty();
		}
	}
}
Beispiel #8
0
static void prompt_hide(Win *win) {
	Text *txt = win->file->text;
	size_t size = text_size(txt);
	/* make sure that file is new line terminated */
	char lastchar;
	if (size > 1 && text_byte_get(txt, size-1, &lastchar) && lastchar != '\n')
		text_insert(txt, size, "\n", 1);
	/* remove empty entries */
	Filerange line = text_object_line(txt, size);
	size_t line_size = text_range_size(&line);
	if (line_size <= 2)
		text_delete(txt, line.start, line_size);
	vis_window_close(win);
}
Beispiel #9
0
Filerange text_object_number(Text *txt, size_t pos) {
    char *buf, *err = NULL;
    Filerange r = text_object_range(txt, pos, is_number);
    if (!text_range_valid(&r))
        return r;
    if (!(buf = text_bytes_alloc0(txt, r.start, text_range_size(&r))))
        return text_range_empty();
    errno = 0;
    strtoll(buf, &err, 0);
    if (errno || err == buf)
        r = text_range_empty();
    else
        r.end = r.start + (err - buf);
    free(buf);
    return r;
}
Beispiel #10
0
static size_t op_case_change(Vis *vis, Text *txt, OperatorContext *c) {
	size_t len = text_range_size(&c->range);
	char *buf = malloc(len);
	if (!buf)
		return c->pos;
	len = text_bytes_get(txt, c->range.start, len, buf);
	size_t rem = len;
	for (char *cur = buf; rem > 0; cur++, rem--) {
		int ch = (unsigned char)*cur;
		if (isascii(ch)) {
			if (c->arg->i == VIS_OP_CASE_SWAP)
				*cur = islower(ch) ? toupper(ch) : tolower(ch);
			else if (c->arg->i == VIS_OP_CASE_UPPER)
				*cur = toupper(ch);
			else
				*cur = tolower(ch);
		}
	}

	text_delete(txt, c->range.start, len);
	text_insert(txt, c->range.start, buf, len);
	free(buf);
	return c->pos;
}