Exemplo n.º 1
0
int
min_match(const char *string, size_t offset, size_t *start, size_t *end)
{
	char	 *s, *e, *q;

	q = query;
	if ((s = e = strcasechr(&string[offset], q)) == NULL)
		return 0;

	for (;;) {
		for (e++, q++; isu8cont(*q); e++, q++);
		if (*q == '\0')
			break;
		if ((e = strcasechr(e, q)) == NULL)
			return 0;
	}

	*start = s - string;
	*end = e - string;
	/* Less than or equal is used in order to obtain the left-most match. */
	if (min_match(string, offset + 1, start, end)
	    && (size_t)(e - s) <= *end - *start) {
		*start = s - string;
		*end = e - string;
	}
	return 1;
}
Exemplo n.º 2
0
/*
 * wr_fputs - like fputs(), but makes control characters visible and
 *     turns \n into \r\n
 */
void
wr_fputs(char *s)
{

#define	PUTC(c)	if (putchar(c) == EOF) goto err;

	for (; *s != '\0'; ++s) {
		if (*s == '\n') {
			PUTC('\r');
			PUTC('\n');
			continue;
		}
		if (isu8cont(*s))
			continue;
		if (isprint(*s) || isspace(*s) || *s == '\a') {
			PUTC(*s);
		} else {
			PUTC('?');
		}

	}
	return;

err:	err(1, NULL);
#undef PUTC
}
Exemplo n.º 3
0
static edit_status
editor_delete_char (rp_input_line *line)
{
  size_t diff = 0;

  if (line->position == line->length)
    return EDIT_NO_OP;

  if (isu8start (line->buffer[line->position]))
    {
      do
        diff++;
      while (isu8cont (line->buffer[line->position + diff]));
    }
  else
    diff++;

  memmove (&line->buffer[line->position],
           &line->buffer[line->position + diff],
           line->length - line->position + diff + 1);

  line->length -= diff;

  return EDIT_DELETE;
}
Exemplo n.º 4
0
static edit_status
editor_backward_char (rp_input_line *line)
{
  if (line->position == 0)
    return EDIT_NO_OP;

  do
    line->position--;
  while (line->position > 0 && isu8cont (line->buffer[line->position]));

  return EDIT_MOVE;
}
Exemplo n.º 5
0
void
print_query(char *query, size_t length, size_t position, size_t scroll)
{
	size_t	i = 0;

	tty_putp(restore_cursor);
	put_line(query + scroll, length - scroll);

	tty_putp(restore_cursor);
	while (i < position - scroll) {
		while (isu8cont(query[++i]));
		tty_putp(cursor_right);
	}
}
Exemplo n.º 6
0
static edit_status
editor_forward_char (rp_input_line *line)
{
  if (line->position == line->length)
    return EDIT_NO_OP;

  if (isu8start (line->buffer[line->position]))
    {
      do
        line->position++;
      while (isu8cont (line->buffer[line->position]));
    }
  else
    line->position++;

  return EDIT_MOVE;
}
Exemplo n.º 7
0
static edit_status
editor_backward_delete_char (rp_input_line *line)
{
  size_t diff = 1;

  if (line->position == 0)
    return EDIT_NO_OP;

  while (line->position - diff > 0
         && isu8cont (line->buffer[line->position - diff]))
    diff++;

  memmove (&line->buffer[line->position - diff],
           &line->buffer[line->position],
           line->length - line->position + 1);

  line->position -= diff;
  line->length -= diff;

  return EDIT_DELETE;
}
Exemplo n.º 8
0
int
print_choices(int selection)
{
	int		 col, i, j, k;
	size_t		 query_length;
	struct choice	*choice;

	tty_putp(clr_eos);
	/* Emit query line. */
	tty_putc('\n');

	query_length = strlen(query);
	for (choice = choices.v, col = i = 0;
	     i < (ssize_t)choices.length
	     && i < lines - 1
	     && (query_length == 0 || choice->score > 0);
	     choice++, i++) {
		if (i == selection)
			tty_putp(enter_standout_mode);

		for (col = j = 0;
		     j < (ssize_t)choice->match_start && col < columns;
		     col += !isu8cont(choice->string[j]), j++)
			if (tty_putc(choice->string[j]) == EOF)
				err(1, "tty_putc");

		tty_putp(enter_underline_mode);

		for (;
		     j < (ssize_t)choice->match_end && col < columns;
		     col += !isu8cont(choice->string[j]), j++)
			if (tty_putc(choice->string[j]) == EOF)
				err(1, "tty_putc");

		tty_putp(exit_underline_mode);

		for (;
		     j < (ssize_t)choice->length && col < columns;
		     col += !isu8cont(choice->string[j]), j++) {
			/* A null character will be present before the
			 * terminating null character if descriptions is
			 * enabled. */
			if (choice->string[j] == '\0') {
				if (tty_putc(' ') == EOF)
					err(1, "tty_putc");
			} else if (tty_putc(choice->string[j]) == EOF) {
				err(1, "tty_putc");
			}
		}

		for (k = MAX(columns - choice->printable_length +
			    (choice->length - col), 0); k > 0; k--)
			if (tty_putc(' ') == EOF)
				err(1, "tty_putc");

		if (i == selection)
			tty_putp(exit_standout_mode);
	}

	return i;
}
Exemplo n.º 9
0
const struct choice *
selected_choice(void)
{
	char		 buf[6];
	int		 key, selection = 0, visible_choices_count;
	int		 word_position;
	size_t		 cursor_position, length, query_length, scroll;

	cursor_position = query_length = strlen(query);

	filter_choices();
	init_tty();

	if (cursor_position >= (size_t)columns)
		scroll = cursor_position - columns + 1;
	else
		scroll = 0;

	visible_choices_count = print_choices(selection);
	print_query(query, query_length, cursor_position, scroll);
	tty_putp(cursor_normal);

	for (;;) {
		fflush(tty_out);
		memset(buf, 0, sizeof(buf));
		key = get_key(buf, sizeof(buf), &length);

		switch (key) {
		case ENTER:
			if (visible_choices_count > 0) {
				restore_tty();
				if (selection >= 0 && selection < (ssize_t)choices.length)
					return &choices.v[selection];
				else
					return NULL;
			}

			break;
		case ALT_ENTER:
			restore_tty();
			choices.v[choices.length].string = query;
			choices.v[choices.length].description = "";
			return &choices.v[choices.length];
		case DEL:
			if (cursor_position > 0) {
				for (length = 1;
				    isu8cont(query[cursor_position - length]);
				    length++);
				delete_between(
				    query,
				    query_length,
				    cursor_position - length,
				    cursor_position);
				cursor_position -= length;
				query_length -= length;
				filter_choices();
				selection = 0;
			}

			break;
		case CTRL_D:
			if (cursor_position < query_length) {
				for (length = 1;
				    isu8cont(query[cursor_position + length]);
				    length++);
				delete_between(
				    query,
				    query_length,
				    cursor_position,
				    cursor_position + length);
				query_length -= length;
				filter_choices();
				selection = 0;
			}

			break;
		case CTRL_U:
			delete_between(
			    query,
			    query_length,
			    0,
			    cursor_position);
			query_length -= cursor_position;
			cursor_position = 0;
			filter_choices();
			selection = 0;
			break;
		case CTRL_K:
			delete_between(
			    query,
			    query_length,
			    cursor_position,
			    query_length);
			query_length = cursor_position;
			filter_choices();
			selection = 0;
			break;
		case CTRL_W:
			if (cursor_position == 0)
				break;

			for (word_position = cursor_position;;) {
				while (isu8cont(query[--word_position]));
				if (word_position < 1)
					break;
				if (query[word_position] != ' '
				    && query[word_position - 1] == ' ')
					break;
			}
			delete_between(
			    query,
			    query_length,
			    word_position,
			    cursor_position);
			query_length -= cursor_position - word_position;
			cursor_position = word_position;
			filter_choices();
			selection = 0;
			break;
		case CTRL_A:
			cursor_position = 0;
			break;
		case CTRL_E:
			cursor_position = query_length;
			break;
		case DOWN:
			if (selection < visible_choices_count - 1)
				++selection;
			break;
		case UP:
			if (selection > 0)
				--selection;
			break;
		case LEFT:
			while (cursor_position > 0
			    && isu8cont(query[--cursor_position]));
			break;
		case RIGHT:
			while (cursor_position < query_length
			    && isu8cont(query[++cursor_position]));
			break;
		default:
			if (!isu8start(buf[0]) && !isprint(buf[0]))
				continue;

			if (query_size < query_length + length) {
				query_size = 2*query_length + length;
				if ((query = reallocarray(query, query_size,
					    sizeof(char))) == NULL)
					err(1, NULL);
			}

			if (cursor_position < query_length)
				memmove(query + cursor_position + length,
					query + cursor_position,
					query_length - cursor_position);

			memcpy(query + cursor_position, buf, length);
			cursor_position += length;
			query_length += length;
			query[query_length] = '\0';
			filter_choices();
			selection = 0;

			break;
		}

		tty_putp(cursor_invisible);

		visible_choices_count = print_choices(selection);
		if (cursor_position >= scroll + columns)
			scroll = cursor_position - columns + 1;
		if (cursor_position < scroll)
			scroll = cursor_position;
		print_query(query, query_length, cursor_position, scroll);
		tty_putp(cursor_normal);
	}
}