mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		@@ -206,7 +206,7 @@ args_print(struct args *args)
 | 
				
			|||||||
char *
 | 
					char *
 | 
				
			||||||
args_escape(const char *s)
 | 
					args_escape(const char *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static const char	 quoted[] = " #\"';$";
 | 
						static const char	 quoted[] = " #\"';${}";
 | 
				
			||||||
	char			*escaped, *result;
 | 
						char			*escaped, *result;
 | 
				
			||||||
	int			 flags;
 | 
						int			 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,14 +44,16 @@ const struct cmd_entry cmd_bind_key_entry = {
 | 
				
			|||||||
static enum cmd_retval
 | 
					static enum cmd_retval
 | 
				
			||||||
cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
 | 
					cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct args		*args = self->args;
 | 
						struct args		 *args = self->args;
 | 
				
			||||||
	key_code		 key;
 | 
						key_code		  key;
 | 
				
			||||||
	const char		*tablename;
 | 
						const char		 *tablename;
 | 
				
			||||||
	struct cmd_parse_result	*pr;
 | 
						struct cmd_parse_result	 *pr;
 | 
				
			||||||
 | 
						char			**argv = args->argv;
 | 
				
			||||||
 | 
						int			  argc = args->argc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	key = key_string_lookup_string(args->argv[0]);
 | 
						key = key_string_lookup_string(argv[0]);
 | 
				
			||||||
	if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
 | 
						if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
 | 
				
			||||||
		cmdq_error(item, "unknown key: %s", args->argv[0]);
 | 
							cmdq_error(item, "unknown key: %s", argv[0]);
 | 
				
			||||||
		return (CMD_RETURN_ERROR);
 | 
							return (CMD_RETURN_ERROR);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,7 +64,10 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	else
 | 
						else
 | 
				
			||||||
		tablename = "prefix";
 | 
							tablename = "prefix";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pr = cmd_parse_from_arguments(args->argc - 1, args->argv + 1, NULL);
 | 
						if (argc == 2)
 | 
				
			||||||
 | 
							pr = cmd_parse_from_string(argv[1], NULL);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							pr = cmd_parse_from_arguments(argc - 1, argv + 1, NULL);
 | 
				
			||||||
	switch (pr->status) {
 | 
						switch (pr->status) {
 | 
				
			||||||
	case CMD_PARSE_EMPTY:
 | 
						case CMD_PARSE_EMPTY:
 | 
				
			||||||
		cmdq_error(item, "empty command");
 | 
							cmdq_error(item, "empty command");
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										100
									
								
								cmd-parse.y
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								cmd-parse.y
									
									
									
									
									
								
							@@ -1236,6 +1236,99 @@ yylex_token_tilde(char **buf, size_t *len)
 | 
				
			|||||||
	return (1);
 | 
						return (1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					yylex_token_brace(char **buf, size_t *len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_parse_state	*ps = &parse_state;
 | 
				
			||||||
 | 
						int 			 ch, nesting = 1, escape = 0, quote = '\0';
 | 
				
			||||||
 | 
						int			 lines = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Extract a string up to the matching unquoted '}', including newlines
 | 
				
			||||||
 | 
						 * and handling nested braces.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * To detect the final and intermediate braces which affect the nesting
 | 
				
			||||||
 | 
						 * depth, we scan the input as if it was a tmux config file, and ignore
 | 
				
			||||||
 | 
						 * braces which would be considered quoted, escaped, or in a comment.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * The result is verbatim copy of the input excluding the final brace.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (ch = yylex_getc1(); ch != EOF; ch = yylex_getc1()) {
 | 
				
			||||||
 | 
							yylex_append1(buf, len, ch);
 | 
				
			||||||
 | 
							if (ch == '\n')
 | 
				
			||||||
 | 
								lines++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If the previous character was a backslash (escape is set),
 | 
				
			||||||
 | 
							 * escape anything if unquoted or in double quotes, otherwise
 | 
				
			||||||
 | 
							 * escape only '\n' and '\\'.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (escape &&
 | 
				
			||||||
 | 
							    (quote == '\0' ||
 | 
				
			||||||
 | 
							    quote == '"' ||
 | 
				
			||||||
 | 
							    ch == '\n' ||
 | 
				
			||||||
 | 
							    ch == '\\')) {
 | 
				
			||||||
 | 
								escape = 0;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * The character is not escaped. If it is a backslash, set the
 | 
				
			||||||
 | 
							 * escape flag.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (ch == '\\') {
 | 
				
			||||||
 | 
								escape = 1;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							escape = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* A newline always resets to unquoted. */
 | 
				
			||||||
 | 
							if (ch == '\n') {
 | 
				
			||||||
 | 
								quote = 0;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (quote) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * Inside quotes or comment. Check if this is the
 | 
				
			||||||
 | 
								 * closing quote.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								if (ch == quote && quote != '#')
 | 
				
			||||||
 | 
									quote = 0;
 | 
				
			||||||
 | 
							} else  {
 | 
				
			||||||
 | 
								/* Not inside quotes or comment. */
 | 
				
			||||||
 | 
								switch (ch) {
 | 
				
			||||||
 | 
								case '"':
 | 
				
			||||||
 | 
								case '\'':
 | 
				
			||||||
 | 
								case '#':
 | 
				
			||||||
 | 
									/* Beginning of quote or comment. */
 | 
				
			||||||
 | 
									quote = ch;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case '{':
 | 
				
			||||||
 | 
									nesting++;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case '}':
 | 
				
			||||||
 | 
									nesting--;
 | 
				
			||||||
 | 
									if (nesting == 0) {
 | 
				
			||||||
 | 
										(*len)--; /* remove closing } */
 | 
				
			||||||
 | 
										ps->input->line += lines;
 | 
				
			||||||
 | 
										return (1);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Update line count after error as reporting the opening line
 | 
				
			||||||
 | 
						 * is more useful than EOF.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						yyerror("unterminated brace string");
 | 
				
			||||||
 | 
						ps->input->line += lines;
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *
 | 
					static char *
 | 
				
			||||||
yylex_token(int ch)
 | 
					yylex_token(int ch)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1282,6 +1375,13 @@ yylex_token(int ch)
 | 
				
			|||||||
				goto error;
 | 
									goto error;
 | 
				
			||||||
			goto skip;
 | 
								goto skip;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (ch == '{' && state == NONE) {
 | 
				
			||||||
 | 
								if (!yylex_token_brace(&buf, &len))
 | 
				
			||||||
 | 
									goto error;
 | 
				
			||||||
 | 
								goto skip;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (ch == '}' && state == NONE)
 | 
				
			||||||
 | 
								goto error;  /* unmatched (matched ones were handled) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * ' and " starts or end quotes (and is consumed).
 | 
							 * ' and " starts or end quotes (and is consumed).
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -242,8 +242,8 @@ key_bindings_init(void)
 | 
				
			|||||||
		"bind w choose-tree -Zw",
 | 
							"bind w choose-tree -Zw",
 | 
				
			||||||
		"bind x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
 | 
							"bind x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
 | 
				
			||||||
		"bind z resize-pane -Z",
 | 
							"bind z resize-pane -Z",
 | 
				
			||||||
		"bind { swap-pane -U",
 | 
							"bind '{' swap-pane -U",
 | 
				
			||||||
		"bind } swap-pane -D",
 | 
							"bind '}' swap-pane -D",
 | 
				
			||||||
		"bind '~' show-messages",
 | 
							"bind '~' show-messages",
 | 
				
			||||||
		"bind PPage copy-mode -u",
 | 
							"bind PPage copy-mode -u",
 | 
				
			||||||
		"bind -r Up select-pane -U",
 | 
							"bind -r Up select-pane -U",
 | 
				
			||||||
@@ -347,8 +347,8 @@ key_bindings_init(void)
 | 
				
			|||||||
		"bind -Tcopy-mode M-r send -X middle-line",
 | 
							"bind -Tcopy-mode M-r send -X middle-line",
 | 
				
			||||||
		"bind -Tcopy-mode M-v send -X page-up",
 | 
							"bind -Tcopy-mode M-v send -X page-up",
 | 
				
			||||||
		"bind -Tcopy-mode M-w send -X copy-selection-and-cancel",
 | 
							"bind -Tcopy-mode M-w send -X copy-selection-and-cancel",
 | 
				
			||||||
		"bind -Tcopy-mode M-{ send -X previous-paragraph",
 | 
							"bind -Tcopy-mode 'M-{' send -X previous-paragraph",
 | 
				
			||||||
		"bind -Tcopy-mode M-} send -X next-paragraph",
 | 
							"bind -Tcopy-mode 'M-}' send -X next-paragraph",
 | 
				
			||||||
		"bind -Tcopy-mode M-Up send -X halfpage-up",
 | 
							"bind -Tcopy-mode M-Up send -X halfpage-up",
 | 
				
			||||||
		"bind -Tcopy-mode M-Down send -X halfpage-down",
 | 
							"bind -Tcopy-mode M-Down send -X halfpage-down",
 | 
				
			||||||
		"bind -Tcopy-mode C-Up send -X scroll-up",
 | 
							"bind -Tcopy-mode C-Up send -X scroll-up",
 | 
				
			||||||
@@ -413,8 +413,8 @@ key_bindings_init(void)
 | 
				
			|||||||
		"bind -Tcopy-mode-vi t command-prompt -1p'(jump to forward)' 'send -X jump-to-forward \"%%%\"'",
 | 
							"bind -Tcopy-mode-vi t command-prompt -1p'(jump to forward)' 'send -X jump-to-forward \"%%%\"'",
 | 
				
			||||||
		"bind -Tcopy-mode-vi v send -X rectangle-toggle",
 | 
							"bind -Tcopy-mode-vi v send -X rectangle-toggle",
 | 
				
			||||||
		"bind -Tcopy-mode-vi w send -X next-word",
 | 
							"bind -Tcopy-mode-vi w send -X next-word",
 | 
				
			||||||
		"bind -Tcopy-mode-vi { send -X previous-paragraph",
 | 
							"bind -Tcopy-mode-vi '{' send -X previous-paragraph",
 | 
				
			||||||
		"bind -Tcopy-mode-vi } send -X next-paragraph",
 | 
							"bind -Tcopy-mode-vi '}' send -X next-paragraph",
 | 
				
			||||||
		"bind -Tcopy-mode-vi % send -X next-matching-bracket",
 | 
							"bind -Tcopy-mode-vi % send -X next-matching-bracket",
 | 
				
			||||||
		"bind -Tcopy-mode-vi MouseDown1Pane select-pane",
 | 
							"bind -Tcopy-mode-vi MouseDown1Pane select-pane",
 | 
				
			||||||
		"bind -Tcopy-mode-vi MouseDrag1Pane select-pane\\; send -X begin-selection",
 | 
							"bind -Tcopy-mode-vi MouseDrag1Pane select-pane\\; send -X begin-selection",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								spawn.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								spawn.c
									
									
									
									
									
								
							@@ -159,6 +159,8 @@ spawn_window(struct spawn_context *sc, char **cause)
 | 
				
			|||||||
			xasprintf(cause, "couldn't create window %d", idx);
 | 
								xasprintf(cause, "couldn't create window %d", idx);
 | 
				
			||||||
			return (NULL);
 | 
								return (NULL);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (s->curw == NULL)
 | 
				
			||||||
 | 
								s->curw = sc->wl;
 | 
				
			||||||
		sc->wl->session = s;
 | 
							sc->wl->session = s;
 | 
				
			||||||
		winlink_set_window(sc->wl, w);
 | 
							winlink_set_window(sc->wl, w);
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								tmux.1
									
									
									
									
									
								
							@@ -495,11 +495,13 @@ line (the \e and the newline are completely removed).
 | 
				
			|||||||
This is called line continuation and applies both inside and outside quoted
 | 
					This is called line continuation and applies both inside and outside quoted
 | 
				
			||||||
strings and in comments.
 | 
					strings and in comments.
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
Command arguments may be specified as strings surrounded by either single (')
 | 
					Command arguments may be specified as strings surrounded by single (') quotes,
 | 
				
			||||||
or double quotes (").
 | 
					double quotes (") or braces ({}).
 | 
				
			||||||
.\" "
 | 
					.\" "
 | 
				
			||||||
This is required when the argument contains any special character.
 | 
					This is required when the argument contains any special character.
 | 
				
			||||||
Strings cannot span multiple lines except with line continuation.
 | 
					Single and double quoted strings cannot span multiple lines except with line
 | 
				
			||||||
 | 
					continuation.
 | 
				
			||||||
 | 
					Braces can span multiple lines.
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
Outside of quotes and inside double quotes, these replacements are performed:
 | 
					Outside of quotes and inside double quotes, these replacements are performed:
 | 
				
			||||||
.Bl -dash -offset indent
 | 
					.Bl -dash -offset indent
 | 
				
			||||||
@@ -525,6 +527,34 @@ is removed) and are not treated as having any special meaning - so for example
 | 
				
			|||||||
variable.
 | 
					variable.
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
 | 
					Braces are similar to single quotes in that the text inside is taken literally
 | 
				
			||||||
 | 
					without replacements, but they can span multiple lines.
 | 
				
			||||||
 | 
					They are designed to avoid the need for additional escaping when passing a group
 | 
				
			||||||
 | 
					of
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					or shell commands as an argument (for example to
 | 
				
			||||||
 | 
					.Ic if-shell
 | 
				
			||||||
 | 
					or
 | 
				
			||||||
 | 
					.Ic pipe-pane ) .
 | 
				
			||||||
 | 
					These two examples produce an identical command - note that no escaping is
 | 
				
			||||||
 | 
					needed when using {}:
 | 
				
			||||||
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
 | 
					if-shell true {
 | 
				
			||||||
 | 
					    display -p 'brace-dollar-foo: }$foo'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if-shell true "\en    display -p 'brace-dollar-foo: }\e$foo'\en"
 | 
				
			||||||
 | 
					.Ed
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					Braces may be enclosed inside braces, for example:
 | 
				
			||||||
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
 | 
					bind x if-shell "true" {
 | 
				
			||||||
 | 
					    if-shell "true" {
 | 
				
			||||||
 | 
					         display "true!"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.Ed
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
Environment variables may be set by using the syntax
 | 
					Environment variables may be set by using the syntax
 | 
				
			||||||
.Ql name=value ,
 | 
					.Ql name=value ,
 | 
				
			||||||
for example
 | 
					for example
 | 
				
			||||||
@@ -825,15 +855,16 @@ directly without invoking the shell.
 | 
				
			|||||||
.Op Ar arguments
 | 
					.Op Ar arguments
 | 
				
			||||||
refers to a
 | 
					refers to a
 | 
				
			||||||
.Nm
 | 
					.Nm
 | 
				
			||||||
command, passed with the command and arguments separately, for example:
 | 
					command, either passed with the command and arguments separately, for example:
 | 
				
			||||||
.Bd -literal -offset indent
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
bind-key F1 set-option status off
 | 
					bind-key F1 set-option status off
 | 
				
			||||||
.Ed
 | 
					.Ed
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
Or if using
 | 
					Or passed as a single string argument in
 | 
				
			||||||
.Xr sh 1 :
 | 
					.Pa .tmux.conf ,
 | 
				
			||||||
 | 
					for example:
 | 
				
			||||||
.Bd -literal -offset indent
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
$ tmux bind-key F1 set-option status off
 | 
					bind-key F1 { set-option status off }
 | 
				
			||||||
.Ed
 | 
					.Ed
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
Example
 | 
					Example
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user