mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		
							
								
								
									
										4
									
								
								cfg.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								cfg.c
									
									
									
									
									
								
							| @@ -182,7 +182,7 @@ load_cfg(const char *path, struct client *c, struct cmdq_item *item, int flags, | ||||
| 		return (0); | ||||
| 	} | ||||
|  | ||||
| 	new_item0 = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); | ||||
| 	new_item0 = cmdq_get_command(pr->cmdlist, NULL); | ||||
| 	if (item != NULL) | ||||
| 		new_item0 = cmdq_insert_after(item, new_item0); | ||||
| 	else | ||||
| @@ -228,7 +228,7 @@ load_cfg_from_buffer(const void *buf, size_t len, const char *path, | ||||
| 		return (0); | ||||
| 	} | ||||
|  | ||||
| 	new_item0 = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); | ||||
| 	new_item0 = cmdq_get_command(pr->cmdlist, NULL); | ||||
| 	if (item != NULL) | ||||
| 		new_item0 = cmdq_insert_after(item, new_item0); | ||||
| 	else | ||||
|   | ||||
| @@ -50,8 +50,7 @@ enum cmd_retval | ||||
| cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag, | ||||
|     int xflag, int rflag, const char *cflag, int Eflag) | ||||
| { | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	 target; | ||||
| 	enum cmd_find_type	 type; | ||||
| 	int			 flags; | ||||
| @@ -120,7 +119,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag, | ||||
| 			environ_update(s->options, c->environ, s->environ); | ||||
|  | ||||
| 		c->session = s; | ||||
| 		if (~state->flags & CMDQ_STATE_REPEAT) | ||||
| 		if (~cmdq_get_flags(item) & CMDQ_STATE_REPEAT) | ||||
| 			server_client_set_key_table(c, NULL); | ||||
| 		tty_update_client_offset(c); | ||||
| 		status_timer_start(c); | ||||
|   | ||||
| @@ -49,8 +49,7 @@ static enum cmd_retval | ||||
| cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct cmd_find_state	*source = cmdq_get_source(item); | ||||
| 	struct client		*c = cmd_find_client(item, NULL, 1); | ||||
|   | ||||
| @@ -177,7 +177,7 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s, | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
| 	case CMD_PARSE_SUCCESS: | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, NULL); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
|   | ||||
| @@ -109,7 +109,7 @@ cmd_confirm_before_callback(struct client *c, void *data, const char *s, | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
| 	case CMD_PARSE_SUCCESS: | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, NULL); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
|   | ||||
| @@ -57,7 +57,7 @@ static enum cmd_retval | ||||
| cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct key_event	*event = cmdq_get_event(item); | ||||
| 	struct cmd_find_state	*source = cmdq_get_source(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct client		*c = cmdq_get_client(item); | ||||
| @@ -70,7 +70,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	} | ||||
|  | ||||
| 	if (args_has(args, 'M')) { | ||||
| 		if ((wp = cmd_mouse_pane(&state->event.m, &s, NULL)) == NULL) | ||||
| 		if ((wp = cmd_mouse_pane(&event->m, &s, NULL)) == NULL) | ||||
| 			return (CMD_RETURN_NORMAL); | ||||
| 		if (c == NULL || c->session != s) | ||||
| 			return (CMD_RETURN_NORMAL); | ||||
| @@ -87,7 +87,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 		swp = wp; | ||||
| 	if (!window_pane_set_mode(wp, swp, &window_copy_mode, NULL, args)) { | ||||
| 		if (args_has(args, 'M')) | ||||
| 			window_copy_start_drag(c, &state->event.m); | ||||
| 			window_copy_start_drag(c, &event->m); | ||||
| 	} | ||||
| 	if (args_has(args, 'u')) | ||||
| 		window_copy_pageup(wp, 0); | ||||
|   | ||||
| @@ -65,8 +65,8 @@ static void | ||||
| cmd_display_menu_get_position(struct client *c, struct cmdq_item *item, | ||||
|     struct args *args, u_int *px, u_int *py, u_int w, u_int h) | ||||
| { | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct key_event	*event = cmdq_get_event(item); | ||||
| 	struct session		*s = c->session; | ||||
| 	struct winlink		*wl = target->wl; | ||||
| 	struct window_pane	*wp = target->wp; | ||||
| @@ -100,8 +100,8 @@ cmd_display_menu_get_position(struct client *c, struct cmdq_item *item, | ||||
| 		else | ||||
| 			*px = 0; | ||||
| 	} else if (strcmp(xp, "M") == 0) { | ||||
| 		if (state->event.m.valid && state->event.m.x > w / 2) | ||||
| 			*px = state->event.m.x - w / 2; | ||||
| 		if (event->m.valid && event->m.x > w / 2) | ||||
| 			*px = event->m.x - w / 2; | ||||
| 		else | ||||
| 			*px = 0; | ||||
| 	} else if (strcmp(xp, "W") == 0) { | ||||
| @@ -134,8 +134,8 @@ cmd_display_menu_get_position(struct client *c, struct cmdq_item *item, | ||||
| 		else | ||||
| 			*py = 0; | ||||
| 	} else if (strcmp(yp, "M") == 0) { | ||||
| 		if (state->event.m.valid) | ||||
| 			*py = state->event.m.y + h; | ||||
| 		if (event->m.valid) | ||||
| 			*py = event->m.y + h; | ||||
| 		else | ||||
| 			*py = 0; | ||||
| 	} else if (strcmp(yp, "S") == 0) { | ||||
| @@ -176,8 +176,8 @@ static enum cmd_retval | ||||
| cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct key_event	*event = cmdq_get_event(item); | ||||
| 	struct client		*c; | ||||
| 	struct menu		*menu = NULL; | ||||
| 	struct menu_item	 menu_item; | ||||
| @@ -230,7 +230,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	cmd_display_menu_get_position(c, item, args, &px, &py, menu->width + 4, | ||||
| 	    menu->count + 2); | ||||
|  | ||||
| 	if (!state->event.m.valid) | ||||
| 	if (!event->m.valid) | ||||
| 		flags |= MENU_NOMOUSE; | ||||
| 	if (menu_display(menu, flags, item, px, py, c, target, NULL, NULL) != 0) | ||||
| 		return (CMD_RETURN_NORMAL); | ||||
|   | ||||
| @@ -225,7 +225,7 @@ cmd_display_panes_key(struct client *c, struct key_event *event) | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
| 	case CMD_PARSE_SUCCESS: | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, NULL); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
|   | ||||
| @@ -960,8 +960,8 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item, | ||||
| 	if (server_check_marked() && (flags & CMD_FIND_DEFAULT_MARKED)) { | ||||
| 		fs->current = &marked_pane; | ||||
| 		log_debug("%s: current is marked pane", __func__); | ||||
| 	} else if (cmd_find_valid_state(&cmdq_get_state(item)->current)) { | ||||
| 		fs->current = &cmdq_get_state(item)->current; | ||||
| 	} else if (cmd_find_valid_state(cmdq_get_current(item))) { | ||||
| 		fs->current = cmdq_get_current(item); | ||||
| 		log_debug("%s: current is from queue", __func__); | ||||
| 	} else if (cmd_find_from_client(¤t, cmdq_get_client(item), | ||||
| 	    flags) == 0) { | ||||
| @@ -981,7 +981,7 @@ cmd_find_target(struct cmd_find_state *fs, struct cmdq_item *item, | ||||
|  | ||||
| 	/* Mouse target is a plain = or {mouse}. */ | ||||
| 	if (strcmp(target, "=") == 0 || strcmp(target, "{mouse}") == 0) { | ||||
| 		m = &cmdq_get_state(item)->event.m; | ||||
| 		m = &cmdq_get_event(item)->m; | ||||
| 		switch (type) { | ||||
| 		case CMD_FIND_PANE: | ||||
| 			fs->wp = cmd_mouse_pane(m, &fs->s, &fs->wl); | ||||
|   | ||||
| @@ -56,16 +56,14 @@ struct cmd_if_shell_data { | ||||
|  | ||||
| 	struct client		*client; | ||||
| 	struct cmdq_item	*item; | ||||
| 	struct mouse_event	 mouse; | ||||
| }; | ||||
|  | ||||
| static enum cmd_retval | ||||
| cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args			*args = cmd_get_args(self); | ||||
| 	struct cmdq_state		*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state		*target = cmdq_get_target(item); | ||||
| 	struct mouse_event		*m = &state->event.m; | ||||
| 	struct cmdq_state		*state = cmdq_get_state(item); | ||||
| 	struct cmd_if_shell_data	*cdata; | ||||
| 	char				*shellcmd, *cmd; | ||||
| 	const char			*file; | ||||
| @@ -102,7 +100,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 			free(pr->error); | ||||
| 			return (CMD_RETURN_ERROR); | ||||
| 		case CMD_PARSE_SUCCESS: | ||||
| 			new_item = cmdq_get_command(pr->cmdlist, target, m, 0); | ||||
| 			new_item = cmdq_get_command(pr->cmdlist, state); | ||||
| 			cmdq_insert_after(item, new_item); | ||||
| 			cmd_list_free(pr->cmdlist); | ||||
| 			break; | ||||
| @@ -117,7 +115,6 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 		cdata->cmd_else = xstrdup(args->argv[2]); | ||||
| 	else | ||||
| 		cdata->cmd_else = NULL; | ||||
| 	memcpy(&cdata->mouse, m, sizeof cdata->mouse); | ||||
|  | ||||
| 	if (!args_has(args, 'b')) | ||||
| 		cdata->client = cmdq_get_client(item); | ||||
| @@ -161,8 +158,8 @@ cmd_if_shell_callback(struct job *job) | ||||
| { | ||||
| 	struct cmd_if_shell_data	*cdata = job_get_data(job); | ||||
| 	struct client			*c = cdata->client; | ||||
| 	struct mouse_event		*m = &cdata->mouse; | ||||
| 	struct cmdq_item		*new_item = NULL; | ||||
| 	struct cmdq_state		*new_state = NULL; | ||||
| 	char				*cmd; | ||||
| 	int				 status; | ||||
| 	struct cmd_parse_result		*pr; | ||||
| @@ -185,7 +182,13 @@ cmd_if_shell_callback(struct job *job) | ||||
| 		free(pr->error); | ||||
| 		break; | ||||
| 	case CMD_PARSE_SUCCESS: | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, NULL, m, 0); | ||||
| 		if (cdata->item == NULL) | ||||
| 			new_state = cmdq_new_state(NULL, NULL, 0); | ||||
| 		else | ||||
| 			new_state = cmdq_get_state(cdata->item); | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, new_state); | ||||
| 		if (cdata->item == NULL) | ||||
| 			cmdq_free_state(new_state); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 		break; | ||||
| 	} | ||||
|   | ||||
| @@ -63,8 +63,7 @@ static enum cmd_retval | ||||
| cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct cmd_find_state	*source = cmdq_get_source(item); | ||||
| 	struct session		*dst_s; | ||||
|   | ||||
| @@ -67,8 +67,7 @@ static enum cmd_retval | ||||
| cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct client		*c = cmdq_get_client(item); | ||||
| 	struct session		*s, *as, *groupwith; | ||||
| @@ -317,7 +316,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 		} else if (c->session != NULL) | ||||
| 			c->last_session = c->session; | ||||
| 		c->session = s; | ||||
| 		if (~state->flags & CMDQ_STATE_REPEAT) | ||||
| 		if (~cmdq_get_flags(item) & CMDQ_STATE_REPEAT) | ||||
| 			server_client_set_key_table(c, NULL); | ||||
| 		tty_update_client_offset(c); | ||||
| 		status_timer_start(c); | ||||
| @@ -345,10 +344,10 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 		free(cp); | ||||
| 	} | ||||
|  | ||||
| 	if (!detached) { | ||||
| 	if (!detached) | ||||
| 		c->flags |= CLIENT_ATTACHED; | ||||
| 	if (!args_has(args, 'd')) | ||||
| 		cmd_find_from_session(current, s, 0); | ||||
| 	} | ||||
|  | ||||
| 	cmd_find_from_session(&fs, s, 0); | ||||
| 	cmdq_insert_hook(s, item, &fs, "after-new-session"); | ||||
|   | ||||
| @@ -52,8 +52,7 @@ static enum cmd_retval | ||||
| cmd_new_window_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct spawn_context	 sc; | ||||
| 	struct client		*c = cmd_find_client(item, NULL, 1); | ||||
|   | ||||
							
								
								
									
										21
									
								
								cmd-parse.y
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								cmd-parse.y
									
									
									
									
									
								
							| @@ -700,15 +700,17 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds, | ||||
|  | ||||
| 	/* | ||||
| 	 * Parse each command into a command list. Create a new command list | ||||
| 	 * for each line so they get a new group (so the queue knows which ones | ||||
| 	 * to remove if a command fails when executed). | ||||
| 	 * for each line (unless the flag is set) so they get a new group (so | ||||
| 	 * the queue knows which ones to remove if a command fails when | ||||
| 	 * executed). | ||||
| 	 */ | ||||
| 	result = cmd_list_new(); | ||||
| 	TAILQ_FOREACH(cmd, cmds, entry) { | ||||
| 		log_debug("%s: %u %s", __func__, cmd->line, cmd->name); | ||||
| 		cmd_log_argv(cmd->argc, cmd->argv, __func__); | ||||
|  | ||||
| 		if (cmdlist == NULL || cmd->line != line) { | ||||
| 		if (cmdlist == NULL || | ||||
| 		    ((~pi->flags & CMD_PARSE_ONEGROUP) && cmd->line != line)) { | ||||
| 			if (cmdlist != NULL) { | ||||
| 				cmd_parse_print_commands(pi, line, cmdlist); | ||||
| 				cmd_list_move(result, cmdlist); | ||||
| @@ -775,6 +777,19 @@ cmd_parse_from_file(FILE *f, struct cmd_parse_input *pi) | ||||
| struct cmd_parse_result * | ||||
| cmd_parse_from_string(const char *s, struct cmd_parse_input *pi) | ||||
| { | ||||
| 	struct cmd_parse_input	input; | ||||
|  | ||||
| 	if (pi == NULL) { | ||||
| 		memset(&input, 0, sizeof input); | ||||
| 		pi = &input; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * When parsing a string, put commands in one group even if there are | ||||
| 	 * multiple lines. This means { a \n b } is identical to "a ; b" when | ||||
| 	 * given as an argument to another command. | ||||
| 	 */ | ||||
| 	pi->flags |= CMD_PARSE_ONEGROUP; | ||||
| 	return (cmd_parse_from_buffer(s, strlen(s), pi)); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										210
									
								
								cmd-queue.c
									
									
									
									
									
								
							
							
						
						
									
										210
									
								
								cmd-queue.c
									
									
									
									
									
								
							| @@ -65,6 +65,23 @@ struct cmdq_item { | ||||
| }; | ||||
| TAILQ_HEAD(cmdq_list, cmdq_item); | ||||
|  | ||||
| /* | ||||
|  * Command queue state. This is the context for commands on the command queue. | ||||
|  * It holds information about how the commands were fired (the key and flags), | ||||
|  * any additional formats for the commands, and the current default target. | ||||
|  * Multiple commands can share the same state and a command may update the | ||||
|  * default target. | ||||
|  */ | ||||
| struct cmdq_state { | ||||
| 	int			 references; | ||||
| 	int			 flags; | ||||
|  | ||||
| 	struct format_tree	*formats; | ||||
|  | ||||
| 	struct key_event	 event; | ||||
| 	struct cmd_find_state	 current; | ||||
| }; | ||||
|  | ||||
| /* Get command queue name. */ | ||||
| static const char * | ||||
| cmdq_name(struct client *c) | ||||
| @@ -128,6 +145,13 @@ cmdq_get_client(struct cmdq_item *item) | ||||
| 	return (item->client); | ||||
| } | ||||
|  | ||||
| /* Get item state. */ | ||||
| struct cmdq_state * | ||||
| cmdq_get_state(struct cmdq_item *item) | ||||
| { | ||||
| 	return (item->state); | ||||
| } | ||||
|  | ||||
| /* Get item target. */ | ||||
| struct cmd_find_state * | ||||
| cmdq_get_target(struct cmdq_item *item) | ||||
| @@ -142,11 +166,89 @@ cmdq_get_source(struct cmdq_item *item) | ||||
| 	return (&item->source); | ||||
| } | ||||
|  | ||||
| /* Get item state. */ | ||||
| struct cmdq_state * | ||||
| cmdq_get_state(struct cmdq_item *item) | ||||
| /* Get state event. */ | ||||
| struct key_event * | ||||
| cmdq_get_event(struct cmdq_item *item) | ||||
| { | ||||
| 	return (item->state); | ||||
| 	return (&item->state->event); | ||||
| } | ||||
|  | ||||
| /* Get state current target. */ | ||||
| struct cmd_find_state * | ||||
| cmdq_get_current(struct cmdq_item *item) | ||||
| { | ||||
| 	return (&item->state->current); | ||||
| } | ||||
|  | ||||
| /* Get state flags. */ | ||||
| int | ||||
| cmdq_get_flags(struct cmdq_item *item) | ||||
| { | ||||
| 	return (item->state->flags); | ||||
| } | ||||
|  | ||||
| /* Create a new state. */ | ||||
| struct cmdq_state * | ||||
| cmdq_new_state(struct cmd_find_state *current, struct key_event *event, | ||||
|     int flags) | ||||
| { | ||||
| 	struct cmdq_state	*state; | ||||
|  | ||||
| 	state = xcalloc(1, sizeof *state); | ||||
| 	state->references = 1; | ||||
| 	state->flags = flags; | ||||
|  | ||||
| 	if (event != NULL) | ||||
| 		memcpy(&state->event, event, sizeof state->event); | ||||
| 	else | ||||
| 		state->event.key = KEYC_NONE; | ||||
| 	if (current != NULL && cmd_find_valid_state(current)) | ||||
| 		cmd_find_copy_state(&state->current, current); | ||||
| 	else | ||||
| 		cmd_find_clear_state(&state->current, 0); | ||||
|  | ||||
| 	return (state); | ||||
| } | ||||
|  | ||||
| /* Add a reference to a state. */ | ||||
| struct cmdq_state * | ||||
| cmdq_link_state(struct cmdq_state *state) | ||||
| { | ||||
| 	state->references++; | ||||
| 	return (state); | ||||
| } | ||||
|  | ||||
| /* Make a copy of a state. */ | ||||
| struct cmdq_state * | ||||
| cmdq_copy_state(struct cmdq_state *state) | ||||
| { | ||||
| 	return (cmdq_new_state(&state->current, &state->event, state->flags)); | ||||
| } | ||||
|  | ||||
| /* Free a state. */ | ||||
| void | ||||
| cmdq_free_state(struct cmdq_state *state) | ||||
| { | ||||
| 	if (--state->references == 0) | ||||
| 		free(state); | ||||
| } | ||||
|  | ||||
| /* Add a format to command queue. */ | ||||
| void | ||||
| cmdq_add_format(struct cmdq_state *state, const char *key, const char *fmt, ...) | ||||
| { | ||||
| 	va_list	 ap; | ||||
| 	char	*value; | ||||
|  | ||||
| 	va_start(ap, fmt); | ||||
| 	xvasprintf(&value, fmt, ap); | ||||
| 	va_end(ap); | ||||
|  | ||||
| 	if (state->formats == NULL) | ||||
| 		state->formats = format_create(NULL, NULL, FORMAT_NONE, 0); | ||||
| 	format_add(state->formats, key, "%s", value); | ||||
|  | ||||
| 	free(value); | ||||
| } | ||||
|  | ||||
| /* Merge formats from item. */ | ||||
| @@ -218,12 +320,14 @@ cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item) | ||||
| /* Insert a hook. */ | ||||
| void | ||||
| cmdq_insert_hook(struct session *s, struct cmdq_item *item, | ||||
|     struct cmd_find_state *fs, const char *fmt, ...) | ||||
|     struct cmd_find_state *current, const char *fmt, ...) | ||||
| { | ||||
| 	struct cmdq_state		*state = item->state; | ||||
| 	struct options			*oo; | ||||
| 	va_list				 ap; | ||||
| 	char				*name; | ||||
| 	struct cmdq_item		*new_item; | ||||
| 	struct cmdq_state		*new_state; | ||||
| 	struct options_entry		*o; | ||||
| 	struct options_array_item	*a; | ||||
| 	struct cmd_list			*cmdlist; | ||||
| @@ -246,25 +350,27 @@ cmdq_insert_hook(struct session *s, struct cmdq_item *item, | ||||
| 	} | ||||
| 	log_debug("running hook %s (parent %p)", name, item); | ||||
|  | ||||
| 	/* | ||||
| 	 * The hooks get a new state because they should not update the current | ||||
| 	 * target or formats for any subsequent commands. | ||||
| 	 */ | ||||
| 	new_state = cmdq_new_state(current, &state->event, CMDQ_STATE_NOHOOKS); | ||||
| 	cmdq_add_format(new_state, "hook", "%s", name); | ||||
|  | ||||
| 	a = options_array_first(o); | ||||
| 	while (a != NULL) { | ||||
| 		cmdlist = options_array_item_value(a)->cmdlist; | ||||
| 		if (cmdlist == NULL) { | ||||
| 			a = options_array_next(a); | ||||
| 			continue; | ||||
| 		if (cmdlist != NULL) { | ||||
| 			new_item = cmdq_get_command(cmdlist, new_state); | ||||
| 			if (item != NULL) | ||||
| 				item = cmdq_insert_after(item, new_item); | ||||
| 			else | ||||
| 				item = cmdq_append(NULL, new_item); | ||||
| 		} | ||||
|  | ||||
| 		new_item = cmdq_get_command(cmdlist, fs, NULL, | ||||
| 		    CMDQ_STATE_NOHOOKS); | ||||
| 		cmdq_format(new_item, "hook", "%s", name); | ||||
| 		if (item != NULL) | ||||
| 			item = cmdq_insert_after(item, new_item); | ||||
| 		else | ||||
| 			item = cmdq_append(NULL, new_item); | ||||
|  | ||||
| 		a = options_array_next(a); | ||||
| 	} | ||||
|  | ||||
| 	cmdq_free_state(new_state); | ||||
| 	free(name); | ||||
| } | ||||
|  | ||||
| @@ -279,17 +385,11 @@ cmdq_continue(struct cmdq_item *item) | ||||
| static void | ||||
| cmdq_remove(struct cmdq_item *item) | ||||
| { | ||||
| 	if (item->state != NULL && --item->state->references == 0) { | ||||
| 		if (item->state->formats != NULL) | ||||
| 			format_free(item->state->formats); | ||||
| 		free(item->state); | ||||
| 	} | ||||
|  | ||||
| 	if (item->client != NULL) | ||||
| 		server_client_unref(item->client); | ||||
|  | ||||
| 	if (item->cmdlist != NULL) | ||||
| 		cmd_list_free(item->cmdlist); | ||||
| 	cmdq_free_state(item->state); | ||||
|  | ||||
| 	TAILQ_REMOVE(item->queue, item, entry); | ||||
|  | ||||
| @@ -316,46 +416,34 @@ cmdq_remove_group(struct cmdq_item *item) | ||||
|  | ||||
| /* Get a command for the command queue. */ | ||||
| struct cmdq_item * | ||||
| cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current, | ||||
|     struct mouse_event *m, int flags) | ||||
| cmdq_get_command(struct cmd_list *cmdlist, struct cmdq_state *state) | ||||
| { | ||||
| 	struct cmdq_item	*item, *first = NULL, *last = NULL; | ||||
| 	struct cmd		*cmd; | ||||
| 	const struct cmd_entry	*entry; | ||||
| 	struct cmdq_state	*state = NULL; | ||||
| 	u_int			 group, last_group = 0; | ||||
| 	int			 created = 0; | ||||
|  | ||||
| 	cmd = cmd_list_first(cmdlist, &group); | ||||
| 	if (state == NULL) { | ||||
| 		state = cmdq_new_state(NULL, NULL, 0); | ||||
| 		created = 1; | ||||
| 	} | ||||
|  | ||||
| 	cmd = cmd_list_first(cmdlist); | ||||
| 	while (cmd != NULL) { | ||||
| 		if (group != last_group) { | ||||
| 			state = xcalloc(1, sizeof *state); | ||||
| 			if (current != NULL) | ||||
| 				cmd_find_copy_state(&state->current, current); | ||||
| 			else | ||||
| 				cmd_find_clear_state(&state->current, 0); | ||||
| 			if (m != NULL) { | ||||
| 				state->event.key = KEYC_NONE; | ||||
| 				memcpy(&state->event.m, m, | ||||
| 				    sizeof state->event.m); | ||||
| 			} | ||||
| 			state->flags = flags; | ||||
| 			last_group = group; | ||||
| 		} | ||||
| 		entry = cmd_get_entry(cmd); | ||||
|  | ||||
| 		item = xcalloc(1, sizeof *item); | ||||
| 		xasprintf(&item->name, "[%s/%p]", entry->name, item); | ||||
| 		item->type = CMDQ_COMMAND; | ||||
| 		item->group = group; | ||||
|  | ||||
| 		item->state = state; | ||||
| 		item->group = cmd_get_group(cmd); | ||||
| 		item->state = cmdq_link_state(state); | ||||
|  | ||||
| 		item->cmdlist = cmdlist; | ||||
| 		item->cmd = cmd; | ||||
|  | ||||
| 		log_debug("%s: %s group %u", __func__, item->name, item->group); | ||||
|  | ||||
| 		state->references++; | ||||
| 		cmdlist->references++; | ||||
| 		log_debug("%s: %s group %u", __func__, item->name, item->group); | ||||
|  | ||||
| 		if (first == NULL) | ||||
| 			first = item; | ||||
| @@ -363,8 +451,11 @@ cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current, | ||||
| 			last->next = item; | ||||
| 		last = item; | ||||
|  | ||||
| 		cmd = cmd_list_next(cmd, &group); | ||||
| 		cmd = cmd_list_next(cmd); | ||||
| 	} | ||||
|  | ||||
| 	if (created) | ||||
| 		cmdq_free_state(state); | ||||
| 	return (first); | ||||
| } | ||||
|  | ||||
| @@ -454,7 +545,9 @@ cmdq_get_callback1(const char *name, cmdq_cb cb, void *data) | ||||
| 	item = xcalloc(1, sizeof *item); | ||||
| 	xasprintf(&item->name, "[%s/%p]", name, item); | ||||
| 	item->type = CMDQ_CALLBACK; | ||||
|  | ||||
| 	item->group = 0; | ||||
| 	item->state = cmdq_new_state(NULL, NULL, 0); | ||||
|  | ||||
| 	item->cb = cb; | ||||
| 	item->data = data; | ||||
| @@ -488,25 +581,6 @@ cmdq_fire_callback(struct cmdq_item *item) | ||||
| 	return (item->cb(item, item->data)); | ||||
| } | ||||
|  | ||||
| /* Add a format to command queue. */ | ||||
| void | ||||
| cmdq_format(struct cmdq_item *item, const char *key, const char *fmt, ...) | ||||
| { | ||||
| 	struct cmdq_state	*state = item->state; | ||||
| 	va_list			 ap; | ||||
| 	char			*value; | ||||
|  | ||||
| 	va_start(ap, fmt); | ||||
| 	xvasprintf(&value, fmt, ap); | ||||
| 	va_end(ap); | ||||
|  | ||||
| 	if (state->formats == NULL) | ||||
| 		state->formats = format_create(NULL, NULL, FORMAT_NONE, 0); | ||||
| 	format_add(state->formats, key, "%s", value); | ||||
|  | ||||
| 	free(value); | ||||
| } | ||||
|  | ||||
| /* Process next item on command queue. */ | ||||
| u_int | ||||
| cmdq_next(struct client *c) | ||||
|   | ||||
| @@ -50,8 +50,8 @@ static enum cmd_retval | ||||
| cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct key_event	*event = cmdq_get_event(item); | ||||
| 	struct window_pane	*wp = target->wp; | ||||
| 	struct winlink		*wl = target->wl; | ||||
| 	struct window		*w = wl->window; | ||||
| @@ -76,12 +76,12 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	} | ||||
|  | ||||
| 	if (args_has(args, 'M')) { | ||||
| 		if (cmd_mouse_window(&state->event.m, &s) == NULL) | ||||
| 		if (!event->m.valid || cmd_mouse_window(&event->m, &s) == NULL) | ||||
| 			return (CMD_RETURN_NORMAL); | ||||
| 		if (c == NULL || c->session != s) | ||||
| 			return (CMD_RETURN_NORMAL); | ||||
| 		c->tty.mouse_drag_update = cmd_resize_pane_mouse_update; | ||||
| 		cmd_resize_pane_mouse_update(c, &state->event.m); | ||||
| 		cmd_resize_pane_mouse_update(c, &event->m); | ||||
| 		return (CMD_RETURN_NORMAL); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -44,8 +44,7 @@ static enum cmd_retval | ||||
| cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct winlink		*wl = target->wl; | ||||
| 	struct window		*w = wl->window; | ||||
|   | ||||
| @@ -85,8 +85,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	const struct cmd_entry	*entry = cmd_get_entry(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct client		*c = cmd_find_client(item, NULL, 1); | ||||
| 	struct winlink		*wl = target->wl; | ||||
|   | ||||
| @@ -85,8 +85,7 @@ static enum cmd_retval | ||||
| cmd_select_window_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct winlink		*wl = target->wl; | ||||
| 	struct session		*s = target->s; | ||||
|   | ||||
| @@ -134,13 +134,13 @@ static enum cmd_retval | ||||
| cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args			*args = cmd_get_args(self); | ||||
| 	struct cmdq_state		*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state		*target = cmdq_get_target(item); | ||||
| 	struct client			*c = cmd_find_client(item, NULL, 1); | ||||
| 	struct window_pane		*wp = target->wp; | ||||
| 	struct session			*s = target->s; | ||||
| 	struct winlink			*wl = target->wl; | ||||
| 	struct mouse_event		*m = &state->event.m; | ||||
| 	struct key_event		*event = cmdq_get_event(item); | ||||
| 	struct mouse_event		*m = &event->m; | ||||
| 	struct window_mode_entry	*wme = TAILQ_FIRST(&wp->modes); | ||||
| 	int				 i; | ||||
| 	key_code			 key; | ||||
|   | ||||
| @@ -53,8 +53,7 @@ static enum cmd_retval | ||||
| cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	*target = cmdq_get_target(item); | ||||
| 	struct spawn_context	 sc; | ||||
| 	struct client		*c = cmd_find_client(item, NULL, 1); | ||||
|   | ||||
| @@ -48,8 +48,7 @@ static enum cmd_retval | ||||
| cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) | ||||
| { | ||||
| 	struct args		*args = cmd_get_args(self); | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct cmd_find_state	*current = &state->current; | ||||
| 	struct cmd_find_state	*current = cmdq_get_current(item); | ||||
| 	struct cmd_find_state	 target; | ||||
| 	const char		*tflag = args_get(args, 't'); | ||||
| 	enum cmd_find_type	 type; | ||||
| @@ -137,7 +136,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) | ||||
| 	if (c->session != NULL && c->session != s) | ||||
| 		c->last_session = c->session; | ||||
| 	c->session = s; | ||||
| 	if (~state->flags & CMDQ_STATE_REPEAT) | ||||
| 	if (~cmdq_get_flags(item) & CMDQ_STATE_REPEAT) | ||||
| 		server_client_set_key_table(c, NULL); | ||||
| 	tty_update_client_offset(c); | ||||
| 	status_timer_start(c); | ||||
|   | ||||
							
								
								
									
										46
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -391,6 +391,13 @@ cmd_get_args(struct cmd *cmd) | ||||
| 	return (cmd->args); | ||||
| } | ||||
|  | ||||
| /* Get group for command. */ | ||||
| u_int | ||||
| cmd_get_group(struct cmd *cmd) | ||||
| { | ||||
| 	return (cmd->group); | ||||
| } | ||||
|  | ||||
| /* Get file and line for command. */ | ||||
| void | ||||
| cmd_get_source(struct cmd *cmd, const char **file, u_int *line) | ||||
| @@ -616,7 +623,7 @@ cmd_list_free(struct cmd_list *cmdlist) | ||||
| char * | ||||
| cmd_list_print(struct cmd_list *cmdlist, int escaped) | ||||
| { | ||||
| 	struct cmd	*cmd; | ||||
| 	struct cmd	*cmd, *next; | ||||
| 	char		*buf, *this; | ||||
| 	size_t		 len; | ||||
|  | ||||
| @@ -626,15 +633,24 @@ cmd_list_print(struct cmd_list *cmdlist, int escaped) | ||||
| 	TAILQ_FOREACH(cmd, cmdlist->list, qentry) { | ||||
| 		this = cmd_print(cmd); | ||||
|  | ||||
| 		len += strlen(this) + 4; | ||||
| 		len += strlen(this) + 6; | ||||
| 		buf = xrealloc(buf, len); | ||||
|  | ||||
| 		strlcat(buf, this, len); | ||||
| 		if (TAILQ_NEXT(cmd, qentry) != NULL) { | ||||
| 			if (escaped) | ||||
| 				strlcat(buf, " \\; ", len); | ||||
| 			else | ||||
| 				strlcat(buf, " ; ", len); | ||||
|  | ||||
| 		next = TAILQ_NEXT(cmd, qentry); | ||||
| 		if (next != NULL) { | ||||
| 			if (cmd->group != next->group) { | ||||
| 				if (escaped) | ||||
| 					strlcat(buf, " \\;\\; ", len); | ||||
| 				else | ||||
| 					strlcat(buf, " ;; ", len); | ||||
| 			} else { | ||||
| 				if (escaped) | ||||
| 					strlcat(buf, " \\; ", len); | ||||
| 				else | ||||
| 					strlcat(buf, " ; ", len); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		free(this); | ||||
| @@ -645,24 +661,16 @@ cmd_list_print(struct cmd_list *cmdlist, int escaped) | ||||
|  | ||||
| /* Get first command in list. */ | ||||
| struct cmd * | ||||
| cmd_list_first(struct cmd_list *cmdlist, u_int *group) | ||||
| cmd_list_first(struct cmd_list *cmdlist) | ||||
| { | ||||
| 	struct cmd	*cmd; | ||||
|  | ||||
| 	cmd = TAILQ_FIRST(cmdlist->list); | ||||
| 	if (cmd != NULL && group != NULL) | ||||
| 		*group = cmd->group; | ||||
| 	return (cmd); | ||||
| 	return (TAILQ_FIRST(cmdlist->list)); | ||||
| } | ||||
|  | ||||
| /* Get next command in list. */ | ||||
| struct cmd * | ||||
| cmd_list_next(struct cmd *cmd, u_int *group) | ||||
| cmd_list_next(struct cmd *cmd) | ||||
| { | ||||
| 	cmd = TAILQ_NEXT(cmd, qentry); | ||||
| 	if (cmd != NULL && group != NULL) | ||||
| 		*group = cmd->group; | ||||
| 	return (cmd); | ||||
| 	return (TAILQ_NEXT(cmd, qentry)); | ||||
| } | ||||
|  | ||||
| /* Do all of the commands in this command list have this flag? */ | ||||
|   | ||||
| @@ -60,6 +60,7 @@ control_callback(__unused struct client *c, __unused const char *path, | ||||
| { | ||||
| 	char			*line; | ||||
| 	struct cmdq_item	*item; | ||||
| 	struct cmdq_state	*state; | ||||
| 	struct cmd_parse_result	*pr; | ||||
|  | ||||
| 	if (closed || error != 0) | ||||
| @@ -85,9 +86,10 @@ control_callback(__unused struct client *c, __unused const char *path, | ||||
| 			cmdq_append(c, item); | ||||
| 			break; | ||||
| 		case CMD_PARSE_SUCCESS: | ||||
| 			item = cmdq_get_command(pr->cmdlist, NULL, NULL, 0); | ||||
| 			cmdq_get_state(item)->flags |= CMDQ_STATE_CONTROL; | ||||
| 			state = cmdq_new_state(NULL, NULL, CMDQ_STATE_CONTROL); | ||||
| 			item = cmdq_get_command(pr->cmdlist, state); | ||||
| 			cmdq_append(c, item); | ||||
| 			cmdq_free_state(state); | ||||
| 			cmd_list_free(pr->cmdlist); | ||||
| 			break; | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										7
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								format.c
									
									
									
									
									
								
							| @@ -1124,16 +1124,13 @@ format_merge(struct format_tree *ft, struct format_tree *from) | ||||
| static void | ||||
| format_create_add_item(struct format_tree *ft, struct cmdq_item *item) | ||||
| { | ||||
| 	struct cmdq_state	*state = cmdq_get_state(item); | ||||
| 	struct mouse_event	*m; | ||||
| 	struct key_event	*event = cmdq_get_event(item); | ||||
| 	struct mouse_event	*m = &event->m; | ||||
| 	struct window_pane	*wp; | ||||
| 	u_int			 x, y; | ||||
|  | ||||
| 	cmdq_merge_formats(item, ft); | ||||
|  | ||||
| 	if (state == NULL) | ||||
| 		return; | ||||
| 	m = &state->event.m; | ||||
| 	if (m->valid && ((wp = cmd_mouse_pane(m, NULL, NULL)) != NULL)) { | ||||
| 		format_add(ft, "mouse_pane", "%%%u", wp->id); | ||||
| 		if (cmd_mouse_at(wp, m, &x, &y, 0) == 0) { | ||||
|   | ||||
| @@ -521,7 +521,7 @@ key_bindings_init(void) | ||||
| 		pr = cmd_parse_from_string(defaults[i], NULL); | ||||
| 		if (pr->status != CMD_PARSE_SUCCESS) | ||||
| 			fatalx("bad default key: %s", defaults[i]); | ||||
| 		cmdq_append(NULL, cmdq_get_command(pr->cmdlist, NULL, NULL, 0)); | ||||
| 		cmdq_append(NULL, cmdq_get_command(pr->cmdlist, NULL)); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 	} | ||||
| } | ||||
| @@ -535,10 +535,11 @@ key_bindings_read_only(struct cmdq_item *item, __unused void *data) | ||||
|  | ||||
| struct cmdq_item * | ||||
| key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item, | ||||
|     struct client *c, struct mouse_event *m, struct cmd_find_state *fs) | ||||
|     struct client *c, struct key_event *event, struct cmd_find_state *fs) | ||||
| { | ||||
| 	struct cmdq_item	*new_item; | ||||
| 	int			 readonly; | ||||
| 	struct cmdq_state	*new_state; | ||||
| 	int			 readonly, flags = 0; | ||||
|  | ||||
| 	if (c == NULL || (~c->flags & CLIENT_READONLY)) | ||||
| 		readonly = 1; | ||||
| @@ -547,9 +548,11 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item, | ||||
| 	if (!readonly) | ||||
| 		new_item = cmdq_get_callback(key_bindings_read_only, NULL); | ||||
| 	else { | ||||
| 		new_item = cmdq_get_command(bd->cmdlist, fs, m, 0); | ||||
| 		if (bd->flags & KEY_BINDING_REPEAT) | ||||
| 			cmdq_get_state(new_item)->flags |= CMDQ_STATE_REPEAT; | ||||
| 			flags |= CMDQ_STATE_REPEAT; | ||||
| 		new_state = cmdq_new_state(fs, event, flags); | ||||
| 		new_item = cmdq_get_command(bd->cmdlist, new_state); | ||||
| 		cmdq_free_state(new_state); | ||||
| 	} | ||||
| 	if (item != NULL) | ||||
| 		new_item = cmdq_insert_after(item, new_item); | ||||
|   | ||||
							
								
								
									
										9
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								menu.c
									
									
									
									
									
								
							| @@ -185,6 +185,7 @@ menu_key_cb(struct client *c, struct key_event *event) | ||||
| 	int				 count = menu->count, old = md->choice; | ||||
| 	const struct menu_item		*item; | ||||
| 	struct cmdq_item		*new_item; | ||||
| 	struct cmdq_state		*new_state; | ||||
| 	struct cmd_parse_result		*pr; | ||||
| 	const char			*name; | ||||
|  | ||||
| @@ -282,10 +283,12 @@ chosen: | ||||
| 		break; | ||||
| 	case CMD_PARSE_SUCCESS: | ||||
| 		if (md->item != NULL) | ||||
| 			m = &cmdq_get_state(md->item)->event.m; | ||||
| 			event = cmdq_get_event(md->item); | ||||
| 		else | ||||
| 			m = NULL; | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, &md->fs, m, 0); | ||||
| 			event = NULL; | ||||
| 		new_state = cmdq_new_state(&md->fs, event, 0); | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, new_state); | ||||
| 		cmdq_free_state(new_state); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
|   | ||||
| @@ -1064,6 +1064,7 @@ mode_tree_run_command(struct client *c, struct cmd_find_state *fs, | ||||
|     const char *template, const char *name) | ||||
| { | ||||
| 	struct cmdq_item	*new_item; | ||||
| 	struct cmdq_state	*new_state; | ||||
| 	char			*command; | ||||
| 	struct cmd_parse_result	*pr; | ||||
|  | ||||
| @@ -1085,7 +1086,9 @@ mode_tree_run_command(struct client *c, struct cmd_find_state *fs, | ||||
| 		free(pr->error); | ||||
| 		break; | ||||
| 	case CMD_PARSE_SUCCESS: | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, fs, NULL, 0); | ||||
| 		new_state = cmdq_new_state(fs, NULL, 0); | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, new_state); | ||||
| 		cmdq_free_state(new_state); | ||||
| 		cmdq_append(c, new_item); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 		break; | ||||
|   | ||||
							
								
								
									
										34
									
								
								notify.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								notify.c
									
									
									
									
									
								
							| @@ -35,19 +35,19 @@ struct notify_entry { | ||||
| }; | ||||
|  | ||||
| static void | ||||
| notify_hook_formats(struct cmdq_item *item, struct session *s, struct window *w, | ||||
|     int pane) | ||||
| notify_hook_formats(struct cmdq_state *state, struct session *s, | ||||
|     struct window *w, int pane) | ||||
| { | ||||
| 	if (s != NULL) { | ||||
| 		cmdq_format(item, "hook_session", "$%u", s->id); | ||||
| 		cmdq_format(item, "hook_session_name", "%s", s->name); | ||||
| 		cmdq_add_format(state, "hook_session", "$%u", s->id); | ||||
| 		cmdq_add_format(state, "hook_session_name", "%s", s->name); | ||||
| 	} | ||||
| 	if (w != NULL) { | ||||
| 		cmdq_format(item, "hook_window", "@%u", w->id); | ||||
| 		cmdq_format(item, "hook_window_name", "%s", w->name); | ||||
| 		cmdq_add_format(state, "hook_window", "@%u", w->id); | ||||
| 		cmdq_add_format(state, "hook_window_name", "%s", w->name); | ||||
| 	} | ||||
| 	if (pane != -1) | ||||
| 		cmdq_format(item, "hook_pane", "%%%d", pane); | ||||
| 		cmdq_add_format(state, "hook_pane", "%%%d", pane); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -56,6 +56,7 @@ notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne) | ||||
| 	struct cmd_find_state		 fs; | ||||
| 	struct options			*oo; | ||||
| 	struct cmdq_item		*new_item; | ||||
| 	struct cmdq_state		*new_state; | ||||
| 	struct session			*s = ne->session; | ||||
| 	struct window			*w = ne->window; | ||||
| 	struct options_entry		*o; | ||||
| @@ -86,22 +87,21 @@ notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne) | ||||
| 	if (o == NULL) | ||||
| 		return; | ||||
|  | ||||
| 	new_state = cmdq_new_state(&fs, NULL, CMDQ_STATE_NOHOOKS); | ||||
| 	cmdq_add_format(new_state, "hook", "%s", ne->name); | ||||
| 	notify_hook_formats(new_state, s, w, ne->pane); | ||||
|  | ||||
| 	a = options_array_first(o); | ||||
| 	while (a != NULL) { | ||||
| 		cmdlist = options_array_item_value(a)->cmdlist; | ||||
| 		if (cmdlist == NULL) { | ||||
| 			a = options_array_next(a); | ||||
| 			continue; | ||||
| 		if (cmdlist != NULL) { | ||||
| 			new_item = cmdq_get_command(cmdlist, new_state); | ||||
| 			item = cmdq_insert_after(item, new_item); | ||||
| 		} | ||||
|  | ||||
| 		new_item = cmdq_get_command(cmdlist, &fs, NULL, | ||||
| 		    CMDQ_STATE_NOHOOKS); | ||||
| 		cmdq_format(new_item, "hook", "%s", ne->name); | ||||
| 		notify_hook_formats(new_item, s, w, ne->pane); | ||||
| 		item = cmdq_insert_after(item, new_item); | ||||
|  | ||||
| 		a = options_array_next(a); | ||||
| 	} | ||||
|  | ||||
| 	cmdq_free_state(new_state); | ||||
| } | ||||
|  | ||||
| static enum cmd_retval | ||||
|   | ||||
							
								
								
									
										9
									
								
								popup.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								popup.c
									
									
									
									
									
								
							| @@ -223,6 +223,7 @@ popup_key_cb(struct client *c, struct key_event *event) | ||||
| 	struct mouse_event	*m = &event->m; | ||||
| 	struct cmd_find_state	*fs = &pd->fs; | ||||
| 	struct cmdq_item	*new_item; | ||||
| 	struct cmdq_state	*new_state; | ||||
| 	struct cmd_parse_result	*pr; | ||||
| 	struct format_tree	*ft; | ||||
| 	const char		*cmd, *buf; | ||||
| @@ -305,10 +306,12 @@ popup_key_cb(struct client *c, struct key_event *event) | ||||
| 		break; | ||||
| 	case CMD_PARSE_SUCCESS: | ||||
| 		if (pd->item != NULL) | ||||
| 			m = &cmdq_get_state(pd->item)->event.m; | ||||
| 			event = cmdq_get_event(pd->item); | ||||
| 		else | ||||
| 			m = NULL; | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, fs, m, 0); | ||||
| 			event = NULL; | ||||
| 		new_state = cmdq_new_state(&pd->fs, event, 0); | ||||
| 		new_item = cmdq_get_command(pr->cmdlist, new_state); | ||||
| 		cmdq_free_state(new_state); | ||||
| 		cmd_list_free(pr->cmdlist); | ||||
| 		cmdq_append(c, new_item); | ||||
| 		break; | ||||
|   | ||||
| @@ -1221,7 +1221,7 @@ try_again: | ||||
| 		server_status_client(c); | ||||
|  | ||||
| 		/* Execute the key binding. */ | ||||
| 		key_bindings_dispatch(bd, item, c, m, &fs); | ||||
| 		key_bindings_dispatch(bd, item, c, event, &fs); | ||||
| 		key_bindings_unref_table(table); | ||||
| 		goto out; | ||||
| 	} | ||||
| @@ -1947,7 +1947,7 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg) | ||||
| 	} | ||||
| 	cmd_free_argv(argc, argv); | ||||
|  | ||||
| 	cmdq_append(c, cmdq_get_command(pr->cmdlist, NULL, NULL, 0)); | ||||
| 	cmdq_append(c, cmdq_get_command(pr->cmdlist, NULL)); | ||||
| 	cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL)); | ||||
|  | ||||
| 	cmd_list_free(pr->cmdlist); | ||||
|   | ||||
							
								
								
									
										40
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -45,6 +45,7 @@ struct cmd; | ||||
| struct cmd_find_state; | ||||
| struct cmdq_item; | ||||
| struct cmdq_list; | ||||
| struct cmdq_state; | ||||
| struct cmds; | ||||
| struct environ; | ||||
| struct format_job_tree; | ||||
| @@ -1371,6 +1372,7 @@ struct cmd_parse_input { | ||||
| #define CMD_PARSE_PARSEONLY 0x2 | ||||
| #define CMD_PARSE_NOALIAS 0x4 | ||||
| #define CMD_PARSE_VERBOSE 0x8 | ||||
| #define CMD_PARSE_ONEGROUP 0x10 | ||||
|  | ||||
| 	const char		*file; | ||||
| 	u_int			 line; | ||||
| @@ -1380,21 +1382,11 @@ struct cmd_parse_input { | ||||
| 	struct cmd_find_state	 fs; | ||||
| }; | ||||
|  | ||||
| /* Command queue item state. */ | ||||
| struct cmdq_state { | ||||
| 	int			 references; | ||||
|  | ||||
| 	int			 flags; | ||||
| /* Command queue flags. */ | ||||
| #define CMDQ_STATE_REPEAT 0x1 | ||||
| #define CMDQ_STATE_CONTROL 0x2 | ||||
| #define CMDQ_STATE_NOHOOKS 0x4 | ||||
|  | ||||
| 	struct format_tree	*formats; | ||||
|  | ||||
| 	struct key_event	 event; | ||||
| 	struct cmd_find_state	 current; | ||||
| }; | ||||
|  | ||||
| /* Command queue callback. */ | ||||
| typedef enum cmd_retval (*cmdq_cb) (struct cmdq_item *, void *); | ||||
|  | ||||
| @@ -2069,6 +2061,7 @@ char		*cmd_stringify_argv(int, char **); | ||||
| char		*cmd_get_alias(const char *); | ||||
| const struct cmd_entry *cmd_get_entry(struct cmd *); | ||||
| struct args	*cmd_get_args(struct cmd *); | ||||
| u_int		 cmd_get_group(struct cmd *); | ||||
| void		 cmd_get_source(struct cmd *, const char **, u_int *); | ||||
| struct cmd	*cmd_parse(int, char **, const char *, u_int, char **); | ||||
| void		 cmd_free(struct cmd *); | ||||
| @@ -2078,8 +2071,8 @@ void		 cmd_list_append(struct cmd_list *, struct cmd *); | ||||
| void		 cmd_list_move(struct cmd_list *, struct cmd_list *); | ||||
| void		 cmd_list_free(struct cmd_list *); | ||||
| char		*cmd_list_print(struct cmd_list *, int); | ||||
| struct cmd	*cmd_list_first(struct cmd_list *, u_int *); | ||||
| struct cmd	*cmd_list_next(struct cmd *, u_int *); | ||||
| struct cmd	*cmd_list_first(struct cmd_list *); | ||||
| struct cmd	*cmd_list_next(struct cmd *); | ||||
| int		 cmd_list_all_have(struct cmd_list *, int); | ||||
| int		 cmd_list_any_have(struct cmd_list *, int); | ||||
| int		 cmd_mouse_at(struct window_pane *, struct mouse_event *, | ||||
| @@ -2104,16 +2097,25 @@ struct cmd_parse_result *cmd_parse_from_arguments(int, char **, | ||||
| 		     struct cmd_parse_input *); | ||||
|  | ||||
| /* cmd-queue.c */ | ||||
| struct cmdq_state *cmdq_new_state(struct cmd_find_state *, struct key_event *, | ||||
| 		     int); | ||||
| struct cmdq_state *cmdq_link_state(struct cmdq_state *); | ||||
| struct cmdq_state *cmdq_copy_state(struct cmdq_state *); | ||||
| void		  cmdq_free_state(struct cmdq_state *); | ||||
| void printflike(3, 4) cmdq_add_format(struct cmdq_state *, const char *, | ||||
| 		     const char *, ...); | ||||
| void		  cmdq_merge_formats(struct cmdq_item *, struct format_tree *); | ||||
| struct cmdq_list *cmdq_new(void); | ||||
| void cmdq_free(struct cmdq_list *); | ||||
| const char	 *cmdq_get_name(struct cmdq_item *); | ||||
| struct client	 *cmdq_get_client(struct cmdq_item *); | ||||
| struct cmdq_state *cmdq_get_state(struct cmdq_item *); | ||||
| struct cmd_find_state *cmdq_get_target(struct cmdq_item *); | ||||
| struct cmd_find_state *cmdq_get_source(struct cmdq_item *); | ||||
| struct cmdq_state *cmdq_get_state(struct cmdq_item *); | ||||
| void		  cmdq_merge_formats(struct cmdq_item *, struct format_tree *); | ||||
| struct cmdq_item *cmdq_get_command(struct cmd_list *, struct cmd_find_state *, | ||||
| 		     struct mouse_event *, int); | ||||
| struct key_event *cmdq_get_event(struct cmdq_item *); | ||||
| struct cmd_find_state *cmdq_get_current(struct cmdq_item *); | ||||
| int		  cmdq_get_flags(struct cmdq_item *); | ||||
| struct cmdq_item *cmdq_get_command(struct cmd_list *, struct cmdq_state *); | ||||
| #define cmdq_get_callback(cb, data) cmdq_get_callback1(#cb, cb, data) | ||||
| struct cmdq_item *cmdq_get_callback1(const char *, cmdq_cb, void *); | ||||
| struct cmdq_item *cmdq_get_error(const char *); | ||||
| @@ -2122,8 +2124,6 @@ struct cmdq_item *cmdq_append(struct client *, struct cmdq_item *); | ||||
| void		 cmdq_insert_hook(struct session *, struct cmdq_item *, | ||||
| 		     struct cmd_find_state *, const char *, ...); | ||||
| void		 cmdq_continue(struct cmdq_item *); | ||||
| void printflike(3, 4) cmdq_format(struct cmdq_item *, const char *, | ||||
| 		     const char *, ...); | ||||
| u_int		 cmdq_next(struct client *); | ||||
| void		 cmdq_guard(struct cmdq_item *, const char *, int); | ||||
| void printflike(2, 3) cmdq_print(struct cmdq_item *, const char *, ...); | ||||
| @@ -2149,7 +2149,7 @@ void	 key_bindings_remove(const char *, key_code); | ||||
| void	 key_bindings_remove_table(const char *); | ||||
| void	 key_bindings_init(void); | ||||
| struct cmdq_item *key_bindings_dispatch(struct key_binding *, | ||||
| 	     struct cmdq_item *, struct client *, struct mouse_event *, | ||||
| 	     struct cmdq_item *, struct client *, struct key_event *, | ||||
| 	     struct cmd_find_state *); | ||||
|  | ||||
| /* key-string.c */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Thomas Adam
					Thomas Adam