Example #1
0
size_t text_line_empty_prev(Text *txt, size_t pos) {
	char c;
	Iterator it = text_iterator_get(txt, pos);
	while (text_iterator_byte_prev(&it, &c)) {
		if (c == '\n' && text_iterator_byte_prev(&it, &c)) {
			if (c == '\r')
				text_iterator_byte_prev(&it, &c);
			if (c == '\n')
				return it.pos + 1;
		}
	}
	return it.pos;
}
Example #2
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 #3
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 #4
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 #5
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 #6
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 #7
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 #8
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 #9
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 #10
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 #11
0
static size_t find_prev(Text *txt, size_t pos, const char *s, bool line) {
	if (!s)
		return pos;
	size_t len = strlen(s), matched = len - 1;
	Iterator it = text_iterator_get(txt, pos), sit;
	if (len == 0)
		return pos;
	for (char c; text_iterator_byte_prev(&it, &c); ) {
		if (c == s[matched]) {
			if (matched == 0)
				return it.pos;
			if (matched == len - 1)
				sit = it;
			matched--;
		} else if (matched < len - 1) {
			it = sit;
			matched = len - 1;
		}
		if (line && c == '\n')
			break;
	}
	return pos;
}
Example #12
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 #13
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 */
}