Example #1
0
static size_t op_shift_left(Vis *vis, Text *txt, OperatorContext *c) {
	size_t pos = text_line_begin(txt, c->range.end), prev_pos;
	size_t tabwidth = vis->tabwidth, tablen;
	size_t deleted = 0;

	/* if range ends at the begin of a line, skip line break */
	if (pos == c->range.end)
		pos = text_line_prev(txt, pos);

	do {
		char c;
		size_t len = 0;
		prev_pos = pos = text_line_begin(txt, pos);
		Iterator it = text_iterator_get(txt, pos);
		if (text_iterator_byte_get(&it, &c) && c == '\t') {
			len = 1;
		} else {
			for (len = 0; text_iterator_byte_get(&it, &c) && c == ' '; len++)
				text_iterator_byte_next(&it, NULL);
		}
		tablen = MIN(len, tabwidth);
		text_delete(txt, pos, tablen);
		pos = text_line_prev(txt, pos);
		deleted += tablen;
	}  while (pos >= c->range.start && pos != prev_pos);

	return c->pos - deleted;
}
Example #2
0
static Filerange text_object_bracket(Text *txt, size_t pos, char type) {
	char c, open, close;
	int opened = 1, closed = 1;
	Filerange r = text_range_empty();

	switch (type) {
	case '(':  case ')': open = '(';  close = ')';  break;
	case '{':  case '}': open = '{';  close = '}';  break;
	case '[':  case ']': open = '[';  close = ']';  break;
	case '<':  case '>': open = '<';  close = '>';  break;
	case '"':            open = '"';  close = '"';  break;
	case '`':            open = '`';  close = '`';  break;
	case '\'':           open = '\''; close = '\''; break;
	default: return r;
	}

	Iterator it = text_iterator_get(txt, pos);

	if (open == close && text_iterator_byte_get(&it, &c) && (c == '"' || c == '`' || c == '\'')) {
		size_t match = text_bracket_match(txt, pos);
		r.start = MIN(pos, match) + 1;
		r.end = MAX(pos, match);
		return r;
	}

	while (text_iterator_byte_get(&it, &c)) {
		if (c == open && --opened == 0) {
			r.start = it.pos + 1;
			break;
		} else if (c == close && it.pos != pos) {
			opened++;
		}
		text_iterator_byte_prev(&it, NULL);
	}

	it = text_iterator_get(txt, pos);
	while (text_iterator_byte_get(&it, &c)) {
		if (c == close && --closed == 0) {
			r.end = it.pos;
			break;
		} else if (c == open && it.pos != pos) {
			closed++;
		}
		text_iterator_byte_next(&it, NULL);
	}

	if (!text_range_valid(&r))
		return text_range_empty();
	return r;
}
Example #3
0
size_t text_line_prev(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);
	if (!text_iterator_byte_get(&it, &c))
		return pos;
	if (c == '\n')
		text_iterator_byte_prev(&it, &c);
	if (c == '\r')
		text_iterator_byte_prev(&it, &c);
	while (text_iterator_byte_get(&it, &c) && c != '\n')
		text_iterator_byte_prev(&it, NULL);
	if (text_iterator_byte_prev(&it, &c) && c != '\r')
		text_iterator_byte_next(&it, &c);
	return it.pos;
}
Example #4
0
Filerange text_object_longword_outer(Text *txt, size_t pos) {
	Filerange r;
	char c, prev = '0', next = '0';
	Iterator it = text_iterator_get(txt, pos);
	if (!text_iterator_byte_get(&it, &c))
		return text_range_empty();
	if (text_iterator_byte_prev(&it, &prev))
		text_iterator_byte_next(&it, NULL);
	text_iterator_byte_next(&it, &next);
	if (isspace(c)) {
		/* middle of two words, include leading white space */
		r.start = text_char_next(txt, text_longword_end_prev(txt, pos));
		r.end = text_char_next(txt, text_longword_end_next(txt, pos));
	} else if (isspace(prev) && isspace(next)) {
		/* on a single character */
		r.start = pos;
		r.end = text_longword_start_next(txt, pos);
	} else if (isspace(prev)) {
		/* at start of a word */
		r.start = pos;
		r.end = text_longword_start_next(txt, text_longword_end_next(txt, pos));
	} else if (isspace(next)) {
		/* at end of a word */
		r.start = text_longword_start_prev(txt, pos);
		r.end = text_longword_start_next(txt, pos);
	} else {
		/* in the middle of a word */
		r.start = text_longword_start_prev(txt, pos);
		r.end = text_longword_start_next(txt, text_longword_end_next(txt, pos));
	}
	return r;
}
Example #5
0
size_t text_line_end(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);
	while (text_iterator_byte_get(&it, &c) && c != '\r' && c != '\n')
		text_iterator_byte_next(&it, NULL);
	return it.pos;
}
Example #6
0
size_t text_line_finish(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, text_line_end(txt, pos));
	do text_iterator_char_prev(&it, NULL);
	while (text_iterator_byte_get(&it, &c) && c != '\n' && space(c));
	return it.pos;
}
Example #7
0
size_t text_line_start(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, text_line_begin(txt, pos));
	while (text_iterator_byte_get(&it, &c) && c != '\n' && space(c))
		text_iterator_byte_next(&it, NULL);
	return it.pos;
}
Example #8
0
size_t text_paragraph_next(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);

	while (text_iterator_byte_get(&it, &c) && (c == '\n' || c == '\r'))
		text_iterator_byte_next(&it, NULL);
	return text_line_empty_next(txt, it.pos);
}
Example #9
0
size_t text_line_char_set(Text *txt, size_t pos, int count) {
	char c;
	size_t bol = text_line_begin(txt, pos);
	Iterator it = text_iterator_get(txt, bol);
	while (count-- > 0 && text_iterator_byte_get(&it, &c) && c != '\r' && c != '\n')
		text_iterator_char_next(&it, NULL);
	return it.pos;
}
Example #10
0
size_t text_line_offset(Text *txt, size_t pos, size_t off) {
	char c;
	size_t bol = text_line_begin(txt, pos);
	Iterator it = text_iterator_get(txt, bol);
	while (off-- > 0 && text_iterator_byte_get(&it, &c) && c != '\r' && c != '\n')
		text_iterator_byte_next(&it, NULL);
	return it.pos;
}
Example #11
0
size_t text_line_char_next(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);
	if (!text_iterator_byte_get(&it, &c) || c == '\r' || c == '\n')
		return pos;
	if (!text_iterator_char_next(&it, &c) || c == '\r' || c == '\n')
		return pos;
	return it.pos;
}
Example #12
0
size_t text_line_begin(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);
	if (!text_iterator_byte_get(&it, &c))
		return pos;
	if (c == '\n')
		text_iterator_byte_prev(&it, &c);
	if (c == '\r')
		text_iterator_byte_prev(&it, &c);
	while (text_iterator_byte_get(&it, &c)) {
		if (c == '\n') {
			it.pos++;
			break;
		}
		text_iterator_byte_prev(&it, NULL);
	}
	return it.pos;
}
Example #13
0
size_t text_paragraph_prev(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);

	/* c == \0 catches starting the search at EOF */
	while (text_iterator_byte_get(&it, &c) && (c == '\n' || c == '\r' || c == '\0'))
		text_iterator_byte_prev(&it, NULL);
	return text_line_empty_prev(txt, it.pos);
}
Example #14
0
size_t text_sentence_prev(Text *txt, size_t pos) {
	char c, prev = 'X';
	bool content = false;
	Iterator it = text_iterator_get(txt, pos);

	while (it.pos != 0 && text_iterator_byte_prev(&it, &c)) {
		if (content && space(prev) && (c == '.' || c == '?' || c == '!')) {
			do text_iterator_byte_next(&it, NULL);
			while (text_iterator_byte_get(&it, &c) && space(c));
			return it.pos;
		}
		content |= !space(c);
		prev = c;
	} /* The loop only ends on hitting BOF or error */
	if (content) /* starting pos was after first sentence in file => find that sentences start */
		while (text_iterator_byte_get(&it, &c) && space(c))
			text_iterator_byte_next(&it, NULL);
	return it.pos;
}
Example #15
0
File: vis.c Project: ewqasd200g/vis
void vis_replace(Vis *vis, size_t pos, const char *data, size_t len) {
	Text *txt = vis->win->file->text;
	Iterator it = text_iterator_get(txt, pos);
	int chars = text_char_count(data, len);
	for (char c; chars-- > 0 && text_iterator_byte_get(&it, &c) && c != '\r' && c != '\n'; )
		text_iterator_char_next(&it, NULL);

	text_delete(txt, pos, it.pos - pos);
	vis_insert(vis, pos, data, len);
}
Example #16
0
int text_line_char_get(Text *txt, size_t pos) {
	char c;
	int count = 0;
	size_t bol = text_line_begin(txt, pos);
	Iterator it = text_iterator_get(txt, bol);
	while (text_iterator_byte_get(&it, &c) && it.pos < pos && c != '\r' && c != '\n') {
		text_iterator_char_next(&it, NULL);
		count++;
	}
	return count;
}
Example #17
0
Filerange text_range_inner(Text *txt, Filerange *rin) {
	char c;
	Filerange r = *rin;
	Iterator it = text_iterator_get(txt, rin->start);
	while (text_iterator_byte_get(&it, &c) && isspace((unsigned char)c))
		text_iterator_byte_next(&it, NULL);
	r.start = it.pos;
	it = text_iterator_get(txt, rin->end);
	do r.end = it.pos; while (text_iterator_byte_prev(&it, &c) && isspace((unsigned char)c));
	return r;
}
Example #18
0
size_t text_customword_end_prev(Text *txt, size_t pos, int (*isboundary)(int)) {
	char c;
	Iterator it = text_iterator_get(txt, pos);
	if (!text_iterator_byte_get(&it, &c))
		return pos;
	if (boundary(c))
		while (boundary(c) && !space(c) && text_iterator_char_prev(&it, &c));
	else
		while (!boundary(c) && text_iterator_char_prev(&it, &c));
	while (space(c) && text_iterator_char_prev(&it, &c));
	return it.pos;
}
Example #19
0
Filerange text_object_entire_inner(Text *txt, size_t pos) {
	char c;
	Filerange r = text_object_entire(txt, pos);
	Iterator it = text_iterator_get(txt, r.start);
	while (text_iterator_byte_get(&it, &c) && (c == '\r' || c == '\n'))
		text_iterator_byte_next(&it, NULL);
	r.start = it.pos;
	it = text_iterator_get(txt, r.end);
	while (text_iterator_byte_prev(&it, &c) && (c == '\r' || c == '\n'));
	r.end = it.pos;
	return text_range_linewise(txt, &r);
}
Example #20
0
size_t text_sentence_next(Text *txt, size_t pos) {
	char c, prev = 'X';
	Iterator it = text_iterator_get(txt, pos), rev = text_iterator_get(txt, pos);

	if (!text_iterator_byte_get(&it, &c))
		return pos;

	while (text_iterator_byte_get(&rev, &prev) && space(prev))
		text_iterator_byte_prev(&rev, NULL);
	prev = rev.pos == 0 ? '.' : prev; /* simulate punctuation at BOF */

	do {
		if ((prev == '.' || prev == '?' || prev == '!') && space(c)) {
			do text_iterator_byte_next(&it, NULL);
			while (text_iterator_byte_get(&it, &c) && space(c));
			return it.pos;
		}
		prev = c;
	} while (text_iterator_byte_next(&it, &c));
	return it.pos;
}
Example #21
0
Filerange text_object_range(Text *txt, size_t pos, int (*isboundary)(int)) {
    char c;
    size_t start;
    Iterator it = text_iterator_get(txt, pos), rit = it;
    if (!text_iterator_byte_get(&rit, &c) || boundary(c))
        return text_range_empty();
    char tmp = c;
    do start = rit.pos;
    while (text_iterator_char_prev(&rit, &c) && !boundary(c));
    for (c = tmp; !boundary(c) && text_iterator_byte_next(&it, &c););
    return text_range_new(start, it.pos);
}
Example #22
0
size_t text_line_empty_next(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);
	while (text_iterator_byte_get(&it, &c)) {
		if (c == '\n' && text_iterator_byte_next(&it, &c)) {
			size_t match = it.pos;
			if (c == '\r')
				text_iterator_byte_next(&it, &c);
			if (c == '\n')
				return match;
		}
		text_iterator_byte_next(&it, NULL);
	}
	return it.pos;
}
Example #23
0
static size_t find_next(Text *txt, size_t pos, const char *s, bool line) {
	if (!s)
		return pos;
	size_t len = strlen(s), matched = 0;
	Iterator it = text_iterator_get(txt, pos), sit;
	for (char c; matched < len && text_iterator_byte_get(&it, &c); ) {
		if (c == s[matched]) {
			if (matched == 0)
				sit = it;
			matched++;
		} else if (matched > 0) {
			it = sit;
			matched = 0;
		}
		text_iterator_byte_next(&it, NULL);
		if (line && c == '\n')
			break;
	}
	return matched == len ? it.pos - len : pos;
}
Example #24
0
static Filerange text_object_customword(Text *txt, size_t pos, int (*isboundary)(int)) {
    Filerange r;
    char c, prev = '0', next = '0';
    Iterator it = text_iterator_get(txt, pos);
    if (!text_iterator_byte_get(&it, &c))
        return text_range_empty();
    if (text_iterator_byte_prev(&it, &prev))
        text_iterator_byte_next(&it, NULL);
    text_iterator_byte_next(&it, &next);
    if (space(c)) {
        r.start = text_char_next(txt, text_customword_end_prev(txt, pos, isboundary));
        r.end = text_customword_start_next(txt, pos, isboundary);
    } else if (boundary(prev) && boundary(next)) {
        if (boundary(c)) {
            r.start = text_char_next(txt, text_customword_end_prev(txt, pos, isboundary));
            r.end = text_char_next(txt, text_customword_end_next(txt, pos, isboundary));
        } else {
            /* on a single character */
            r.start = pos;
            r.end = text_char_next(txt, pos);
        }
    } else if (boundary(prev)) {
        /* at start of a word */
        r.start = pos;
        r.end = text_char_next(txt, text_customword_end_next(txt, pos, isboundary));
    } else if (boundary(next)) {
        /* at end of a word */
        r.start = text_customword_start_prev(txt, pos, isboundary);
        r.end = text_char_next(txt, pos);
    } else {
        /* in the middle of a word */
        r.start = text_customword_start_prev(txt, pos, isboundary);
        r.end = text_char_next(txt, text_customword_end_next(txt, pos, isboundary));
    }

    return r;
}
Example #25
0
size_t text_bracket_match_symbol(Text *txt, size_t pos, const char *symbols) {
	int direction, count = 1;
	char search, current, c;
	bool instring = false;
	Iterator it = text_iterator_get(txt, pos);
	if (!text_iterator_byte_get(&it, &current))
		return pos;
	if (symbols && !memchr(symbols, current, strlen(symbols)))
		return pos;
	switch (current) {
	case '(': search = ')'; direction =  1; break;
	case ')': search = '('; direction = -1; break;
	case '{': search = '}'; direction =  1; break;
	case '}': search = '{'; direction = -1; break;
	case '[': search = ']'; direction =  1; break;
	case ']': search = '['; direction = -1; break;
	case '<': search = '>'; direction =  1; break;
	case '>': search = '<'; direction = -1; break;
	case '"':
	case '`':
	case '\'': {
		char special[] = " \n)}]>.,:;";
		search = current;
		direction = 1;
		if (text_iterator_byte_next(&it, &c)) {
			/* if a single or double quote is followed by
			 * a special character, search backwards */
			if (memchr(special, c, sizeof(special)))
				direction = -1;
			text_iterator_byte_prev(&it, NULL);
		}
		break;
	}
	default: return pos;
	}

	if (direction >= 0) { /* forward search */
		while (text_iterator_byte_next(&it, &c)) {
			if (c != current && c == '"')
				instring = !instring;
			if (!instring) {
				if (c == search && --count == 0)
					return it.pos;
				else if (c == current)
					count++;
			}
		}
	} else { /* backwards */
		while (text_iterator_byte_prev(&it, &c)) {
			if (c != current && c == '"')
				instring = !instring;
			if (!instring) {
				if (c == search && --count == 0)
					return it.pos;
				else if (c == current)
					count++;
			}
		}
	}

	return pos; /* no match found */
}