Пример #1
0
size_t text_search_forward(Text *txt, size_t pos, Regex *regex) {
	size_t start = pos + 1;
	size_t end = text_size(txt);
	RegexMatch match[1];
	bool found = start < end && !text_search_range_forward(txt, start, end - start, regex, 1, match, 0);

	if (!found) {
		start = 0;
		end = pos;
		found = !text_search_range_forward(txt, start, end, regex, 1, match, 0);
	}

	return found ? match[0].start : pos;
}
Пример #2
0
Filerange text_object_search_forward(Text *txt, size_t pos, Regex *regex) {
    size_t start = pos;
    size_t end = text_size(txt);
    RegexMatch match[1];
    bool found = start < end && !text_search_range_forward(txt, start, end - start, regex, 1, match, 0);
    if (found)
        return text_range_new(match[0].start, match[0].end);
    return text_range_empty();
}
Пример #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;
}
Пример #4
0
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;

	if (cmd->regex) {
		size_t start = range->start, end = range->end, last_start = EPOS;
		RegexMatch match[1];
		while (start < end) {
			bool found = text_search_range_forward(txt, start,
				end - start, cmd->regex, 1, match,
				start > range->start ? REG_NOTBOL : 0) == 0;
			Filerange r = text_range_empty();
			if (found) {
				if (argv[0][0] == 'x')
					r = text_range_new(match[0].start, match[0].end);
				else
					r = text_range_new(start, match[0].start);
				if (match[0].start == match[0].end) {
					if (last_start == match[0].start) {
						start++;
						continue;
					}
					/* in Plan 9's regexp library ^ matches the beginning
					 * of a line, however in POSIX with REG_NEWLINE ^
					 * matches the zero-length string immediately after a
					 * newline. Try filtering out the last such match at EOF.
					 */
					if (end == match[0].start && start > range->start)
						break;
				}
				start = match[0].end;
			} else {
				if (argv[0][0] == 'y')
					r = text_range_new(start, end);
				start = end;
			}

			if (text_range_valid(&r)) {
				Mark mark_start = text_mark_set(txt, start);
				Mark mark_end = text_mark_set(txt, end);
				ret &= sam_execute(vis, win, cmd->cmd, NULL, &r);
				last_start = start = text_mark_get(txt, mark_start);
				if (start == EPOS && last_start != r.end)
					last_start = start = r.end;
				end = text_mark_get(txt, mark_end);
				if (start == EPOS || end == EPOS) {
					ret = false;
					break;
				}
			}
		}
	} else {
		size_t start = range->start, end = range->end;
		while (start < end) {
			size_t next = text_line_next(txt, start);
			if (next > end)
				next = end;
			Filerange r = text_range_new(start, next);
			if (start == next || !text_range_valid(&r))
				break;
			start = next;
			Mark mark_start = text_mark_set(txt, start);
			Mark mark_end = text_mark_set(txt, end);
			ret &= sam_execute(vis, win, cmd->cmd, NULL, &r);
			start = text_mark_get(txt, mark_start);
			if (start == EPOS)
				start = r.end;
			end = text_mark_get(txt, mark_end);
			if (end == EPOS) {
				ret = false;
				break;
			}
		}
	}

	view_cursors_dispose(cur);
	return ret;
}