mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
Sync from OpenBSD.
This commit is contained in:
		
							
								
								
									
										7
									
								
								cfg.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								cfg.c
									
									
									
									
									
								
							| @@ -36,7 +36,8 @@ void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); | ||||
|  | ||||
| char			*cfg_cause; | ||||
| int			 cfg_finished; | ||||
| struct causelist	cfg_causes = ARRAY_INITIALIZER; | ||||
| int	 		 cfg_references; | ||||
| struct causelist	 cfg_causes; | ||||
|  | ||||
| /* ARGSUSED */ | ||||
| void printflike2 | ||||
| @@ -89,6 +90,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) | ||||
| 	} | ||||
| 	n = 0; | ||||
|  | ||||
| 	cfg_references++; | ||||
|  | ||||
| 	line = NULL; | ||||
| 	retval = CMD_RETURN_NORMAL; | ||||
| 	while ((buf = fgetln(f, &len))) { | ||||
| @@ -171,6 +174,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) | ||||
| 	} | ||||
| 	fclose(f); | ||||
|  | ||||
| 	cfg_references--; | ||||
|  | ||||
| 	return (retval); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -30,13 +30,15 @@ | ||||
|  */ | ||||
|  | ||||
| enum cmd_retval	 cmd_run_shell_exec(struct cmd *, struct cmd_ctx *); | ||||
|  | ||||
| void	cmd_run_shell_callback(struct job *); | ||||
| void	cmd_run_shell_free(void *); | ||||
| void	cmd_run_shell_print(struct job *, const char *); | ||||
|  | ||||
| const struct cmd_entry cmd_run_shell_entry = { | ||||
| 	"run-shell", "run", | ||||
| 	"", 1, 1, | ||||
| 	"command", | ||||
| 	"t:", 1, 1, | ||||
| 	CMD_TARGET_PANE_USAGE " command", | ||||
| 	0, | ||||
| 	NULL, | ||||
| 	NULL, | ||||
| @@ -46,17 +48,42 @@ const struct cmd_entry cmd_run_shell_entry = { | ||||
| struct cmd_run_shell_data { | ||||
| 	char		*cmd; | ||||
| 	struct cmd_ctx	 ctx; | ||||
| 	u_int		 wp_id; | ||||
| }; | ||||
|  | ||||
| void | ||||
| cmd_run_shell_print(struct job *job, const char *msg) | ||||
| { | ||||
| 	struct cmd_run_shell_data	*cdata = job->data; | ||||
| 	struct cmd_ctx			*ctx = &cdata->ctx; | ||||
| 	struct window_pane		*wp; | ||||
|  | ||||
| 	wp = window_pane_find_by_id(cdata->wp_id); | ||||
| 	if (wp == NULL) { | ||||
| 		ctx->print(ctx, "%s", msg); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (window_pane_set_mode(wp, &window_copy_mode) == 0) | ||||
| 		window_copy_init_for_output(wp); | ||||
| 	if (wp->mode == &window_copy_mode) | ||||
| 		window_copy_add(wp, "%s", msg); | ||||
| } | ||||
|  | ||||
| enum cmd_retval | ||||
| cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| { | ||||
| 	struct args			*args = self->args; | ||||
| 	struct cmd_run_shell_data	*cdata; | ||||
| 	const char			*shellcmd = args->argv[0]; | ||||
| 	struct window_pane		*wp; | ||||
|  | ||||
| 	if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) | ||||
| 		return (CMD_RETURN_ERROR); | ||||
|  | ||||
| 	cdata = xmalloc(sizeof *cdata); | ||||
| 	cdata->cmd = xstrdup(args->argv[0]); | ||||
| 	cdata->wp_id = wp->id; | ||||
| 	memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); | ||||
|  | ||||
| 	if (ctx->cmdclient != NULL) | ||||
| @@ -87,7 +114,7 @@ cmd_run_shell_callback(struct job *job) | ||||
| 	lines = 0; | ||||
| 	do { | ||||
| 		if ((line = evbuffer_readline(job->event->input)) != NULL) { | ||||
| 			ctx->print(ctx, "%s", line); | ||||
| 			cmd_run_shell_print (job, line); | ||||
| 			lines++; | ||||
| 		} | ||||
| 	} while (line != NULL); | ||||
| @@ -98,7 +125,7 @@ cmd_run_shell_callback(struct job *job) | ||||
| 		memcpy(line, EVBUFFER_DATA(job->event->input), size); | ||||
| 		line[size] = '\0'; | ||||
|  | ||||
| 		ctx->print(ctx, "%s", line); | ||||
| 		cmd_run_shell_print(job, line); | ||||
| 		lines++; | ||||
|  | ||||
| 		free(line); | ||||
| @@ -115,10 +142,10 @@ cmd_run_shell_callback(struct job *job) | ||||
| 		xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); | ||||
| 	} | ||||
| 	if (msg != NULL) { | ||||
| 		if (lines != 0) | ||||
| 			ctx->print(ctx, "%s", msg); | ||||
| 		else | ||||
| 		if (lines == 0) | ||||
| 			ctx->info(ctx, "%s", msg); | ||||
| 		else | ||||
| 			cmd_run_shell_print(job, msg); | ||||
| 		free(msg); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -42,35 +42,32 @@ enum cmd_retval | ||||
| cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| { | ||||
| 	struct args		*args = self->args; | ||||
| 	struct causelist	 causes; | ||||
| 	char			*cause; | ||||
| 	struct window_pane	*wp; | ||||
| 	int			 retval; | ||||
| 	u_int			 i; | ||||
| 	char			*cause; | ||||
|  | ||||
| 	ARRAY_INIT(&causes); | ||||
| 	retval = load_cfg(args->argv[0], ctx, &cfg_causes); | ||||
|  | ||||
| 	retval = load_cfg(args->argv[0], ctx, &causes); | ||||
| 	if (ARRAY_EMPTY(&causes)) | ||||
| 	/* | ||||
| 	 * If the context for the cmdclient came from tmux's configuration | ||||
| 	 * file, then return the status of this command now, regardless of the | ||||
| 	 * error condition. Any errors from parsing a configuration file at | ||||
| 	 * startup will be handled for us by the server. | ||||
| 	 */ | ||||
| 	if (cfg_references > 0 || | ||||
| 	    (ctx->curclient == NULL && ctx->cmdclient == NULL)) | ||||
| 		return (retval); | ||||
|  | ||||
| 	if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) { | ||||
| 		wp = RB_MIN(sessions, &sessions)->curw->window->active; | ||||
| 		window_pane_set_mode(wp, &window_copy_mode); | ||||
| 		window_copy_init_for_output(wp); | ||||
| 		for (i = 0; i < ARRAY_LENGTH(&causes); i++) { | ||||
| 			cause = ARRAY_ITEM(&causes, i); | ||||
| 			window_copy_add(wp, "%s", cause); | ||||
| 			free(cause); | ||||
| 		} | ||||
| 	} else { | ||||
| 		for (i = 0; i < ARRAY_LENGTH(&causes); i++) { | ||||
| 			cause = ARRAY_ITEM(&causes, i); | ||||
| 	/* | ||||
| 	 * We were called from the command-line in which case print the errors | ||||
| 	 * gathered here directly. | ||||
| 	 */ | ||||
| 	for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) { | ||||
| 		cause = ARRAY_ITEM(&cfg_causes, i); | ||||
| 		ctx->print(ctx, "%s", cause); | ||||
| 		free(cause); | ||||
| 	} | ||||
| 	} | ||||
| 	ARRAY_FREE(&causes); | ||||
| 	ARRAY_FREE(&cfg_causes); | ||||
|  | ||||
| 	return (retval); | ||||
| } | ||||
|   | ||||
							
								
								
									
										36
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -115,6 +115,7 @@ const struct cmd_entry *cmd_table[] = { | ||||
| 	NULL | ||||
| }; | ||||
|  | ||||
| int		 cmd_session_better(struct session *, struct session *, int); | ||||
| struct session	*cmd_choose_session_list(struct sessionslist *); | ||||
| struct session	*cmd_choose_session(int); | ||||
| struct client	*cmd_choose_client(struct clients *); | ||||
| @@ -370,6 +371,24 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached) | ||||
| 	return (cmd_choose_session(prefer_unattached)); | ||||
| } | ||||
|  | ||||
| /* Is this session better? */ | ||||
| int | ||||
| cmd_session_better(struct session *s, struct session *best, | ||||
|     int prefer_unattached) | ||||
| { | ||||
| 	if (best == NULL) | ||||
| 		return 1; | ||||
| 	if (prefer_unattached) { | ||||
| 		if (!(best->flags & SESSION_UNATTACHED) && | ||||
| 		    (s->flags & SESSION_UNATTACHED)) | ||||
| 			return 1; | ||||
| 		else if ((best->flags & SESSION_UNATTACHED) && | ||||
| 		    !(s->flags & SESSION_UNATTACHED)) | ||||
| 			return 0; | ||||
| 	} | ||||
| 	return (timercmp(&s->activity_time, &best->activity_time, >)); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Find the most recently used session, preferring unattached if the flag is | ||||
|  * set. | ||||
| @@ -377,21 +396,14 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached) | ||||
| struct session * | ||||
| cmd_choose_session(int prefer_unattached) | ||||
| { | ||||
| 	struct session	*s, *sbest; | ||||
| 	struct timeval	*tv = NULL; | ||||
| 	struct session	*s, *best; | ||||
|  | ||||
| 	sbest = NULL; | ||||
| 	best = NULL; | ||||
| 	RB_FOREACH(s, sessions, &sessions) { | ||||
| 		if (tv == NULL || timercmp(&s->activity_time, tv, >) || | ||||
| 		    (prefer_unattached && | ||||
| 		    !(sbest->flags & SESSION_UNATTACHED) && | ||||
| 		    (s->flags & SESSION_UNATTACHED))) { | ||||
| 			sbest = s; | ||||
| 			tv = &s->activity_time; | ||||
| 		if (cmd_session_better(s, best, prefer_unattached)) | ||||
| 			best = s; | ||||
| 	} | ||||
| 	} | ||||
|  | ||||
| 	return (sbest); | ||||
| 	return (best); | ||||
| } | ||||
|  | ||||
| /* Find the most recently used session from a list. */ | ||||
|   | ||||
| @@ -685,6 +685,21 @@ const struct options_table_entry window_options_table[] = { | ||||
| 	  .default_str = "#I:#W#F" | ||||
| 	}, | ||||
|  | ||||
| 	{ .name = "window-status-last-attr", | ||||
| 	  .type = OPTIONS_TABLE_ATTRIBUTES, | ||||
| 	  .default_num = 0 | ||||
| 	}, | ||||
|  | ||||
| 	{ .name = "window-status-last-bg", | ||||
| 	  .type = OPTIONS_TABLE_COLOUR, | ||||
| 	  .default_num = 8 | ||||
| 	}, | ||||
|  | ||||
| 	{ .name = "window-status-last-fg", | ||||
| 	  .type = OPTIONS_TABLE_COLOUR, | ||||
| 	  .default_num = 8 | ||||
| 	}, | ||||
|  | ||||
| 	{ .name = "window-status-fg", | ||||
| 	  .type = OPTIONS_TABLE_COLOUR, | ||||
| 	  .default_num = 8 | ||||
|   | ||||
							
								
								
									
										11
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								status.c
									
									
									
									
									
								
							| @@ -705,6 +705,17 @@ status_print( | ||||
| 			gc->attr = attr; | ||||
| 		fmt = options_get_string(oo, "window-status-current-format"); | ||||
| 	} | ||||
| 	if (wl == TAILQ_FIRST(&s->lastw)) { | ||||
| 		fg = options_get_number(oo, "window-status-last-fg"); | ||||
| 		if (fg != 8) | ||||
| 			colour_set_fg(gc, fg); | ||||
| 		bg = options_get_number(oo, "window-status-last-bg"); | ||||
| 		if (bg != 8) | ||||
| 			colour_set_bg(gc, bg); | ||||
| 		attr = options_get_number(oo, "window-status-last-attr"); | ||||
| 		if (attr != 0) | ||||
| 			gc->attr = attr; | ||||
| 	} | ||||
|  | ||||
| 	if (wl->flags & WINLINK_BELL) { | ||||
| 		fg = options_get_number(oo, "window-status-bell-fg"); | ||||
|   | ||||
							
								
								
									
										19
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -2827,6 +2827,15 @@ Like | ||||
| .Ar window-status-format , | ||||
| but is the format used when the window is the current window. | ||||
| .Pp | ||||
| .It Ic window-status-last-attr Ar attributes | ||||
| Set status line attributes for the last active window. | ||||
| .Pp | ||||
| .It Ic window-status-last-bg Ar colour | ||||
| Set status line background colour for the last active window. | ||||
| .Pp | ||||
| .It Ic window-status-last-fg Ar colour | ||||
| Set status line foreground colour for the last active window. | ||||
| .Pp | ||||
| .It Ic window-status-fg Ar colour | ||||
| Set status line foreground colour for a single window. | ||||
| .Pp | ||||
| @@ -3389,12 +3398,18 @@ otherwise. | ||||
| Lock each client individually by running the command specified by the | ||||
| .Ic lock-command | ||||
| option. | ||||
| .It Ic run-shell Ar shell-command | ||||
| .It Xo Ic run-shell | ||||
| .Op Fl t Ar target-pane | ||||
| .Ar shell-command | ||||
| .Xc | ||||
| .D1 (alias: Ic run ) | ||||
| Execute | ||||
| .Ar shell-command | ||||
| in the background without creating a window. | ||||
| After it finishes, any output to stdout is displayed in copy mode. | ||||
| After it finishes, any output to stdout is displayed in copy mode (in the pane | ||||
| specified by | ||||
| .Fl t | ||||
| or the current pane if omitted). | ||||
| If the command doesn't return success, the exit status is also displayed. | ||||
| .It Ic server-info | ||||
| .D1 (alias: Ic info ) | ||||
|   | ||||
							
								
								
									
										10
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tmux.c
									
									
									
									
									
								
							| @@ -162,7 +162,7 @@ parseenvironment(void) | ||||
| char * | ||||
| makesocketpath(const char *label) | ||||
| { | ||||
| 	char		base[MAXPATHLEN], *path, *s; | ||||
| 	char		base[MAXPATHLEN], realbase[MAXPATHLEN], *path, *s; | ||||
| 	struct stat	sb; | ||||
| 	u_int		uid; | ||||
|  | ||||
| @@ -186,7 +186,10 @@ makesocketpath(const char *label) | ||||
| 		return (NULL); | ||||
| 	} | ||||
|  | ||||
| 	xasprintf(&path, "%s/%s", base, label); | ||||
| 	if (realpath(base, realbase) == NULL) | ||||
| 		strlcpy(realbase, base, sizeof realbase); | ||||
|  | ||||
| 	xasprintf(&path, "%s/%s", realbase, label); | ||||
| 	return (path); | ||||
| } | ||||
|  | ||||
| @@ -333,6 +336,8 @@ main(int argc, char **argv) | ||||
| 	options_init(&global_w_options, NULL); | ||||
| 	options_table_populate_tree(window_options_table, &global_w_options); | ||||
|  | ||||
| 	ARRAY_INIT(&cfg_causes); | ||||
|  | ||||
| 	/* Enable UTF-8 if the first client is on UTF-8 terminal. */ | ||||
| 	if (flags & IDENTIFY_UTF8) { | ||||
| 		options_set_number(&global_s_options, "status-utf8", 1); | ||||
| @@ -390,7 +395,6 @@ main(int argc, char **argv) | ||||
| 		} | ||||
| 	} | ||||
| 	free(label); | ||||
| 	if (realpath(path, socket_path) == NULL) | ||||
| 	strlcpy(socket_path, path, sizeof socket_path); | ||||
| 	free(path); | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1513,6 +1513,7 @@ __dead void	 shell_exec(const char *, const char *); | ||||
|  | ||||
| /* cfg.c */ | ||||
| extern int       cfg_finished; | ||||
| extern int       cfg_references; | ||||
| extern struct causelist cfg_causes; | ||||
| void printflike2 cfg_add_cause(struct causelist *, const char *, ...); | ||||
| int		 load_cfg(const char *, struct cmd_ctx *, struct causelist *); | ||||
|   | ||||
| @@ -832,10 +832,10 @@ window_copy_mouse( | ||||
| 	if (m->event == MOUSE_EVENT_WHEEL) { | ||||
| 		if (m->wheel == MOUSE_WHEEL_UP) { | ||||
| 			for (i = 0; i < 5; i++) | ||||
| 				window_copy_cursor_up(wp, 0); | ||||
| 				window_copy_cursor_up(wp, 1); | ||||
| 		} else if (m->wheel == MOUSE_WHEEL_DOWN) { | ||||
| 			for (i = 0; i < 5; i++) | ||||
| 				window_copy_cursor_down(wp, 0); | ||||
| 				window_copy_cursor_down(wp, 1); | ||||
| 			if (data->oy == 0) | ||||
| 				goto reset_mode; | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Thomas Adam
					Thomas Adam