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:
		@@ -33,8 +33,8 @@ const struct cmd_entry cmd_bind_key_entry = {
 | 
			
		||||
	.name = "bind-key",
 | 
			
		||||
	.alias = "bind",
 | 
			
		||||
 | 
			
		||||
	.args = { "cnrT:", 2, -1 },
 | 
			
		||||
	.usage = "[-cnr] [-T key-table] key "
 | 
			
		||||
	.args = { "cnrN:T:", 2, -1 },
 | 
			
		||||
	.usage = "[-cnr] [-T key-table] [-N note] key "
 | 
			
		||||
	         "command [arguments]",
 | 
			
		||||
 | 
			
		||||
	.flags = CMD_AFTERHOOK,
 | 
			
		||||
@@ -46,10 +46,10 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
{
 | 
			
		||||
	struct args		 *args = self->args;
 | 
			
		||||
	key_code		  key;
 | 
			
		||||
	const char		 *tablename;
 | 
			
		||||
	const char		 *tablename, *note;
 | 
			
		||||
	struct cmd_parse_result	 *pr;
 | 
			
		||||
	char			**argv = args->argv;
 | 
			
		||||
	int			  argc = args->argc;
 | 
			
		||||
	int			  argc = args->argc, repeat;
 | 
			
		||||
 | 
			
		||||
	key = key_string_lookup_string(argv[0]);
 | 
			
		||||
	if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
 | 
			
		||||
@@ -63,6 +63,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
		tablename = "root";
 | 
			
		||||
	else
 | 
			
		||||
		tablename = "prefix";
 | 
			
		||||
	repeat = args_has(args, 'r');
 | 
			
		||||
 | 
			
		||||
	if (argc == 2)
 | 
			
		||||
		pr = cmd_parse_from_string(argv[1], NULL);
 | 
			
		||||
@@ -79,6 +80,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
	case CMD_PARSE_SUCCESS:
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	key_bindings_add(tablename, key, args_has(args, 'r'), pr->cmdlist);
 | 
			
		||||
	note = args_get(args, 'N');
 | 
			
		||||
	key_bindings_add(tablename, key, note, repeat, pr->cmdlist);
 | 
			
		||||
	return (CMD_RETURN_NORMAL);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,8 @@ const struct cmd_entry cmd_command_prompt_entry = {
 | 
			
		||||
	.name = "command-prompt",
 | 
			
		||||
	.alias = NULL,
 | 
			
		||||
 | 
			
		||||
	.args = { "1iI:Np:t:", 0, 1 },
 | 
			
		||||
	.usage = "[-1Ni] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
 | 
			
		||||
	.args = { "1kiI:Np:t:", 0, 1 },
 | 
			
		||||
	.usage = "[-1kiN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
 | 
			
		||||
		 "[template]",
 | 
			
		||||
 | 
			
		||||
	.flags = 0,
 | 
			
		||||
@@ -122,6 +122,8 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
		cdata->flags |= PROMPT_NUMERIC;
 | 
			
		||||
	else if (args_has(args, 'i'))
 | 
			
		||||
		cdata->flags |= PROMPT_INCREMENTAL;
 | 
			
		||||
	else if (args_has(args, 'k'))
 | 
			
		||||
		cdata->flags |= PROMPT_KEY;
 | 
			
		||||
	status_prompt_set(c, prompt, input, cmd_command_prompt_callback,
 | 
			
		||||
	    cmd_command_prompt_free, cdata, cdata->flags);
 | 
			
		||||
	free(prompt);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										150
									
								
								cmd-list-keys.c
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								cmd-list-keys.c
									
									
									
									
									
								
							@@ -36,8 +36,8 @@ const struct cmd_entry cmd_list_keys_entry = {
 | 
			
		||||
	.name = "list-keys",
 | 
			
		||||
	.alias = "lsk",
 | 
			
		||||
 | 
			
		||||
	.args = { "T:", 0, 0 },
 | 
			
		||||
	.usage = "[-T key-table]",
 | 
			
		||||
	.args = { "1NP:T:", 0, 1 },
 | 
			
		||||
	.usage = "[-1N] [-P prefix-string] [-T key-table] [key]",
 | 
			
		||||
 | 
			
		||||
	.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
 | 
			
		||||
	.exec = cmd_list_keys_exec
 | 
			
		||||
@@ -54,6 +54,88 @@ const struct cmd_entry cmd_list_commands_entry = {
 | 
			
		||||
	.exec = cmd_list_keys_exec
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static u_int
 | 
			
		||||
cmd_list_keys_get_width(const char *tablename, key_code only)
 | 
			
		||||
{
 | 
			
		||||
	struct key_table	*table;
 | 
			
		||||
	struct key_binding	*bd;
 | 
			
		||||
	u_int			 width, keywidth = 0;
 | 
			
		||||
 | 
			
		||||
	table = key_bindings_get_table(tablename, 0);
 | 
			
		||||
	if (table == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	bd = key_bindings_first(table);
 | 
			
		||||
	while (bd != NULL) {
 | 
			
		||||
		if ((only != KEYC_UNKNOWN && bd->key != only) ||
 | 
			
		||||
		    KEYC_IS_MOUSE(bd->key) ||
 | 
			
		||||
		    bd->note == NULL) {
 | 
			
		||||
			bd = key_bindings_next(table, bd);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		width = utf8_cstrwidth(key_string_lookup_key(bd->key));
 | 
			
		||||
		if (width > keywidth)
 | 
			
		||||
			keywidth = width;
 | 
			
		||||
 | 
			
		||||
		bd = key_bindings_next(table, bd);
 | 
			
		||||
	}
 | 
			
		||||
	return (keywidth);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args,
 | 
			
		||||
    const char *tablename, u_int keywidth, key_code only, const char *prefix)
 | 
			
		||||
{
 | 
			
		||||
	struct client		*c = cmd_find_client(item, NULL, 1);
 | 
			
		||||
	struct key_table	*table;
 | 
			
		||||
	struct key_binding	*bd;
 | 
			
		||||
	const char		*key;
 | 
			
		||||
	char			*tmp;
 | 
			
		||||
	int	                 found = 0;
 | 
			
		||||
 | 
			
		||||
	table = key_bindings_get_table(tablename, 0);
 | 
			
		||||
	if (table == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	bd = key_bindings_first(table);
 | 
			
		||||
	while (bd != NULL) {
 | 
			
		||||
		if ((only != KEYC_UNKNOWN && bd->key != only) ||
 | 
			
		||||
		    KEYC_IS_MOUSE(bd->key) ||
 | 
			
		||||
		    bd->note == NULL) {
 | 
			
		||||
			bd = key_bindings_next(table, bd);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		found = 1;
 | 
			
		||||
		key = key_string_lookup_key(bd->key);
 | 
			
		||||
 | 
			
		||||
		tmp = utf8_padcstr(key, keywidth + 1);
 | 
			
		||||
		if (args_has(args, '1') && c != NULL)
 | 
			
		||||
			status_message_set(c, "%s%s%s", prefix, tmp, bd->note);
 | 
			
		||||
		else
 | 
			
		||||
			cmdq_print(item, "%s%s%s", prefix, tmp, bd->note);
 | 
			
		||||
		free(tmp);
 | 
			
		||||
 | 
			
		||||
		if (args_has(args, '1'))
 | 
			
		||||
			break;
 | 
			
		||||
		bd = key_bindings_next(table, bd);
 | 
			
		||||
	}
 | 
			
		||||
	return (found);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
cmd_list_keys_get_prefix(struct args *args, key_code *prefix)
 | 
			
		||||
{
 | 
			
		||||
	char	*s;
 | 
			
		||||
 | 
			
		||||
	*prefix = options_get_number(global_s_options, "prefix");
 | 
			
		||||
	if (!args_has(args, 'P')) {
 | 
			
		||||
		if (*prefix != KEYC_NONE)
 | 
			
		||||
			xasprintf(&s, "%s ", key_string_lookup_key(*prefix));
 | 
			
		||||
		else
 | 
			
		||||
			s = xstrdup("");
 | 
			
		||||
	} else
 | 
			
		||||
		s = xstrdup(args_get(args, 'P'));
 | 
			
		||||
	return (s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static enum cmd_retval
 | 
			
		||||
cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
{
 | 
			
		||||
@@ -61,19 +143,63 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
	struct key_table	*table;
 | 
			
		||||
	struct key_binding	*bd;
 | 
			
		||||
	const char		*tablename, *r;
 | 
			
		||||
	char			*key, *cp, *tmp;
 | 
			
		||||
	int			 repeat, width, tablewidth, keywidth;
 | 
			
		||||
	char			*key, *cp, *tmp, *start, *empty;
 | 
			
		||||
	key_code		 prefix, only = KEYC_UNKNOWN;
 | 
			
		||||
	int			 repeat, width, tablewidth, keywidth, found = 0;
 | 
			
		||||
	size_t			 tmpsize, tmpused, cplen;
 | 
			
		||||
 | 
			
		||||
	if (self->entry == &cmd_list_commands_entry)
 | 
			
		||||
		return (cmd_list_keys_commands(self, item));
 | 
			
		||||
 | 
			
		||||
	if (args->argc != 0) {
 | 
			
		||||
		only = key_string_lookup_string(args->argv[0]);
 | 
			
		||||
		if (only == KEYC_UNKNOWN) {
 | 
			
		||||
			cmdq_error(item, "invalid key: %s", args->argv[0]);
 | 
			
		||||
			return (CMD_RETURN_ERROR);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tablename = args_get(args, 'T');
 | 
			
		||||
	if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
 | 
			
		||||
		cmdq_error(item, "table %s doesn't exist", tablename);
 | 
			
		||||
		return (CMD_RETURN_ERROR);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 'N')) {
 | 
			
		||||
		if (tablename == NULL) {
 | 
			
		||||
			start = cmd_list_keys_get_prefix(args, &prefix);
 | 
			
		||||
			keywidth = cmd_list_keys_get_width("root", only);
 | 
			
		||||
			if (prefix != KEYC_NONE) {
 | 
			
		||||
				width = cmd_list_keys_get_width("prefix", only);
 | 
			
		||||
				if (width == 0)
 | 
			
		||||
					prefix = KEYC_NONE;
 | 
			
		||||
				else if (width > keywidth)
 | 
			
		||||
					keywidth = width;
 | 
			
		||||
			}
 | 
			
		||||
			empty = utf8_padcstr("", utf8_cstrwidth(start));
 | 
			
		||||
 | 
			
		||||
			found = cmd_list_keys_print_notes(item, args, "root",
 | 
			
		||||
			    keywidth, only, empty);
 | 
			
		||||
			if (prefix != KEYC_NONE) {
 | 
			
		||||
				if (cmd_list_keys_print_notes(item, args,
 | 
			
		||||
				    "prefix", keywidth, only, start))
 | 
			
		||||
					found = 1;
 | 
			
		||||
			}
 | 
			
		||||
			free(empty);
 | 
			
		||||
		} else {
 | 
			
		||||
			if (args_has(args, 'P'))
 | 
			
		||||
				start = xstrdup(args_get(args, 'P'));
 | 
			
		||||
			else
 | 
			
		||||
				start = xstrdup("");
 | 
			
		||||
			keywidth = cmd_list_keys_get_width(tablename, only);
 | 
			
		||||
			found = cmd_list_keys_print_notes(item, args, tablename,
 | 
			
		||||
			    keywidth, only, start);
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		free(start);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repeat = 0;
 | 
			
		||||
	tablewidth = keywidth = 0;
 | 
			
		||||
	table = key_bindings_first_table ();
 | 
			
		||||
@@ -84,6 +210,10 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
		}
 | 
			
		||||
		bd = key_bindings_first(table);
 | 
			
		||||
		while (bd != NULL) {
 | 
			
		||||
			if (only != KEYC_UNKNOWN && bd->key != only) {
 | 
			
		||||
				bd = key_bindings_next(table, bd);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			key = args_escape(key_string_lookup_key(bd->key));
 | 
			
		||||
 | 
			
		||||
			if (bd->flags & KEY_BINDING_REPEAT)
 | 
			
		||||
@@ -113,6 +243,11 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
		}
 | 
			
		||||
		bd = key_bindings_first(table);
 | 
			
		||||
		while (bd != NULL) {
 | 
			
		||||
			if (only != KEYC_UNKNOWN && bd->key != only) {
 | 
			
		||||
				bd = key_bindings_next(table, bd);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			found = 1;
 | 
			
		||||
			key = args_escape(key_string_lookup_key(bd->key));
 | 
			
		||||
 | 
			
		||||
			if (!repeat)
 | 
			
		||||
@@ -162,13 +297,18 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
 | 
			
		||||
	free(tmp);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	if (only != KEYC_UNKNOWN && !found) {
 | 
			
		||||
		cmdq_error(item, "unknown key: %s", args->argv[0]);
 | 
			
		||||
		return (CMD_RETURN_ERROR);
 | 
			
		||||
	}
 | 
			
		||||
	return (CMD_RETURN_NORMAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static enum cmd_retval
 | 
			
		||||
cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
{
 | 
			
		||||
	struct args		*args = self->args;
 | 
			
		||||
	struct args		 *args = self->args;
 | 
			
		||||
	const struct cmd_entry	**entryp;
 | 
			
		||||
	const struct cmd_entry	 *entry;
 | 
			
		||||
	struct format_tree	 *ft;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								cmd-parse.y
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								cmd-parse.y
									
									
									
									
									
								
							@@ -133,7 +133,12 @@ statements	: statement '\n'
 | 
			
		||||
			free($2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
statement	: condition
 | 
			
		||||
statement	: /* empty */
 | 
			
		||||
		{
 | 
			
		||||
			$$ = xmalloc (sizeof *$$);
 | 
			
		||||
			TAILQ_INIT($$);
 | 
			
		||||
		}
 | 
			
		||||
		| condition
 | 
			
		||||
		{
 | 
			
		||||
			struct cmd_parse_state	*ps = &parse_state;
 | 
			
		||||
 | 
			
		||||
@@ -144,11 +149,6 @@ statement	: condition
 | 
			
		||||
				cmd_parse_free_commands($1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		| assignment
 | 
			
		||||
		{
 | 
			
		||||
			$$ = xmalloc (sizeof *$$);
 | 
			
		||||
			TAILQ_INIT($$);
 | 
			
		||||
		}
 | 
			
		||||
		| commands
 | 
			
		||||
		{
 | 
			
		||||
			struct cmd_parse_state	*ps = &parse_state;
 | 
			
		||||
@@ -194,8 +194,10 @@ expanded	: format
 | 
			
		||||
			free($1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
assignment	: /* empty */
 | 
			
		||||
		| EQUALS
 | 
			
		||||
optional_assignment	: /* empty */
 | 
			
		||||
			| assignment
 | 
			
		||||
 | 
			
		||||
assignment	: EQUALS
 | 
			
		||||
		{
 | 
			
		||||
			struct cmd_parse_state	*ps = &parse_state;
 | 
			
		||||
			int			 flags = ps->input->flags;
 | 
			
		||||
@@ -372,7 +374,15 @@ commands	: command
 | 
			
		||||
			$$ = $1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
command		: assignment TOKEN
 | 
			
		||||
command		: assignment
 | 
			
		||||
		{
 | 
			
		||||
			struct cmd_parse_state	*ps = &parse_state;
 | 
			
		||||
 | 
			
		||||
			$$ = xcalloc(1, sizeof *$$);
 | 
			
		||||
			$$->name = NULL;
 | 
			
		||||
			$$->line = ps->input->line;
 | 
			
		||||
		}
 | 
			
		||||
		| optional_assignment TOKEN
 | 
			
		||||
		{
 | 
			
		||||
			struct cmd_parse_state	*ps = &parse_state;
 | 
			
		||||
 | 
			
		||||
@@ -381,7 +391,7 @@ command		: assignment TOKEN
 | 
			
		||||
			$$->line = ps->input->line;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		| assignment TOKEN arguments
 | 
			
		||||
		| optional_assignment TOKEN arguments
 | 
			
		||||
		{
 | 
			
		||||
			struct cmd_parse_state	*ps = &parse_state;
 | 
			
		||||
 | 
			
		||||
@@ -631,6 +641,8 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
 | 
			
		||||
	 * command list.
 | 
			
		||||
	 */
 | 
			
		||||
	TAILQ_FOREACH_SAFE(cmd, cmds, entry, next) {
 | 
			
		||||
		if (cmd->name == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		alias = cmd_get_alias(cmd->name);
 | 
			
		||||
		if (alias == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
@@ -676,6 +688,8 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
 | 
			
		||||
	 */
 | 
			
		||||
	result = cmd_list_new();
 | 
			
		||||
	TAILQ_FOREACH(cmd, cmds, entry) {
 | 
			
		||||
		if (cmd->name == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		log_debug("%s: %u %s", __func__, cmd->line, cmd->name);
 | 
			
		||||
		cmd_log_argv(cmd->argc, cmd->argv, __func__);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										168
									
								
								key-bindings.c
									
									
									
									
									
								
							
							
						
						
									
										168
									
								
								key-bindings.c
									
									
									
									
									
								
							@@ -90,6 +90,7 @@ key_bindings_free(struct key_table *table, struct key_binding *bd)
 | 
			
		||||
{
 | 
			
		||||
	RB_REMOVE(key_bindings, &table->key_bindings, bd);
 | 
			
		||||
	cmd_list_free(bd->cmdlist);
 | 
			
		||||
	free((void *)bd->note);
 | 
			
		||||
	free(bd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -163,7 +164,7 @@ key_bindings_next(__unused struct key_table *table, struct key_binding *bd)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
key_bindings_add(const char *name, key_code key, int repeat,
 | 
			
		||||
key_bindings_add(const char *name, key_code key, const char *note, int repeat,
 | 
			
		||||
    struct cmd_list *cmdlist)
 | 
			
		||||
{
 | 
			
		||||
	struct key_table	*table;
 | 
			
		||||
@@ -177,6 +178,8 @@ key_bindings_add(const char *name, key_code key, int repeat,
 | 
			
		||||
 | 
			
		||||
	bd = xcalloc(1, sizeof *bd);
 | 
			
		||||
	bd->key = key;
 | 
			
		||||
	if (note != NULL)
 | 
			
		||||
		bd->note = xstrdup(note);
 | 
			
		||||
	RB_INSERT(key_bindings, &table->key_bindings, bd);
 | 
			
		||||
 | 
			
		||||
	if (repeat)
 | 
			
		||||
@@ -226,87 +229,88 @@ void
 | 
			
		||||
key_bindings_init(void)
 | 
			
		||||
{
 | 
			
		||||
	static const char *defaults[] = {
 | 
			
		||||
		"bind C-b send-prefix",
 | 
			
		||||
		"bind C-o rotate-window",
 | 
			
		||||
		"bind C-z suspend-client",
 | 
			
		||||
		"bind Space next-layout",
 | 
			
		||||
		"bind ! break-pane",
 | 
			
		||||
		"bind '\"' split-window",
 | 
			
		||||
		"bind '#' list-buffers",
 | 
			
		||||
		"bind '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
 | 
			
		||||
		"bind % split-window -h",
 | 
			
		||||
		"bind & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
 | 
			
		||||
		"bind \"'\" command-prompt -pindex \"select-window -t ':%%'\"",
 | 
			
		||||
		"bind ( switch-client -p",
 | 
			
		||||
		"bind ) switch-client -n",
 | 
			
		||||
		"bind , command-prompt -I'#W' \"rename-window -- '%%'\"",
 | 
			
		||||
		"bind - delete-buffer",
 | 
			
		||||
		"bind . command-prompt \"move-window -t '%%'\"",
 | 
			
		||||
		"bind 0 select-window -t:=0",
 | 
			
		||||
		"bind 1 select-window -t:=1",
 | 
			
		||||
		"bind 2 select-window -t:=2",
 | 
			
		||||
		"bind 3 select-window -t:=3",
 | 
			
		||||
		"bind 4 select-window -t:=4",
 | 
			
		||||
		"bind 5 select-window -t:=5",
 | 
			
		||||
		"bind 6 select-window -t:=6",
 | 
			
		||||
		"bind 7 select-window -t:=7",
 | 
			
		||||
		"bind 8 select-window -t:=8",
 | 
			
		||||
		"bind 9 select-window -t:=9",
 | 
			
		||||
		"bind : command-prompt",
 | 
			
		||||
		"bind \\; last-pane",
 | 
			
		||||
		"bind = choose-buffer -Z",
 | 
			
		||||
		"bind ? list-keys",
 | 
			
		||||
		"bind D choose-client -Z",
 | 
			
		||||
		"bind E select-layout -E",
 | 
			
		||||
		"bind L switch-client -l",
 | 
			
		||||
		"bind M select-pane -M",
 | 
			
		||||
		"bind [ copy-mode",
 | 
			
		||||
		"bind ] paste-buffer",
 | 
			
		||||
		"bind c new-window",
 | 
			
		||||
		"bind d detach-client",
 | 
			
		||||
		"bind f command-prompt \"find-window -Z -- '%%'\"",
 | 
			
		||||
		"bind i display-message",
 | 
			
		||||
		"bind l last-window",
 | 
			
		||||
		"bind m select-pane -m",
 | 
			
		||||
		"bind n next-window",
 | 
			
		||||
		"bind o select-pane -t:.+",
 | 
			
		||||
		"bind p previous-window",
 | 
			
		||||
		"bind q display-panes",
 | 
			
		||||
		"bind r refresh-client",
 | 
			
		||||
		"bind s choose-tree -Zs",
 | 
			
		||||
		"bind t clock-mode",
 | 
			
		||||
		"bind w choose-tree -Zw",
 | 
			
		||||
		"bind x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
 | 
			
		||||
		"bind z resize-pane -Z",
 | 
			
		||||
		"bind '{' swap-pane -U",
 | 
			
		||||
		"bind '}' swap-pane -D",
 | 
			
		||||
		"bind '~' show-messages",
 | 
			
		||||
		"bind PPage copy-mode -u",
 | 
			
		||||
		"bind -r Up select-pane -U",
 | 
			
		||||
		"bind -r Down select-pane -D",
 | 
			
		||||
		"bind -r Left select-pane -L",
 | 
			
		||||
		"bind -r Right select-pane -R",
 | 
			
		||||
		"bind M-1 select-layout even-horizontal",
 | 
			
		||||
		"bind M-2 select-layout even-vertical",
 | 
			
		||||
		"bind M-3 select-layout main-horizontal",
 | 
			
		||||
		"bind M-4 select-layout main-vertical",
 | 
			
		||||
		"bind M-5 select-layout tiled",
 | 
			
		||||
		"bind M-n next-window -a",
 | 
			
		||||
		"bind M-o rotate-window -D",
 | 
			
		||||
		"bind M-p previous-window -a",
 | 
			
		||||
		"bind -r S-Up refresh-client -U 10",
 | 
			
		||||
		"bind -r S-Down refresh-client -D 10",
 | 
			
		||||
		"bind -r S-Left refresh-client -L 10",
 | 
			
		||||
		"bind -r S-Right refresh-client -R 10",
 | 
			
		||||
		"bind -r DC refresh-client -c",
 | 
			
		||||
		"bind -r M-Up resize-pane -U 5",
 | 
			
		||||
		"bind -r M-Down resize-pane -D 5",
 | 
			
		||||
		"bind -r M-Left resize-pane -L 5",
 | 
			
		||||
		"bind -r M-Right resize-pane -R 5",
 | 
			
		||||
		"bind -r C-Up resize-pane -U",
 | 
			
		||||
		"bind -r C-Down resize-pane -D",
 | 
			
		||||
		"bind -r C-Left resize-pane -L",
 | 
			
		||||
		"bind -r C-Right resize-pane -R",
 | 
			
		||||
		"bind -N 'Send the prefix key' C-b send-prefix",
 | 
			
		||||
		"bind -N 'Rotate through the panes' C-o rotate-window",
 | 
			
		||||
		"bind -N 'Suspend the current client' C-z suspend-client",
 | 
			
		||||
		"bind -N 'Select next layout' Space next-layout",
 | 
			
		||||
		"bind -N 'Break pane to a new window' ! break-pane",
 | 
			
		||||
		"bind -N 'Split window vertically' '\"' split-window",
 | 
			
		||||
		"bind -N 'List all paste buffers' '#' list-buffers",
 | 
			
		||||
		"bind -N 'Rename current session' '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
 | 
			
		||||
		"bind -N 'Split window horizontally' % split-window -h",
 | 
			
		||||
		"bind -N 'Kill current window' & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
 | 
			
		||||
		"bind -N 'Prompt for window index to select' \"'\" command-prompt -pindex \"select-window -t ':%%'\"",
 | 
			
		||||
		"bind -N 'Switch to previous client' ( switch-client -p",
 | 
			
		||||
		"bind -N 'Switch to next client' ) switch-client -n",
 | 
			
		||||
		"bind -N 'Rename current window' , command-prompt -I'#W' \"rename-window -- '%%'\"",
 | 
			
		||||
		"bind -N 'Delete the most recent paste buffer' - delete-buffer",
 | 
			
		||||
		"bind -N 'Move the current window' . command-prompt \"move-window -t '%%'\"",
 | 
			
		||||
		"bind -N 'Describe key binding' '/' command-prompt -kpkey 'list-keys -1N \"%%%\"'",
 | 
			
		||||
		"bind -N 'Select window 0' 0 select-window -t:=0",
 | 
			
		||||
		"bind -N 'Select window 1' 1 select-window -t:=1",
 | 
			
		||||
		"bind -N 'Select window 2' 2 select-window -t:=2",
 | 
			
		||||
		"bind -N 'Select window 3' 3 select-window -t:=3",
 | 
			
		||||
		"bind -N 'Select window 4' 4 select-window -t:=4",
 | 
			
		||||
		"bind -N 'Select window 5' 5 select-window -t:=5",
 | 
			
		||||
		"bind -N 'Select window 6' 6 select-window -t:=6",
 | 
			
		||||
		"bind -N 'Select window 7' 7 select-window -t:=7",
 | 
			
		||||
		"bind -N 'Select window 8' 8 select-window -t:=8",
 | 
			
		||||
		"bind -N 'Select window 9' 9 select-window -t:=9",
 | 
			
		||||
		"bind -N 'Prompt for a command' : command-prompt",
 | 
			
		||||
		"bind -N 'Move to the previously active pane' \\; last-pane",
 | 
			
		||||
		"bind -N 'Choose a paste buffer from a list' = choose-buffer -Z",
 | 
			
		||||
		"bind -N 'List key bindings' ? list-keys -N",
 | 
			
		||||
		"bind -N 'Choose a client from a list' D choose-client -Z",
 | 
			
		||||
		"bind -N 'Spread panes out evenly' E select-layout -E",
 | 
			
		||||
		"bind -N 'Switch to the last client' L switch-client -l",
 | 
			
		||||
		"bind -N 'Clear the marked pane' M select-pane -M",
 | 
			
		||||
		"bind -N 'Enter copy mode' [ copy-mode",
 | 
			
		||||
		"bind -N 'Paste the most recent paste buffer' ] paste-buffer",
 | 
			
		||||
		"bind -N 'Create a new window' c new-window",
 | 
			
		||||
		"bind -N 'Detach the current client' d detach-client",
 | 
			
		||||
		"bind -N 'Search for a pane' f command-prompt \"find-window -Z -- '%%'\"",
 | 
			
		||||
		"bind -N 'Display window information' i display-message",
 | 
			
		||||
		"bind -N 'Select the previously current window' l last-window",
 | 
			
		||||
		"bind -N 'Toggle the marked pane' m select-pane -m",
 | 
			
		||||
		"bind -N 'Select the next window' n next-window",
 | 
			
		||||
		"bind -N 'Select the next pane' o select-pane -t:.+",
 | 
			
		||||
		"bind -N 'Select the previous pane' p previous-window",
 | 
			
		||||
		"bind -N 'Display pane numbers' q display-panes",
 | 
			
		||||
		"bind -N 'Redraw the current client' r refresh-client",
 | 
			
		||||
		"bind -N 'Choose a session from a list' s choose-tree -Zs",
 | 
			
		||||
		"bind -N 'Show a clock' t clock-mode",
 | 
			
		||||
		"bind -N 'Choose a window from a list' w choose-tree -Zw",
 | 
			
		||||
		"bind -N 'Kill the active pane' x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
 | 
			
		||||
		"bind -N 'Zoom the active pane' z resize-pane -Z",
 | 
			
		||||
		"bind -N 'Swap the active pane with the pane above' '{' swap-pane -U",
 | 
			
		||||
		"bind -N 'Swap the active pane with the pane below' '}' swap-pane -D",
 | 
			
		||||
		"bind -N 'Show messages' '~' show-messages",
 | 
			
		||||
		"bind -N 'Enter copy mode and scroll up' PPage copy-mode -u",
 | 
			
		||||
		"bind -N 'Select the pane above the active pane' -r Up select-pane -U",
 | 
			
		||||
		"bind -N 'Select the pane below the active pane' -r Down select-pane -D",
 | 
			
		||||
		"bind -N 'Select the pane to the left of the active pane' -r Left select-pane -L",
 | 
			
		||||
		"bind -N 'Select the pane to the right of the active pane' -r Right select-pane -R",
 | 
			
		||||
		"bind -N 'Set the even-horizontal layout' M-1 select-layout even-horizontal",
 | 
			
		||||
		"bind -N 'Set the even-vertical layout' M-2 select-layout even-vertical",
 | 
			
		||||
		"bind -N 'Set the main-horizontal layout' M-3 select-layout main-horizontal",
 | 
			
		||||
		"bind -N 'Set the main-vertical layout' M-4 select-layout main-vertical",
 | 
			
		||||
		"bind -N 'Select the tiled layout' M-5 select-layout tiled",
 | 
			
		||||
		"bind -N 'Select the next window with an alert' M-n next-window -a",
 | 
			
		||||
		"bind -N 'Rotate through the panes in reverse' M-o rotate-window -D",
 | 
			
		||||
		"bind -N 'Select the previous window with an alert' M-p previous-window -a",
 | 
			
		||||
		"bind -N 'Move the visible part of the window up' -r S-Up refresh-client -U 10",
 | 
			
		||||
		"bind -N 'Move the visible part of the window down' -r S-Down refresh-client -D 10",
 | 
			
		||||
		"bind -N 'Move the visible part of the window left' -r S-Left refresh-client -L 10",
 | 
			
		||||
		"bind -N 'Move the visible part of the window right' -r S-Right refresh-client -R 10",
 | 
			
		||||
		"bind -N 'Reset so the visible part of the window follows the cursor' -r DC refresh-client -c",
 | 
			
		||||
		"bind -N 'Resize the pane up by 5' -r M-Up resize-pane -U 5",
 | 
			
		||||
		"bind -N 'Resize the pane down by 5' -r M-Down resize-pane -D 5",
 | 
			
		||||
		"bind -N 'Resize the pane left by 5' -r M-Left resize-pane -L 5",
 | 
			
		||||
		"bind -N 'Resize the pane right by 5' -r M-Right resize-pane -R 5",
 | 
			
		||||
		"bind -N 'Resize the pane up' -r C-Up resize-pane -U",
 | 
			
		||||
		"bind -N 'Resize the pane down' -r C-Down resize-pane -D",
 | 
			
		||||
		"bind -N 'Resize the pane left' -r C-Left resize-pane -L",
 | 
			
		||||
		"bind -N 'Resize the pane right' -r C-Right resize-pane -R",
 | 
			
		||||
 | 
			
		||||
		"bind -n MouseDown1Pane select-pane -t=\\; send-keys -M",
 | 
			
		||||
		"bind -n MouseDrag1Border resize-pane -M",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								status.c
									
									
									
									
									
								
							@@ -915,11 +915,17 @@ status_prompt_key(struct client *c, key_code key)
 | 
			
		||||
{
 | 
			
		||||
	struct options		*oo = c->session->options;
 | 
			
		||||
	char			*s, *cp, word[64], prefix = '=';
 | 
			
		||||
	const char		*histstr, *ws = NULL;
 | 
			
		||||
	const char		*histstr, *ws = NULL, *keystring;
 | 
			
		||||
	size_t			 size, n, off, idx, used;
 | 
			
		||||
	struct utf8_data	 tmp, *first, *last, *ud;
 | 
			
		||||
	int			 keys;
 | 
			
		||||
 | 
			
		||||
	if (c->prompt_flags & PROMPT_KEY) {
 | 
			
		||||
		keystring = key_string_lookup_key(key);
 | 
			
		||||
		c->prompt_inputcb(c, c->prompt_data, keystring, 1);
 | 
			
		||||
		status_prompt_clear(c);
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
	size = utf8_strlen(c->prompt_buffer);
 | 
			
		||||
 | 
			
		||||
	if (c->prompt_flags & PROMPT_NUMERIC) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								tmux.1
									
									
									
									
									
								
							@@ -556,7 +556,7 @@ Braces may be enclosed inside braces, for example:
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
bind x if-shell "true" {
 | 
			
		||||
    if-shell "true" {
 | 
			
		||||
         display "true!"
 | 
			
		||||
        display "true!"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
.Ed
 | 
			
		||||
@@ -1292,6 +1292,17 @@ shows the parsed commands and line numbers if possible.
 | 
			
		||||
Start the
 | 
			
		||||
.Nm
 | 
			
		||||
server, if not already running, without creating any sessions.
 | 
			
		||||
.Pp
 | 
			
		||||
Note that as by default the
 | 
			
		||||
.Nm
 | 
			
		||||
server will exit with no sessions, this is only useful if a session is created in
 | 
			
		||||
.Pa ~/.tmux.conf ,
 | 
			
		||||
.Ic exit-empty
 | 
			
		||||
is turned off, or another command is run as part of the same command sequence.
 | 
			
		||||
For example:
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
$ tmux start \\; show -g
 | 
			
		||||
.Ed
 | 
			
		||||
.It Xo Ic suspend-client
 | 
			
		||||
.Op Fl t Ar target-client
 | 
			
		||||
.Xc
 | 
			
		||||
@@ -1340,7 +1351,8 @@ is used,
 | 
			
		||||
option will not be applied.
 | 
			
		||||
.Pp
 | 
			
		||||
.Fl T
 | 
			
		||||
sets the client's key table; the next key from the client will be interpreted from
 | 
			
		||||
sets the client's key table; the next key from the client will be interpreted
 | 
			
		||||
from
 | 
			
		||||
.Ar key-table .
 | 
			
		||||
This may be used to configure multiple prefix keys, or to bind commands to
 | 
			
		||||
sequences of keys.
 | 
			
		||||
@@ -2618,6 +2630,7 @@ Commands related to key bindings are as follows:
 | 
			
		||||
.Bl -tag -width Ds
 | 
			
		||||
.It Xo Ic bind-key
 | 
			
		||||
.Op Fl nr
 | 
			
		||||
.Op Fl N Ar note
 | 
			
		||||
.Op Fl T Ar key-table
 | 
			
		||||
.Ar key Ar command Op Ar arguments
 | 
			
		||||
.Xc
 | 
			
		||||
@@ -2665,22 +2678,46 @@ The
 | 
			
		||||
flag indicates this key may repeat, see the
 | 
			
		||||
.Ic repeat-time
 | 
			
		||||
option.
 | 
			
		||||
.Fl N
 | 
			
		||||
attaches a note to the key (shown with
 | 
			
		||||
.Ic list-keys
 | 
			
		||||
.Fl N ) .
 | 
			
		||||
.Pp
 | 
			
		||||
To view the default bindings and possible commands, see the
 | 
			
		||||
.Ic list-keys
 | 
			
		||||
command.
 | 
			
		||||
.It Xo Ic list-keys
 | 
			
		||||
.Op Fl T Ar key-table
 | 
			
		||||
.Op Fl 1N
 | 
			
		||||
.Op Fl P Ar prefix-string Fl T Ar key-table
 | 
			
		||||
.Op key
 | 
			
		||||
.Xc
 | 
			
		||||
.D1 (alias: Ic lsk )
 | 
			
		||||
List all key bindings.
 | 
			
		||||
Without
 | 
			
		||||
.Fl T
 | 
			
		||||
all key tables are printed.
 | 
			
		||||
By default this shows all keys or any bindings for
 | 
			
		||||
.Ar key
 | 
			
		||||
in the syntax of the
 | 
			
		||||
.Ic bind-key
 | 
			
		||||
command.
 | 
			
		||||
.Fl N
 | 
			
		||||
instead show keys and attached notes, i
 | 
			
		||||
.Ar key-table
 | 
			
		||||
if given or in the
 | 
			
		||||
.Em root
 | 
			
		||||
and
 | 
			
		||||
.Em prefix
 | 
			
		||||
key tables by default.
 | 
			
		||||
.Fl P
 | 
			
		||||
specifies a prefix to print before each key.
 | 
			
		||||
With
 | 
			
		||||
.Fl 1
 | 
			
		||||
only the first matching key and note is shown.
 | 
			
		||||
.Pp
 | 
			
		||||
Without
 | 
			
		||||
.Fl N ,
 | 
			
		||||
.Fl T
 | 
			
		||||
only
 | 
			
		||||
.Ar key-table .
 | 
			
		||||
prints only keys in
 | 
			
		||||
.Ar key-table ,
 | 
			
		||||
otherwise all key tables are printed.
 | 
			
		||||
.It Xo Ic send-keys
 | 
			
		||||
.Op Fl FHlMRX
 | 
			
		||||
.Op Fl N Ar repeat-count
 | 
			
		||||
@@ -4700,7 +4737,7 @@ session option.
 | 
			
		||||
Commands related to the status line are as follows:
 | 
			
		||||
.Bl -tag -width Ds
 | 
			
		||||
.It Xo Ic command-prompt
 | 
			
		||||
.Op Fl 1Ni
 | 
			
		||||
.Op Fl 1ikN
 | 
			
		||||
.Op Fl I Ar inputs
 | 
			
		||||
.Op Fl p Ar prompts
 | 
			
		||||
.Op Fl t Ar target-client
 | 
			
		||||
@@ -4750,6 +4787,10 @@ but any quotation marks are escaped.
 | 
			
		||||
.Fl 1
 | 
			
		||||
makes the prompt only accept one key press, in this case the resulting input
 | 
			
		||||
is a single character.
 | 
			
		||||
.Fl k
 | 
			
		||||
is like
 | 
			
		||||
.Fl 1
 | 
			
		||||
but the key press is translated to a key name.
 | 
			
		||||
.Fl N
 | 
			
		||||
makes the prompt only accept numeric key presses.
 | 
			
		||||
.Fl i
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1611,6 +1611,7 @@ struct client {
 | 
			
		||||
#define PROMPT_NUMERIC 0x2
 | 
			
		||||
#define PROMPT_INCREMENTAL 0x4
 | 
			
		||||
#define PROMPT_NOFORMAT 0x8
 | 
			
		||||
#define PROMPT_KEY 0x10
 | 
			
		||||
	int		 prompt_flags;
 | 
			
		||||
 | 
			
		||||
	struct session	*session;
 | 
			
		||||
@@ -1638,6 +1639,7 @@ TAILQ_HEAD(clients, client);
 | 
			
		||||
struct key_binding {
 | 
			
		||||
	key_code		 key;
 | 
			
		||||
	struct cmd_list		*cmdlist;
 | 
			
		||||
	const char		*note;
 | 
			
		||||
 | 
			
		||||
	int			 flags;
 | 
			
		||||
#define KEY_BINDING_REPEAT 0x1
 | 
			
		||||
@@ -2149,7 +2151,8 @@ void	 key_bindings_unref_table(struct key_table *);
 | 
			
		||||
struct key_binding *key_bindings_get(struct key_table *, key_code);
 | 
			
		||||
struct key_binding *key_bindings_first(struct key_table *);
 | 
			
		||||
struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
 | 
			
		||||
void	 key_bindings_add(const char *, key_code, int, struct cmd_list *);
 | 
			
		||||
void	 key_bindings_add(const char *, key_code, const char *, int,
 | 
			
		||||
	     struct cmd_list *);
 | 
			
		||||
void	 key_bindings_remove(const char *, key_code);
 | 
			
		||||
void	 key_bindings_remove_table(const char *);
 | 
			
		||||
void	 key_bindings_init(void);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user