Example #1
0
/* Return a pointer to start of current string, and set the suitable maximum
 * of can be displayed.(*len <= roll_display_window_size) */
char *roll_display_ptr(int *len, int *padding)
{
	*len = *padding = 0;
	if (roll_display_length_max <= roll_display_window_size) {
		if (len)
			*len = roll_display_orig_size;

		if (padding)
			*padding = roll_display_window_size -
						roll_display_length_max;
		return roll_display_orig;
	}

	char *ret = roll_display_curr;
	char *tmp = roll_display_curr;
	int l = 0;
	int t;

	/* Assume non-ascii characters use 2 width of ascii to display. */
	while (l < roll_display_window_size && *tmp) {
		t = utf8_char_length(tmp);
		l += (1 == t) ? 1 : 2;
		*len += t;
		tmp += t;
	}


	/* If display next non-ascii character will use width greater than
	 * specified '*len' */
	if (l > roll_display_window_size) {
		*len -= t;
		l -= (1 == t) ? 1 : 2;
		if (padding)
			*padding = roll_display_window_size - l;
	}

	if (likely(*tmp))
		roll_display_curr += utf8_char_length(roll_display_curr);
	else
		roll_display_curr = roll_display_orig;

	return ret;
}
Example #2
0
static const char *
get_author_initials(const char *author)
{
	static char initials[256];
	size_t pos = 0;
	const char *end = strchr(author, '\0');

#define is_initial_sep(c) (isspace(c) || ispunct(c) || (c) == '@' || (c) == '-')

	memset(initials, 0, sizeof(initials));
	while (author < end) {
		unsigned char bytes;
		size_t i;

		while (author < end && is_initial_sep(*author))
			author++;

		bytes = utf8_char_length(author);
		if (bytes >= sizeof(initials) - 1 - pos)
			break;
		while (bytes--) {
			initials[pos++] = *author++;
		}

		i = pos;
		while (author < end && !is_initial_sep(*author)) {
			bytes = utf8_char_length(author);
			if (bytes >= sizeof(initials) - 1 - i) {
				while (author < end && !is_initial_sep(*author))
					author++;
				break;
			}
			while (bytes--) {
				initials[i++] = *author++;
			}
		}

		initials[i++] = 0;
	}

	return initials;
}
Example #3
0
/* Calculates how much of string can be shown within the given maximum width
 * and sets trimmed parameter to non-zero value if all of string could not be
 * shown. If the reserve flag is true, it will reserve at least one
 * trailing character, which can be useful when drawing a delimiter.
 *
 * Returns the number of bytes to output from string to satisfy max_width. */
size_t
utf8_length(const char **start, int max_chars, size_t skip, int *width, size_t max_width, int *trimmed, bool reserve, int tab_size)
{
	const char *string = *start;
	const char *end = max_chars < 0 ? strchr(string, '\0') : string + max_chars;
	unsigned char last_bytes = 0;
	size_t last_ucwidth = 0;

	*width = 0;
	*trimmed = 0;

	while (string < end) {
		unsigned char bytes = utf8_char_length(string);
		size_t ucwidth;
		unsigned long unicode;

		if (string + bytes > end)
			break;

		/* Change representation to figure out whether
		 * it is a single- or double-width character. */

		unicode = utf8_to_unicode(string, bytes);
		/* FIXME: Graceful handling of invalid Unicode character. */
		if (!unicode)
			break;

		ucwidth = unicode_width(unicode, tab_size);
		if (skip > 0) {
			skip -= ucwidth <= skip ? ucwidth : skip;
			*start += bytes;
		}
		*width  += ucwidth;
		if (max_width > 0 && *width > max_width) {
			*trimmed = 1;
			*width -= ucwidth;
			if (reserve && *width == max_width) {
				string -= last_bytes;
				*width -= last_ucwidth;
			}
			break;
		}

		string  += bytes;
		if (ucwidth) {
			last_bytes = bytes;
			last_ucwidth = ucwidth;
		} else {
			last_bytes += bytes;
		}
	}

	return string - *start;
}
Example #4
0
unsigned int source_pos_t::col(char *input)
{
	unsigned int col = 1;
	char *c = input + line_offset;
	char *e = input + offset;
	while (c < e) {
		size_t len = utf8_char_length(*c);
		c += len;
		col++;
	}
	return col;
}
Example #5
0
File: string.c Project: avm/tig
const char*
utf8_skip(const char *string, size_t skip)
{
	while (skip-- > 0) {
		unsigned char len = utf8_char_length(string);
		assert(len > 0);
		while (len-- > 0) {
			if (!*string)
				return string;
			string++;
		}
	}
	return string;
}
Example #6
0
File: string.c Project: avm/tig
size_t
utf8_char_count(const char *string)
{
	size_t count = 0;
	while (1) {
		unsigned char len = utf8_char_length(string);
		while (len-- > 0) {
			if (!*string)
				return count;
			string++;
		}
		count += 1;
	}
}
Example #7
0
int roll_display_init(char *s, int window_size)
{
	if (!s || window_size <= 0)
		return -1;
	char *ptr = s;
	int tmp;

	roll_display_orig = s;
	roll_display_curr = s;
	roll_display_window_size = window_size;
	roll_display_orig_size = strlen(s);
	
	while (*ptr) {
		tmp = utf8_char_length(ptr);
		roll_display_length_max += (1 == tmp? 1 : 2) ;
		ptr += tmp;
	}
	return 0;
}
Example #8
0
File: keys.c Project: bbolli/tig
int
get_key_value(const char *name, struct key_input *input)
{
	int i;

	memset(input, 0, sizeof(*input));

	for (i = 0; i < ARRAY_SIZE(key_table); i++)
		if (!strcasecmp(key_table[i].name, name)) {
			if (key_table[i].value == ' ') {
				name = " ";
				break;
			}
			if (key_table[i].value == '#') {
				name = "#";
				break;
			}
			input->data.key = key_table[i].value;
			return OK;
		}

	if (name[0] == '^' && name[1] == '[') {
		input->modifiers.escape = 1;
		name += 2;
	} else if (name[0] == '^') {
		input->modifiers.control = 1;
		name += 1;
	}

	i = utf8_char_length(name);
	if (strlen(name) == i && utf8_to_unicode(name, i) != 0) {
		strncpy(input->data.bytes, name, i);
		input->modifiers.multibytes = 1;
		return OK;
	}

	return ERR;
}
Example #9
0
File: keys.c Project: acklinr/tig
static enum status_code
parse_key_value(struct key *key, const char **name_ptr, size_t offset,
		const char *replacement, const char *end)
{
	const char *name = replacement ? replacement : *name_ptr + offset;
	size_t namelen = utf8_char_length(name);
	const char *nameend = name + namelen;

	if (strlen(name) < namelen || utf8_to_unicode(name, namelen) == 0)
		return error("Error parsing UTF-8 bytes: %s", name);

	strncpy(key->data.bytes, name, namelen);
	key->modifiers.multibytes = 1;
	if (end) {
		*name_ptr = end + 1;
		if (!replacement && nameend + 1 < end)
			return success("Ignoring text after key mapping: %.*s",
				(int) (end - nameend), nameend);
	} else {
		*name_ptr = nameend;
	}

	return SUCCESS;
}
Example #10
0
int
get_input(int prompt_position, struct key_input *input, bool modifiers)
{
	struct view *view;
	int i, key, cursor_y, cursor_x;

	if (prompt_position)
		input_mode = TRUE;

	memset(input, 0, sizeof(*input));

	while (TRUE) {
		bool loading = FALSE;

		foreach_view (view, i) {
			update_view(view);
			if (view_is_displayed(view) && view->has_scrolled &&
			    use_scroll_redrawwin)
				redrawwin(view->win);
			view->has_scrolled = FALSE;
			if (view->pipe)
				loading = TRUE;
		}

		/* Update the cursor position. */
		if (prompt_position) {
			getbegyx(status_win, cursor_y, cursor_x);
			cursor_x = prompt_position;
		} else {
			view = display[current_view];
			getbegyx(view->win, cursor_y, cursor_x);
			cursor_x = view->width - 1;
			cursor_y += view->pos.lineno - view->pos.offset;
		}
		setsyx(cursor_y, cursor_x);

		/* Refresh, accept single keystroke of input */
		doupdate();
		nodelay(status_win, loading);
		key = wgetch(status_win);

		/* wgetch() with nodelay() enabled returns ERR when
		 * there's no input. */
		if (key == ERR) {

		} else if (key == KEY_ESC && modifiers) {
			input->modifiers.escape = 1;

		} else if (key == KEY_RESIZE) {
			int height, width;

			getmaxyx(stdscr, height, width);

			wresize(status_win, 1, width);
			mvwin(status_win, height - 1, 0);
			wnoutrefresh(status_win);
			resize_display();
			redraw_display(TRUE);

		} else {
			int pos, key_length;

			input_mode = FALSE;
			if (key == erasechar())
				key = KEY_BACKSPACE;

			/*
			 * Ctrl-<key> values are represented using a 0x1F
			 * bitmask on the key value. To 'unmap' we assume that:
			 *
			 * - Ctrl-Z is handled by Ncurses.
			 * - Ctrl-m is the same as Return/Enter.
			 * - Ctrl-i is the same as Tab.
			 *
			 * For all other key values in the range the Ctrl flag
			 * is set and the key value is updated to the proper
			 * ASCII value.
			 */
			if (KEY_CTL('a') <= key && key <= KEY_CTL('x') && key != KEY_RETURN && key != KEY_TAB) {
				input->modifiers.control = 1;
				key = key | 0x40;
			}

			if ((key >= KEY_MIN && key < KEY_MAX) || key < 0x1F) { // || key == ' ') {
				input->data.key = key;
				return input->data.key;
			}

			input->modifiers.multibytes = 1;
			input->data.bytes[0] = key;

			key_length = utf8_char_length(input->data.bytes);
			for (pos = 1; pos < key_length && pos < sizeof(input->data.bytes) - 1; pos++) {
				input->data.bytes[pos] = wgetch(status_win);
			}

			return OK;
		}
	}