mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Final parts of command hooks, add before- and after- hooks to each command.
This commit is contained in:
		@@ -157,6 +157,7 @@ cmd_if_shell_callback(struct job *job)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmdq1 = cmdq_new(cmdq->client);
 | 
			
		||||
	cmdq1->flags |= cmdq->flags & CMD_Q_NOHOOKS;
 | 
			
		||||
	cmdq1->emptyfn = cmd_if_shell_done;
 | 
			
		||||
	cmdq1->data = cdata;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								cmd-queue.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								cmd-queue.c
									
									
									
									
									
								
							@@ -186,6 +186,9 @@ static enum cmd_retval
 | 
			
		||||
cmdq_continue_one(struct cmd_q *cmdq)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd	*cmd = cmdq->cmd;
 | 
			
		||||
	const char	*name = cmd->entry->name;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	struct hooks	*hooks;
 | 
			
		||||
	enum cmd_retval	 retval;
 | 
			
		||||
	char		*tmp;
 | 
			
		||||
	int		 flags = !!(cmd->flags & CMD_CONTROL);
 | 
			
		||||
@@ -197,19 +200,51 @@ cmdq_continue_one(struct cmd_q *cmdq)
 | 
			
		||||
	cmdq->time = time(NULL);
 | 
			
		||||
	cmdq->number++;
 | 
			
		||||
 | 
			
		||||
	if (~cmdq->flags & CMD_Q_REENTRY)
 | 
			
		||||
		cmdq_guard(cmdq, "begin", flags);
 | 
			
		||||
 | 
			
		||||
	if (cmd_prepare_state(cmd, cmdq, NULL) != 0)
 | 
			
		||||
	if (cmd_prepare_state(cmd, cmdq, cmdq->parent) != 0)
 | 
			
		||||
		goto error;
 | 
			
		||||
 | 
			
		||||
	if (~cmdq->flags & CMD_Q_NOHOOKS) {
 | 
			
		||||
		s = NULL;
 | 
			
		||||
		if (cmdq->state.tflag.s != NULL)
 | 
			
		||||
			s = cmdq->state.tflag.s;
 | 
			
		||||
		else if (cmdq->state.sflag.s != NULL)
 | 
			
		||||
			s = cmdq->state.sflag.s;
 | 
			
		||||
		else if (cmdq->state.c != NULL)
 | 
			
		||||
			s = cmdq->state.c->session;
 | 
			
		||||
		if (s != NULL)
 | 
			
		||||
			hooks = s->hooks;
 | 
			
		||||
		else
 | 
			
		||||
			hooks = global_hooks;
 | 
			
		||||
 | 
			
		||||
		if (~cmdq->flags & CMD_Q_REENTRY) {
 | 
			
		||||
			cmdq->flags |= CMD_Q_REENTRY;
 | 
			
		||||
			if (hooks_wait(hooks, cmdq, NULL,
 | 
			
		||||
			    "before-%s", name) == 0)
 | 
			
		||||
				return (CMD_RETURN_WAIT);
 | 
			
		||||
			if (cmd_prepare_state(cmd, cmdq, cmdq->parent) != 0)
 | 
			
		||||
				goto error;
 | 
			
		||||
		}
 | 
			
		||||
	} else
 | 
			
		||||
		hooks = NULL;
 | 
			
		||||
	cmdq->flags &= ~CMD_Q_REENTRY;
 | 
			
		||||
 | 
			
		||||
	retval = cmd->entry->exec(cmd, cmdq);
 | 
			
		||||
	if (retval == CMD_RETURN_ERROR)
 | 
			
		||||
		goto error;
 | 
			
		||||
 | 
			
		||||
	if (hooks != NULL && hooks_wait(hooks, cmdq, NULL,
 | 
			
		||||
	    "after-%s", name) == 0)
 | 
			
		||||
		retval = CMD_RETURN_WAIT;
 | 
			
		||||
	cmdq_guard(cmdq, "end", flags);
 | 
			
		||||
 | 
			
		||||
	return (retval);
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
	cmdq_guard(cmdq, "error", flags);
 | 
			
		||||
	cmdq->flags &= ~CMD_Q_REENTRY;
 | 
			
		||||
	return (CMD_RETURN_ERROR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -232,11 +267,18 @@ cmdq_continue(struct cmd_q *cmdq)
 | 
			
		||||
	if (empty)
 | 
			
		||||
		goto empty;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If the command isn't in the middle of running hooks (due to
 | 
			
		||||
	 * CMD_RETURN_WAIT), move onto the next command; otherwise, leave the
 | 
			
		||||
	 * state of the queue as it is.
 | 
			
		||||
	 */
 | 
			
		||||
	if (~cmdq->flags & CMD_Q_REENTRY) {
 | 
			
		||||
		if (cmdq->item == NULL) {
 | 
			
		||||
			cmdq->item = TAILQ_FIRST(&cmdq->queue);
 | 
			
		||||
			cmdq->cmd = TAILQ_FIRST(&cmdq->item->cmdlist->list);
 | 
			
		||||
		} else
 | 
			
		||||
			cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		while (cmdq->cmd != NULL) {
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
 | 
			
		||||
	char		*cause;
 | 
			
		||||
 | 
			
		||||
	cmdq1 = cmdq_new(cmdq->client);
 | 
			
		||||
	cmdq1->flags |= cmdq->flags & CMD_Q_NOHOOKS;
 | 
			
		||||
	cmdq1->emptyfn = cmd_source_file_done;
 | 
			
		||||
	cmdq1->data = cmdq;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								format.c
									
									
									
									
									
								
							@@ -468,6 +468,7 @@ struct format_tree *
 | 
			
		||||
format_create(struct cmd_q *cmdq, int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct format_tree	*ft;
 | 
			
		||||
	struct cmd		*cmd;
 | 
			
		||||
 | 
			
		||||
	if (!event_initialized(&format_job_event)) {
 | 
			
		||||
		evtimer_set(&format_job_event, format_job_timer, NULL);
 | 
			
		||||
@@ -486,6 +487,10 @@ format_create(struct cmd_q *cmdq, int flags)
 | 
			
		||||
 | 
			
		||||
	if (cmdq != NULL && cmdq->cmd != NULL)
 | 
			
		||||
		format_add(ft, "command_name", "%s", cmdq->cmd->entry->name);
 | 
			
		||||
	if (cmdq != NULL && cmdq->parent != NULL) {
 | 
			
		||||
		cmd = cmdq->parent->cmd;
 | 
			
		||||
		format_add(ft, "command_hooked", "%s", cmd->entry->name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (ft);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								tmux.1
									
									
									
									
									
								
							@@ -3221,9 +3221,35 @@ shows only the option value, not the name.
 | 
			
		||||
.Nm
 | 
			
		||||
allows commands to run on various triggers, called
 | 
			
		||||
.Em hooks .
 | 
			
		||||
Each hook has a
 | 
			
		||||
.Em name .
 | 
			
		||||
The following hooks are available:
 | 
			
		||||
Each
 | 
			
		||||
.Nm
 | 
			
		||||
command has a
 | 
			
		||||
.Em before
 | 
			
		||||
hook and an
 | 
			
		||||
.Em after
 | 
			
		||||
hook and there are a number of hooks not associated with commands.
 | 
			
		||||
.Pp
 | 
			
		||||
A command's before hook is run before the command is executed and its after
 | 
			
		||||
hook is run afterwards, except when the command is run as part of a hook
 | 
			
		||||
itself.
 | 
			
		||||
Before hooks are named using the
 | 
			
		||||
.Ql before-
 | 
			
		||||
prefix and after hooks the
 | 
			
		||||
.Ql after-
 | 
			
		||||
prefix.
 | 
			
		||||
For example, the following command adds a hook to select the even-vertical
 | 
			
		||||
layout after every
 | 
			
		||||
.Ic split-window :
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
set-hook after-split-window "selectl even-vertical"
 | 
			
		||||
.Ed
 | 
			
		||||
.Pp
 | 
			
		||||
Or to write when each new window is created to a file:
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
set-hook before-new-window 'run "date >>/tmp/log"'
 | 
			
		||||
.Ed
 | 
			
		||||
.Pp
 | 
			
		||||
In addition, the following hooks are available:
 | 
			
		||||
.Bl -tag -width "XXXXXXXXXXXXXXXX"
 | 
			
		||||
.It alert-activity
 | 
			
		||||
Run when a window has activity.
 | 
			
		||||
@@ -3450,6 +3476,7 @@ The following variables are available, where appropriate:
 | 
			
		||||
.It Li "client_tty" Ta "" Ta "Pseudo terminal of client"
 | 
			
		||||
.It Li "client_utf8" Ta "" Ta "1 if client supports utf8"
 | 
			
		||||
.It Li "client_width" Ta "" Ta "Width of client"
 | 
			
		||||
.It Li "command_hooked" Ta "" Ta "Name of command hooked, if any"
 | 
			
		||||
.It Li "command_name" Ta "" Ta "Name of command in use, if any"
 | 
			
		||||
.It Li "cursor_flag" Ta "" Ta "Pane cursor flag"
 | 
			
		||||
.It Li "cursor_x" Ta "" Ta "Cursor X position in pane"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user