mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'master' of github.com:tmux/tmux
This commit is contained in:
		@@ -140,12 +140,14 @@ const struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
 | 
			
		||||
	{ MODEKEYCOPY_RECTANGLETOGGLE, "rectangle-toggle" },
 | 
			
		||||
	{ MODEKEYCOPY_MIDDLELINE, "middle-line" },
 | 
			
		||||
	{ MODEKEYCOPY_NEXTPAGE, "page-down" },
 | 
			
		||||
	{ MODEKEYCOPY_NEXTPARAGRAPH, "next-paragraph" },
 | 
			
		||||
	{ MODEKEYCOPY_NEXTSPACE, "next-space" },
 | 
			
		||||
	{ MODEKEYCOPY_NEXTSPACEEND, "next-space-end" },
 | 
			
		||||
	{ MODEKEYCOPY_NEXTWORD, "next-word" },
 | 
			
		||||
	{ MODEKEYCOPY_NEXTWORDEND, "next-word-end" },
 | 
			
		||||
	{ MODEKEYCOPY_OTHEREND, "other-end" },
 | 
			
		||||
	{ MODEKEYCOPY_PREVIOUSPAGE, "page-up" },
 | 
			
		||||
	{ MODEKEYCOPY_PREVIOUSPARAGRAPH, "previous-paragraph" },
 | 
			
		||||
	{ MODEKEYCOPY_PREVIOUSSPACE, "previous-space" },
 | 
			
		||||
	{ MODEKEYCOPY_PREVIOUSWORD, "previous-word" },
 | 
			
		||||
	{ MODEKEYCOPY_RIGHT, "cursor-right" },
 | 
			
		||||
@@ -335,6 +337,8 @@ const struct mode_key_entry mode_key_vi_copy[] = {
 | 
			
		||||
	{ 'q',			    0, MODEKEYCOPY_CANCEL },
 | 
			
		||||
	{ 'v',			    0, MODEKEYCOPY_RECTANGLETOGGLE },
 | 
			
		||||
	{ 'w',			    0, MODEKEYCOPY_NEXTWORD },
 | 
			
		||||
	{ '{',			    0, MODEKEYCOPY_PREVIOUSPARAGRAPH },
 | 
			
		||||
	{ '}',			    0, MODEKEYCOPY_NEXTPARAGRAPH },
 | 
			
		||||
	{ KEYC_BSPACE,		    0, MODEKEYCOPY_LEFT },
 | 
			
		||||
	{ KEYC_DOWN | KEYC_CTRL,    0, MODEKEYCOPY_SCROLLDOWN },
 | 
			
		||||
	{ KEYC_DOWN,		    0, MODEKEYCOPY_DOWN },
 | 
			
		||||
@@ -483,6 +487,8 @@ const struct mode_key_entry mode_key_emacs_copy[] = {
 | 
			
		||||
	{ 't',			    0, MODEKEYCOPY_JUMPTO },
 | 
			
		||||
	{ 'v' | KEYC_ESCAPE,	    0, MODEKEYCOPY_PREVIOUSPAGE },
 | 
			
		||||
	{ 'w' | KEYC_ESCAPE,	    0, MODEKEYCOPY_COPYSELECTION },
 | 
			
		||||
	{ '{' | KEYC_ESCAPE,	    0, MODEKEYCOPY_PREVIOUSPARAGRAPH },
 | 
			
		||||
	{ '}' | KEYC_ESCAPE,	    0, MODEKEYCOPY_NEXTPARAGRAPH },
 | 
			
		||||
	{ KEYC_DOWN | KEYC_CTRL,    0, MODEKEYCOPY_SCROLLDOWN },
 | 
			
		||||
	{ KEYC_DOWN | KEYC_ESCAPE,  0, MODEKEYCOPY_HALFPAGEDOWN },
 | 
			
		||||
	{ KEYC_DOWN,		    0, MODEKEYCOPY_DOWN },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.1
									
									
									
									
									
								
							@@ -1029,6 +1029,7 @@ The following keys are supported as appropriate for the mode:
 | 
			
		||||
.It Li "Jump to backward" Ta "T" Ta ""
 | 
			
		||||
.It Li "Jump to forward" Ta "t" Ta ""
 | 
			
		||||
.It Li "Next page" Ta "C-f" Ta "Page down"
 | 
			
		||||
.It Li "Next paragraph" Ta "}" Ta "M-}"
 | 
			
		||||
.It Li "Next space" Ta "W" Ta ""
 | 
			
		||||
.It Li "Next space, end of word" Ta "E" Ta ""
 | 
			
		||||
.It Li "Next word" Ta "w" Ta ""
 | 
			
		||||
@@ -1036,6 +1037,7 @@ The following keys are supported as appropriate for the mode:
 | 
			
		||||
.It Li "Other end of selection" Ta "o" Ta ""
 | 
			
		||||
.It Li "Paste buffer" Ta "p" Ta "C-y"
 | 
			
		||||
.It Li "Previous page" Ta "C-b" Ta "Page up"
 | 
			
		||||
.It Li "Previous paragraph" Ta "{" Ta "M-{"
 | 
			
		||||
.It Li "Previous space" Ta "B" Ta ""
 | 
			
		||||
.It Li "Previous word" Ta "b" Ta "M-b"
 | 
			
		||||
.It Li "Quit mode" Ta "q" Ta "Escape"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -538,12 +538,14 @@ enum mode_key_cmd {
 | 
			
		||||
	MODEKEYCOPY_LEFT,
 | 
			
		||||
	MODEKEYCOPY_MIDDLELINE,
 | 
			
		||||
	MODEKEYCOPY_NEXTPAGE,
 | 
			
		||||
	MODEKEYCOPY_NEXTPARAGRAPH,
 | 
			
		||||
	MODEKEYCOPY_NEXTSPACE,
 | 
			
		||||
	MODEKEYCOPY_NEXTSPACEEND,
 | 
			
		||||
	MODEKEYCOPY_NEXTWORD,
 | 
			
		||||
	MODEKEYCOPY_NEXTWORDEND,
 | 
			
		||||
	MODEKEYCOPY_OTHEREND,
 | 
			
		||||
	MODEKEYCOPY_PREVIOUSPAGE,
 | 
			
		||||
	MODEKEYCOPY_PREVIOUSPARAGRAPH,
 | 
			
		||||
	MODEKEYCOPY_PREVIOUSSPACE,
 | 
			
		||||
	MODEKEYCOPY_PREVIOUSWORD,
 | 
			
		||||
	MODEKEYCOPY_RECTANGLETOGGLE,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										187
									
								
								tty-keys.c
									
									
									
									
									
								
							
							
						
						
									
										187
									
								
								tty-keys.c
									
									
									
									
									
								
							@@ -33,14 +33,17 @@
 | 
			
		||||
 * into a ternary tree.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void		tty_keys_add1(struct tty_key **, const char *, key_code);
 | 
			
		||||
void		tty_keys_add(struct tty *, const char *, key_code);
 | 
			
		||||
void		tty_keys_free1(struct tty_key *);
 | 
			
		||||
struct tty_key *tty_keys_find1(struct tty_key *, const char *, size_t,
 | 
			
		||||
static void	tty_keys_add1(struct tty_key **, const char *, key_code);
 | 
			
		||||
static void	tty_keys_add(struct tty *, const char *, key_code);
 | 
			
		||||
static void	tty_keys_free1(struct tty_key *);
 | 
			
		||||
static struct tty_key *tty_keys_find1(struct tty_key *, const char *, size_t,
 | 
			
		||||
		    size_t *);
 | 
			
		||||
struct tty_key *tty_keys_find(struct tty *, const char *, size_t, size_t *);
 | 
			
		||||
void		tty_keys_callback(int, short, void *);
 | 
			
		||||
int		tty_keys_mouse(struct tty *, const char *, size_t, size_t *);
 | 
			
		||||
static struct tty_key *tty_keys_find(struct tty *, const char *, size_t,
 | 
			
		||||
		    size_t *);
 | 
			
		||||
static int	tty_keys_next1(struct tty *, const char *, size_t, key_code *,
 | 
			
		||||
		    size_t *);
 | 
			
		||||
static void	tty_keys_callback(int, short, void *);
 | 
			
		||||
static int	tty_keys_mouse(struct tty *, const char *, size_t, size_t *);
 | 
			
		||||
 | 
			
		||||
/* Default raw keys. */
 | 
			
		||||
struct tty_default_key_raw {
 | 
			
		||||
@@ -316,7 +319,7 @@ const struct tty_default_key_code tty_default_code_keys[] = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Add key to tree. */
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
tty_keys_add(struct tty *tty, const char *s, key_code key)
 | 
			
		||||
{
 | 
			
		||||
	struct tty_key	*tk;
 | 
			
		||||
@@ -334,7 +337,7 @@ tty_keys_add(struct tty *tty, const char *s, key_code key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Add next node to the tree. */
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
tty_keys_add1(struct tty_key **tkp, const char *s, key_code key)
 | 
			
		||||
{
 | 
			
		||||
	struct tty_key	*tk;
 | 
			
		||||
@@ -409,7 +412,7 @@ tty_keys_free(struct tty *tty)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Free a single key. */
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
tty_keys_free1(struct tty_key *tk)
 | 
			
		||||
{
 | 
			
		||||
	if (tk->next != NULL)
 | 
			
		||||
@@ -422,7 +425,7 @@ tty_keys_free1(struct tty_key *tk)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Lookup a key in the tree. */
 | 
			
		||||
struct tty_key *
 | 
			
		||||
static struct tty_key *
 | 
			
		||||
tty_keys_find(struct tty *tty, const char *buf, size_t len, size_t *size)
 | 
			
		||||
{
 | 
			
		||||
	*size = 0;
 | 
			
		||||
@@ -430,7 +433,7 @@ tty_keys_find(struct tty *tty, const char *buf, size_t len, size_t *size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find the next node. */
 | 
			
		||||
struct tty_key *
 | 
			
		||||
static struct tty_key *
 | 
			
		||||
tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size)
 | 
			
		||||
{
 | 
			
		||||
	/* If the node is NULL, this is the end of the tree. No match. */
 | 
			
		||||
@@ -460,6 +463,56 @@ tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size)
 | 
			
		||||
	return (tty_keys_find1(tk, buf, len, size));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Look up part of the next key. */
 | 
			
		||||
static int
 | 
			
		||||
tty_keys_next1(struct tty *tty, const char *buf, size_t len, key_code *key,
 | 
			
		||||
    size_t *size)
 | 
			
		||||
{
 | 
			
		||||
	struct tty_key		*tk, *tk1;
 | 
			
		||||
	struct utf8_data	 ud;
 | 
			
		||||
	enum utf8_state		 more;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
	wchar_t			 wc;
 | 
			
		||||
 | 
			
		||||
	log_debug("next key is %zu (%.*s)", len, (int)len, buf);
 | 
			
		||||
 | 
			
		||||
	/* Empty buffer is a partial key. */
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return (1);
 | 
			
		||||
 | 
			
		||||
	/* Is this a known key? */
 | 
			
		||||
	tk = tty_keys_find(tty, buf, len, size);
 | 
			
		||||
	if (tk != NULL) {
 | 
			
		||||
		tk1 = tk;
 | 
			
		||||
		do
 | 
			
		||||
			log_debug("keys in list: %#llx", tk->key);
 | 
			
		||||
		while ((tk1 = tk1->next) != NULL);
 | 
			
		||||
		*key = tk->key;
 | 
			
		||||
		return (tk->next != NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Is this valid UTF-8? */
 | 
			
		||||
	more = utf8_open(&ud, (u_char)*buf);
 | 
			
		||||
	if (more == UTF8_MORE) {
 | 
			
		||||
		*size = ud.size;
 | 
			
		||||
		if (len < ud.size)
 | 
			
		||||
			return (1);
 | 
			
		||||
		for (i = 1; i < ud.size; i++)
 | 
			
		||||
			more = utf8_append(&ud, (u_char)buf[i]);
 | 
			
		||||
		if (more != UTF8_DONE)
 | 
			
		||||
			return (0);
 | 
			
		||||
 | 
			
		||||
		if (utf8_combine(&ud, &wc) != UTF8_DONE)
 | 
			
		||||
			return (0);
 | 
			
		||||
		*key = wc;
 | 
			
		||||
 | 
			
		||||
		log_debug("UTF-8 key %.*s %#llx", (int)ud.size, buf, *key);
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (-1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Process at least one key in the buffer and invoke tty->key_callback. Return
 | 
			
		||||
 * 0 if there are no further keys, or 1 if there could be more in the buffer.
 | 
			
		||||
@@ -467,17 +520,12 @@ tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size)
 | 
			
		||||
key_code
 | 
			
		||||
tty_keys_next(struct tty *tty)
 | 
			
		||||
{
 | 
			
		||||
	struct tty_key		*tk;
 | 
			
		||||
	struct timeval		 tv;
 | 
			
		||||
	const char		*buf;
 | 
			
		||||
	size_t			 len, size;
 | 
			
		||||
	cc_t			 bspace;
 | 
			
		||||
	int			 delay, expired = 0;
 | 
			
		||||
	key_code		 key;
 | 
			
		||||
	struct utf8_data	 ud;
 | 
			
		||||
	enum utf8_state		 more;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
	wchar_t			 wc;
 | 
			
		||||
	struct timeval	 tv;
 | 
			
		||||
	const char	*buf;
 | 
			
		||||
	size_t		 len, size;
 | 
			
		||||
	cc_t		 bspace;
 | 
			
		||||
	int		 delay, expired = 0;
 | 
			
		||||
	key_code	 key;
 | 
			
		||||
 | 
			
		||||
	/* Get key buffer. */
 | 
			
		||||
	buf = EVBUFFER_DATA(tty->event->input);
 | 
			
		||||
@@ -485,7 +533,7 @@ tty_keys_next(struct tty *tty)
 | 
			
		||||
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return (0);
 | 
			
		||||
	log_debug("keys are %zu (%.*s)", len, (int) len, buf);
 | 
			
		||||
	log_debug("keys are %zu (%.*s)", len, (int)len, buf);
 | 
			
		||||
 | 
			
		||||
	/* Is this a mouse key press? */
 | 
			
		||||
	switch (tty_keys_mouse(tty, buf, len, &size)) {
 | 
			
		||||
@@ -501,68 +549,65 @@ tty_keys_next(struct tty *tty)
 | 
			
		||||
		goto partial_key;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Look for matching key string and return if found. */
 | 
			
		||||
	tk = tty_keys_find(tty, buf, len, &size);
 | 
			
		||||
	if (tk != NULL) {
 | 
			
		||||
		if (tk->next != NULL)
 | 
			
		||||
first_key:
 | 
			
		||||
	/* If escape is at the start, try without it. */
 | 
			
		||||
	if (*buf == '\033') {
 | 
			
		||||
		switch (tty_keys_next1 (tty, buf + 1, len - 1, &key, &size)) {
 | 
			
		||||
		case 0:		/* found */
 | 
			
		||||
			if (key != KEYC_UNKNOWN)
 | 
			
		||||
				key |= KEYC_ESCAPE;
 | 
			
		||||
			size++; /* include escape */
 | 
			
		||||
			goto complete_key;
 | 
			
		||||
		case -1:	/* not found */
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			if (expired)
 | 
			
		||||
				goto complete_key;
 | 
			
		||||
			goto partial_key;
 | 
			
		||||
		key = tk->key;
 | 
			
		||||
		goto complete_key;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Try to parse a key with an xterm-style modifier. */
 | 
			
		||||
	/* Try with the escape. */
 | 
			
		||||
	switch (tty_keys_next1 (tty, buf, len, &key, &size)) {
 | 
			
		||||
	case 0:		/* found */
 | 
			
		||||
		goto complete_key;
 | 
			
		||||
	case -1:	/* not found */
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		if (expired)
 | 
			
		||||
			goto complete_key;
 | 
			
		||||
		goto partial_key;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Is this an an xterm(1) key? */
 | 
			
		||||
	switch (xterm_keys_find(buf, len, &size, &key)) {
 | 
			
		||||
	case 0:		/* found */
 | 
			
		||||
		goto complete_key;
 | 
			
		||||
	case -1:	/* not found */
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		if (expired)
 | 
			
		||||
			break;
 | 
			
		||||
		goto partial_key;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
first_key:
 | 
			
		||||
	/* Is this a meta key? */
 | 
			
		||||
	if (len >= 2 && buf[0] == '\033') {
 | 
			
		||||
		if (buf[1] != '\033') {
 | 
			
		||||
			key = buf[1] | KEYC_ESCAPE;
 | 
			
		||||
	/*
 | 
			
		||||
	 * If this starts with escape and is at least two keys, it must be
 | 
			
		||||
	 * complete even if the timer has not expired, because otherwise
 | 
			
		||||
	 * tty_keys_next1 would have found a partial key. If just an escape
 | 
			
		||||
	 * alone, it needs to wait for the timer first.
 | 
			
		||||
	 */
 | 
			
		||||
	if (*buf == '\033') {
 | 
			
		||||
		if (len >= 2) {
 | 
			
		||||
			key = (u_char)buf[1] | KEYC_ESCAPE;
 | 
			
		||||
			size = 2;
 | 
			
		||||
			goto complete_key;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		tk = tty_keys_find(tty, buf + 1, len - 1, &size);
 | 
			
		||||
		if (tk != NULL && (!expired || tk->next == NULL)) {
 | 
			
		||||
			size++;	/* include escape */
 | 
			
		||||
			if (tk->next != NULL)
 | 
			
		||||
				goto partial_key;
 | 
			
		||||
			key = tk->key;
 | 
			
		||||
			if (key != KEYC_UNKNOWN)
 | 
			
		||||
				key |= KEYC_ESCAPE;
 | 
			
		||||
			goto complete_key;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Is this valid UTF-8? */
 | 
			
		||||
	if ((more = utf8_open(&ud, (u_char)*buf) == UTF8_MORE)) {
 | 
			
		||||
		size = ud.size;
 | 
			
		||||
		if (len < size) {
 | 
			
		||||
			if (expired)
 | 
			
		||||
				goto discard_key;
 | 
			
		||||
		if (!expired)
 | 
			
		||||
			goto partial_key;
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 1; i < size; i++)
 | 
			
		||||
			more = utf8_append(&ud, (u_char)buf[i]);
 | 
			
		||||
		if (more != UTF8_DONE)
 | 
			
		||||
			goto discard_key;
 | 
			
		||||
 | 
			
		||||
		if (utf8_combine(&ud, &wc) != UTF8_DONE)
 | 
			
		||||
			goto discard_key;
 | 
			
		||||
		key = wc;
 | 
			
		||||
 | 
			
		||||
		log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key);
 | 
			
		||||
		goto complete_key;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* No key found, take first. */
 | 
			
		||||
	/* No longer key found, use the first character. */
 | 
			
		||||
	key = (u_char)*buf;
 | 
			
		||||
	size = 1;
 | 
			
		||||
 | 
			
		||||
@@ -578,7 +623,7 @@ first_key:
 | 
			
		||||
	goto complete_key;
 | 
			
		||||
 | 
			
		||||
partial_key:
 | 
			
		||||
	log_debug("partial key %.*s", (int) len, buf);
 | 
			
		||||
	log_debug("partial key %.*s", (int)len, buf);
 | 
			
		||||
 | 
			
		||||
	/* If timer is going, check for expiration. */
 | 
			
		||||
	if (tty->flags & TTY_TIMER) {
 | 
			
		||||
@@ -640,7 +685,7 @@ discard_key:
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Key timer callback. */
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
tty_keys_callback(__unused int fd, __unused short events, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct tty	*tty = data;
 | 
			
		||||
@@ -655,7 +700,7 @@ tty_keys_callback(__unused int fd, __unused short events, void *data)
 | 
			
		||||
 * Handle mouse key input. Returns 0 for success, -1 for failure, 1 for partial
 | 
			
		||||
 * (probably a mouse sequence but need more data).
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
static int
 | 
			
		||||
tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
 | 
			
		||||
{
 | 
			
		||||
	struct mouse_event	*m = &tty->mouse;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								utf8.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								utf8.c
									
									
									
									
									
								
							@@ -118,6 +118,14 @@ utf8_width(wchar_t wc)
 | 
			
		||||
	width = wcwidth(wc);
 | 
			
		||||
	if (width < 0 || width > 0xff) {
 | 
			
		||||
		log_debug("Unicode %04x, wcwidth() %d", wc, width);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Many platforms have no width for relatively common
 | 
			
		||||
		 * characters (wcwidth() returns -1); assume width 1 in this
 | 
			
		||||
		 * case and hope for the best.
 | 
			
		||||
		 */
 | 
			
		||||
		if (width < 0)
 | 
			
		||||
			return (1);
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	return (width);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,8 @@
 | 
			
		||||
struct screen *window_copy_init(struct window_pane *);
 | 
			
		||||
void	window_copy_free(struct window_pane *);
 | 
			
		||||
void	window_copy_pagedown(struct window_pane *);
 | 
			
		||||
void	window_copy_next_paragraph(struct window_pane *);
 | 
			
		||||
void	window_copy_previous_paragraph(struct window_pane *);
 | 
			
		||||
void	window_copy_resize(struct window_pane *, u_int, u_int);
 | 
			
		||||
void	window_copy_key(struct window_pane *, struct client *, struct session *,
 | 
			
		||||
	    key_code, struct mouse_event *);
 | 
			
		||||
@@ -403,6 +405,44 @@ window_copy_pagedown(struct window_pane *wp)
 | 
			
		||||
	window_copy_redraw_screen(wp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_previous_paragraph(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	u_int				 ox, oy;
 | 
			
		||||
 | 
			
		||||
	oy = screen_hsize(data->backing) + data->cy - data->oy;
 | 
			
		||||
	ox = window_copy_find_length(wp, oy);
 | 
			
		||||
 | 
			
		||||
	while (oy > 0 && window_copy_find_length(wp, oy) == 0)
 | 
			
		||||
		oy--;
 | 
			
		||||
 | 
			
		||||
	while (oy > 0 && window_copy_find_length(wp, oy) > 0)
 | 
			
		||||
		oy--;
 | 
			
		||||
 | 
			
		||||
	window_copy_scroll_to(wp, 0, oy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_next_paragraph(struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = wp->modedata;
 | 
			
		||||
	struct screen			*s = &data->screen;
 | 
			
		||||
	u_int				 maxy, ox, oy;
 | 
			
		||||
 | 
			
		||||
	oy = screen_hsize(data->backing) + data->cy - data->oy;
 | 
			
		||||
	maxy = screen_hsize(data->backing) + screen_size_y(s) - 1;
 | 
			
		||||
 | 
			
		||||
	while (oy < maxy && window_copy_find_length(wp, oy) == 0)
 | 
			
		||||
		oy++;
 | 
			
		||||
 | 
			
		||||
	while (oy < maxy && window_copy_find_length(wp, oy) > 0)
 | 
			
		||||
		oy++;
 | 
			
		||||
 | 
			
		||||
	ox = window_copy_find_length(wp, oy);
 | 
			
		||||
	window_copy_scroll_to(wp, ox, oy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
 | 
			
		||||
{
 | 
			
		||||
@@ -548,6 +588,14 @@ window_copy_key(struct window_pane *wp, struct client *c, struct session *sess,
 | 
			
		||||
		for (; np != 0; np--)
 | 
			
		||||
			window_copy_pagedown(wp);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODEKEYCOPY_PREVIOUSPARAGRAPH:
 | 
			
		||||
		for (; np != 0; np--)
 | 
			
		||||
			window_copy_previous_paragraph(wp);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODEKEYCOPY_NEXTPARAGRAPH:
 | 
			
		||||
		for (; np != 0; np--)
 | 
			
		||||
			window_copy_next_paragraph(wp);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODEKEYCOPY_HALFPAGEUP:
 | 
			
		||||
		n = screen_size_y(s) / 2;
 | 
			
		||||
		for (; np != 0; np--) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user