Example #1
0
File: input.c Project: dmt4/ne
static void input_prev_word(void) {
	bool word_skipped = false;

	while(pos > 0) {
		input_move_left(false);
		const int c = get_char(&input_buffer[pos], encoding);
		if (ne_isword(c, encoding)) word_skipped = true;
		else if (word_skipped) {
			input_move_right(false);
			break;
		}
	}
	input_refresh();
}
Example #2
0
File: input.c Project: dmt4/ne
static void input_next_word(void) {
	bool space_skipped = false;

	while(pos < len) {
		const int c = get_char(&input_buffer[pos], encoding);
		if (!ne_isword(c, encoding)) space_skipped = true;
		else if (space_skipped) break;
		input_move_right(false);
	}
	if (x == ne_columns - 1) {
		offset = pos;
		x = start_x;
	}
	input_refresh();
}
Example #3
0
File: autocomp.c Project: vigna/ne
static void search_buff(const buffer *b, char * p, const int encoding, const bool case_search, const int ext) {
	assert(p);
	const int p_len = strlen(p);
	const int (*cmp)(const char *, const char *, size_t) = case_search ? strncmp : strncasecmp;
	for(line_desc *ld = (line_desc *)b->line_desc_list.head, *next; next = (line_desc *)ld->ld_node.next; ld = next) {
		int64_t l = 0, r = 0;
		do {
			/* find left edge of word */
			while (l < ld->line_len - p_len && !ne_isword(get_char(&ld->line[l], b->encoding), b->encoding)) l += get_char_width(&ld->line[l], b->encoding);
			if (l < ld->line_len - p_len ) {
				int ch;
				/* find right edge of word */
				r = l + get_char_width(&ld->line[l], b->encoding);
				/* accept "'" as a word character if it is followed by another word character, so that
				   words like "don't" are not broken into "don" and "t". */
				while (r < ld->line_len
				       && (    ne_isword(ch=get_char(&ld->line[r], b->encoding), b->encoding)
				            || ( r+1 < ld->line_len && ch == '\'' && ne_isword(get_char(&ld->line[r+1], b->encoding), b->encoding))
				          )
				      ) r += get_char_width(&ld->line[r], b->encoding);
				if ((b != cur_buffer || ld != b->cur_line_desc || b->cur_pos < l || r < b->cur_pos)
				     && r - l > p_len && (b->encoding == encoding || is_ascii(&ld->line[l], r - l))
				     && !cmp(p, &ld->line[l], p_len))
					add_string(&ld->line[l], r - l, ext);
				l = r;
				count_scanned++;
			}
			assert(l <= ld->line_len);
			if (stop || count_scanned >= MAX_AUTOCOMPLETE_SCAN) {
				add_string(NULL, -1, 0);
				return;
			}
		} while (l < ld->line_len - p_len);
	}
	add_string(NULL, -1, 0);
}
Example #4
0
File: input.c Project: dmt4/ne
static void input_autocomplete(void) {
	int dx = 0, prefix_pos = pos;
	char *p;

	/* find a usable prefix */
	if (prefix_pos && prefix_pos <= len) {
		prefix_pos = prev_pos(input_buffer, prefix_pos, encoding);
		dx--;
		while (prefix_pos && ne_isword(get_char(&input_buffer[prefix_pos], encoding), encoding)) {
			dx--;
			prefix_pos = prev_pos(input_buffer, prefix_pos, encoding);
		}
		if (! ne_isword(get_char(&input_buffer[prefix_pos], encoding), encoding)) {
			dx++;
			prefix_pos = next_pos(input_buffer, prefix_pos, encoding);
		}
		p = malloc(pos - prefix_pos + 1);
		if (!p) {
			alert(); /* OUT_OF_MEMORY */
			return;
		}
		strncpy(p, &input_buffer[prefix_pos], pos - prefix_pos);
	}
	else p = malloc(1); /* no prefix left of the cursor; we'll give an empty one. */
	p[pos - prefix_pos] = 0;

	int ac_err;
	if (p = autocomplete(p, NULL, true, &ac_err)) {
		encoding_type ac_encoding = detect_encoding(p, strlen(p));
		if (ac_encoding != ENC_ASCII && encoding != ENC_ASCII && ac_encoding != encoding) {
			free(p);
			alert();
		} else {
			encoding = ac_encoding;

			if (prefix_pos < pos) {
				memmove(&input_buffer[prefix_pos], &input_buffer[pos], len - pos + 1);
				len -= pos - prefix_pos;
				pos = prefix_pos;
			}
			int ac_len = strlen(p);
			if (ac_len + len >= MAX_INPUT_LINE_LEN) ac_len = MAX_INPUT_LINE_LEN - len;
			memmove(&input_buffer[pos + ac_len], &input_buffer[pos], len - pos + 1);
			memmove(&input_buffer[pos], p, ac_len);
			len += ac_len;
			while (ac_len > 0) {
				const int cw = get_char_width(&input_buffer[pos],encoding);
				pos = next_pos(input_buffer, pos, encoding);
				ac_len -= cw;
				dx++;
			}
			free(p); 
			x += dx;
			if (x >= ne_columns) {
				dx = x - ne_columns + 1;
				while (dx--) {
					offset = next_pos(input_buffer, offset, encoding);
				}
				x = ne_columns - 1;
			}
		}
	}
	if (ac_err == AUTOCOMPLETE_COMPLETED || ac_err == AUTOCOMPLETE_CANCELLED) {
		do_action(cur_buffer, REFRESH_A, 0, NULL);
		refresh_window(cur_buffer);
		set_attr(0);
		print_prompt(NULL);
	}
	input_refresh();
}
Example #5
0
File: edit.c Project: vigna/ne
static int to_something(buffer *b, int (to_first)(int), int (to_rest)(int)) {
	assert_buffer(b);

	/* If we are after the end of the line, just return ERROR. */

	if (b->cur_line == b->num_lines -1 && b->cur_pos >= b->cur_line_desc->line_len) return ERROR;

	int64_t pos = b->cur_pos;
	int c;
	/* First of all, we search for the word start, if we're not over it. */
	if (pos >= b->cur_line_desc->line_len || !ne_isword(c = get_char(&b->cur_line_desc->line[pos], b->encoding), b->encoding))
		if (search_word(b, 1) != OK)
			return ERROR;

	bool changed = false;
	int64_t new_len = 0;
	pos = b->cur_pos;
	const int64_t cur_char = b->cur_char;
	const int cur_x = b->cur_x;
	/* Then, we compute the word position extremes, length of the result (which
		may change because of casing). */
	while (pos < b->cur_line_desc->line_len && ne_isword(c = get_char(&b->cur_line_desc->line[pos], b->encoding), b->encoding)) {
		const int new_c = new_len ? to_rest(c) : to_first(c);
		changed |= (c != new_c);

		if (b->encoding == ENC_UTF8) new_len += utf8seqlen(new_c);
		else new_len++;

		pos = next_pos(b->cur_line_desc->line, pos, b->encoding);
	}

	const int64_t len = pos - b->cur_pos;
	if (!len) {
		char_right(b);
		return OK;
	}

	if (changed) {
		/* We actually perform changes only if some character was case folded. */
		char * word = malloc(new_len * sizeof *word);
		if (!word) return OUT_OF_MEMORY;

		pos = b->cur_pos;
		new_len = 0;
		/* Second pass: we actually build the transformed word. */
		while (pos < b->cur_line_desc->line_len && ne_isword(c = get_char(&b->cur_line_desc->line[pos], b->encoding), b->encoding)) {
			if (b->encoding == ENC_UTF8) new_len += utf8str(new_len ? to_rest(c) : to_first(c), word + new_len);
			else {
				word[new_len] = new_len ? to_rest(c) : to_first(c);
				new_len++;
			}

			pos = next_pos(b->cur_line_desc->line, pos, b->encoding);
		}

		start_undo_chain(b);

		delete_stream(b, b->cur_line_desc, b->cur_line, b->cur_pos, len);
		if (new_len) insert_stream(b, b->cur_line_desc, b->cur_line, b->cur_pos, word, new_len);

		free(word);

		end_undo_chain(b);

		if (cur_char < b->attr_len) b->attr_len = cur_char;
		update_line(b, b->cur_line_desc, b->cur_y, cur_x, false);
		need_attr_update = true;
	}

	return search_word(b, 1);
}