예제 #1
0
static size_t op_join(Vis *vis, Text *txt, OperatorContext *c) {
	size_t pos = text_line_begin(txt, c->range.end), prev_pos;
	Mark mark = NULL;

	/* if operator and range are both linewise, skip last line break */
	if (c->linewise && text_range_is_linewise(txt, &c->range)) {
		size_t line_prev = text_line_prev(txt, pos);
		size_t line_prev_prev = text_line_prev(txt, line_prev);
		if (line_prev_prev >= c->range.start)
			pos = line_prev;
	}

	size_t len = c->arg->s ? strlen(c->arg->s) : 0;

	do {
		prev_pos = pos;
		size_t end = text_line_start(txt, pos);
		pos = text_line_prev(txt, end);
		if (pos < c->range.start || end <= pos)
			break;
		text_delete(txt, pos, end - pos);
		char prev, next;
		if (text_byte_get(txt, pos-1, &prev) && !isspace((unsigned char)prev) &&
		    text_byte_get(txt, pos, &next) && next != '\r' && next != '\n')
			text_insert(txt, pos, c->arg->s, len);
		if (!mark)
			mark = text_mark_set(txt, pos);
	} while (pos != prev_pos);

	size_t newpos = text_mark_get(txt, mark);
	return newpos != EPOS ? newpos : c->range.start;
}
예제 #2
0
static size_t op_join(Vis *vis, Text *txt, OperatorContext *c) {
	size_t pos = text_line_begin(txt, c->range.end), prev_pos;
	Mark mark = NULL;

	/* if operator and range are both linewise, skip last line break */
	if (c->linewise && text_range_is_linewise(txt, &c->range)) {
		size_t line_prev = text_line_prev(txt, pos);
		size_t line_prev_prev = text_line_prev(txt, line_prev);
		if (line_prev_prev >= c->range.start)
			pos = line_prev;
	}

	do {
		prev_pos = pos;
		size_t end = text_line_start(txt, pos);
		pos = text_char_next(txt, text_line_finish(txt, text_line_prev(txt, end)));
		if (pos >= c->range.start && end > pos) {
			text_delete(txt, pos, end - pos);
			text_insert(txt, pos, " ", 1);
			if (!mark)
				mark = text_mark_set(txt, pos);
		} else {
			break;
		}
	} while (pos != prev_pos);

	size_t newpos = text_mark_get(txt, mark);
	return newpos != EPOS ? newpos : c->range.start;
}
예제 #3
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;
}