mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Handle empty pending output (not a failure) and add \n. From George
Nachman.
This commit is contained in:
		| @@ -29,10 +29,16 @@ | |||||||
|  |  | ||||||
| enum cmd_retval	 cmd_capture_pane_exec(struct cmd *, struct cmd_q *); | enum cmd_retval	 cmd_capture_pane_exec(struct cmd *, struct cmd_q *); | ||||||
|  |  | ||||||
|  | char		*cmd_capture_pane_append(char *, size_t *, char *, size_t); | ||||||
|  | char		*cmd_capture_pane_pending(struct args *, struct window_pane *, | ||||||
|  | 		     size_t *); | ||||||
|  | char		*cmd_capture_pane_history(struct args *, struct cmd_q *, | ||||||
|  | 		     struct window_pane *, size_t *); | ||||||
|  |  | ||||||
| const struct cmd_entry cmd_capture_pane_entry = { | const struct cmd_entry cmd_capture_pane_entry = { | ||||||
| 	"capture-pane", "capturep", | 	"capture-pane", "capturep", | ||||||
| 	"ab:CeE:JpqS:t:", 0, 0, | 	"ab:CeE:JpPqS:t:", 0, 0, | ||||||
| 	"[-aCeJpq] [-b buffer-index] [-E end-line] [-S start-line]" | 	"[-aCeJpPq] [-b buffer-index] [-E end-line] [-S start-line]" | ||||||
| 	CMD_TARGET_PANE_USAGE, | 	CMD_TARGET_PANE_USAGE, | ||||||
| 	0, | 	0, | ||||||
| 	NULL, | 	NULL, | ||||||
| @@ -40,92 +46,140 @@ const struct cmd_entry cmd_capture_pane_entry = { | |||||||
| 	cmd_capture_pane_exec | 	cmd_capture_pane_exec | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | char * | ||||||
|  | cmd_capture_pane_append(char *buf, size_t *len, char *line, size_t linelen) | ||||||
|  | { | ||||||
|  | 	buf = xrealloc(buf, 1, *len + linelen + 1); | ||||||
|  | 	memcpy(buf + *len, line, linelen); | ||||||
|  | 	*len += linelen; | ||||||
|  | 	return (buf); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char * | ||||||
|  | cmd_capture_pane_pending(struct args *args, struct window_pane *wp, | ||||||
|  |     size_t *len) | ||||||
|  | { | ||||||
|  | 	char	*buf, *line, tmp[5]; | ||||||
|  | 	size_t	 linelen; | ||||||
|  | 	u_int	 i; | ||||||
|  |  | ||||||
|  | 	if (wp->ictx.since_ground == NULL) | ||||||
|  | 		return (xstrdup("")); | ||||||
|  |  | ||||||
|  | 	line = EVBUFFER_DATA(wp->ictx.since_ground); | ||||||
|  | 	linelen = EVBUFFER_LENGTH(wp->ictx.since_ground); | ||||||
|  |  | ||||||
|  | 	buf = xstrdup(""); | ||||||
|  | 	if (args_has(args, 'C')) { | ||||||
|  | 		for (i = 0; i < linelen; i++) { | ||||||
|  | 			if (line[i] >= ' ') { | ||||||
|  | 				tmp[0] = line[i]; | ||||||
|  | 				tmp[1] = '\0'; | ||||||
|  | 			} else | ||||||
|  | 				xsnprintf(tmp, sizeof tmp, "\\%03o", line[i]); | ||||||
|  | 			buf = cmd_capture_pane_append(buf, len, tmp, | ||||||
|  | 			    strlen(tmp)); | ||||||
|  | 		} | ||||||
|  | 	} else | ||||||
|  | 		buf = cmd_capture_pane_append(buf, len, line, linelen); | ||||||
|  | 	return (buf); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char * | ||||||
|  | cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq, | ||||||
|  |     struct window_pane *wp, size_t *len) | ||||||
|  | { | ||||||
|  | 	struct grid		*gd; | ||||||
|  | 	const struct grid_line	*gl; | ||||||
|  | 	struct grid_cell	*gc = NULL; | ||||||
|  | 	int			 n, with_codes, escape_c0, join_lines; | ||||||
|  | 	u_int			 i, sx, top, bottom, tmp; | ||||||
|  | 	char			*cause, *buf, *line; | ||||||
|  | 	size_t			 linelen; | ||||||
|  |  | ||||||
|  | 	sx = screen_size_x(&wp->base); | ||||||
|  | 	if (args_has(args, 'a')) { | ||||||
|  | 		gd = wp->saved_grid; | ||||||
|  | 		if (gd == NULL) { | ||||||
|  | 			if (!args_has(args, 'q')) { | ||||||
|  | 				cmdq_error(cmdq, "no alternate screen"); | ||||||
|  | 				return (NULL); | ||||||
|  | 			} | ||||||
|  | 			return (xstrdup("")); | ||||||
|  | 		} | ||||||
|  | 	} else | ||||||
|  | 		gd = wp->base.grid; | ||||||
|  |  | ||||||
|  | 	n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause); | ||||||
|  | 	if (cause != NULL) { | ||||||
|  | 		top = gd->hsize; | ||||||
|  | 		free(cause); | ||||||
|  | 	} else if (n < 0 && (u_int) -n > gd->hsize) | ||||||
|  | 		top = 0; | ||||||
|  | 	else | ||||||
|  | 		top = gd->hsize + n; | ||||||
|  | 	if (top > gd->hsize + gd->sy - 1) | ||||||
|  | 		top = gd->hsize + gd->sy - 1; | ||||||
|  |  | ||||||
|  | 	n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause); | ||||||
|  | 	if (cause != NULL) { | ||||||
|  | 		bottom = gd->hsize + gd->sy - 1; | ||||||
|  | 		free(cause); | ||||||
|  | 	} else if (n < 0 && (u_int) -n > gd->hsize) | ||||||
|  | 		bottom = 0; | ||||||
|  | 	else | ||||||
|  | 		bottom = gd->hsize + n; | ||||||
|  | 	if (bottom > gd->hsize + gd->sy - 1) | ||||||
|  | 		bottom = gd->hsize + gd->sy - 1; | ||||||
|  |  | ||||||
|  | 	if (bottom < top) { | ||||||
|  | 		tmp = bottom; | ||||||
|  | 		bottom = top; | ||||||
|  | 		top = tmp; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	with_codes = args_has(args, 'e'); | ||||||
|  | 	escape_c0 = args_has(args, 'C'); | ||||||
|  | 	join_lines = args_has(args, 'J'); | ||||||
|  |  | ||||||
|  | 	buf = NULL; | ||||||
|  | 	for (i = top; i <= bottom; i++) { | ||||||
|  | 		line = grid_string_cells(gd, 0, i, sx, &gc, with_codes, | ||||||
|  | 		    escape_c0, !join_lines); | ||||||
|  | 		linelen = strlen(line); | ||||||
|  |  | ||||||
|  | 		buf = cmd_capture_pane_append(buf, len, line, linelen); | ||||||
|  |  | ||||||
|  | 		gl = grid_peek_line(gd, i); | ||||||
|  | 		if (!join_lines || !(gl->flags & GRID_LINE_WRAPPED)) | ||||||
|  | 			buf[(*len)++] = '\n'; | ||||||
|  |  | ||||||
|  | 		free(line); | ||||||
|  | 	} | ||||||
|  | 	return (buf); | ||||||
|  | } | ||||||
|  |  | ||||||
| enum cmd_retval | enum cmd_retval | ||||||
| cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq) | cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq) | ||||||
| { | { | ||||||
| 	struct args		*args = self->args; | 	struct args		*args = self->args; | ||||||
| 	struct client		*c; | 	struct client		*c; | ||||||
| 	struct window_pane	*wp; | 	struct window_pane	*wp; | ||||||
| 	char			*buf, *line, *cause; | 	char			*buf, *cause; | ||||||
| 	struct screen		*s; | 	int			 buffer; | ||||||
| 	struct grid		*gd; | 	u_int			 limit; | ||||||
| 	int			 buffer, n, with_codes, escape_c0, join_lines; | 	size_t			 len; | ||||||
| 	u_int			 i, limit, top, bottom, tmp, sx; |  | ||||||
| 	size_t			 len, linelen; |  | ||||||
| 	struct grid_cell	*gc; |  | ||||||
| 	const struct grid_line	*gl; |  | ||||||
|  |  | ||||||
| 	if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) | 	if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) | ||||||
| 		return (CMD_RETURN_ERROR); | 		return (CMD_RETURN_ERROR); | ||||||
|  |  | ||||||
| 	if (args_has(args, 'a')) { |  | ||||||
| 		s = NULL; |  | ||||||
| 		gd = wp->saved_grid; |  | ||||||
| 		sx = screen_size_x(&wp->base); |  | ||||||
| 		if (gd == NULL && !args_has(args, 'q')) { |  | ||||||
| 			cmdq_error(cmdq, "no alternate screen"); |  | ||||||
| 			return (CMD_RETURN_ERROR); |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		s = &wp->base; |  | ||||||
| 		sx = screen_size_x(s); |  | ||||||
| 		gd = s->grid; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	buf = NULL; |  | ||||||
| 	len = 0; | 	len = 0; | ||||||
|  | 	if (args_has(args, 'P')) | ||||||
| 	if (gd != NULL) { | 		buf = cmd_capture_pane_pending(args, wp, &len); | ||||||
| 		n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause); | 	else | ||||||
| 		if (cause != NULL) { | 		buf = cmd_capture_pane_history(args, cmdq, wp, &len); | ||||||
| 			top = gd->hsize; | 	if (buf == NULL) | ||||||
| 			free(cause); | 		return (CMD_RETURN_ERROR); | ||||||
| 		} else if (n < 0 && (u_int) -n > gd->hsize) |  | ||||||
| 			top = 0; |  | ||||||
| 		else |  | ||||||
| 			top = gd->hsize + n; |  | ||||||
| 		if (top > gd->hsize + gd->sy - 1) |  | ||||||
| 			top = gd->hsize + gd->sy - 1; |  | ||||||
|  |  | ||||||
| 		n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause); |  | ||||||
| 		if (cause != NULL) { |  | ||||||
| 			bottom = gd->hsize + gd->sy - 1; |  | ||||||
| 			free(cause); |  | ||||||
| 		} else if (n < 0 && (u_int) -n > gd->hsize) |  | ||||||
| 			bottom = 0; |  | ||||||
| 		else |  | ||||||
| 			bottom = gd->hsize + n; |  | ||||||
| 		if (bottom > gd->hsize + gd->sy - 1) |  | ||||||
| 			bottom = gd->hsize + gd->sy - 1; |  | ||||||
|  |  | ||||||
| 		if (bottom < top) { |  | ||||||
| 			tmp = bottom; |  | ||||||
| 			bottom = top; |  | ||||||
| 			top = tmp; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		with_codes = args_has(args, 'e'); |  | ||||||
| 		escape_c0 = args_has(args, 'C'); |  | ||||||
| 		join_lines = args_has(args, 'J'); |  | ||||||
|  |  | ||||||
| 		gc = NULL; |  | ||||||
| 		for (i = top; i <= bottom; i++) { |  | ||||||
| 			line = grid_string_cells(gd, 0, i, sx, &gc, with_codes, |  | ||||||
| 			    escape_c0, !join_lines); |  | ||||||
| 			linelen = strlen(line); |  | ||||||
|  |  | ||||||
| 			buf = xrealloc(buf, 1, len + linelen + 1); |  | ||||||
| 			memcpy(buf + len, line, linelen); |  | ||||||
| 			len += linelen; |  | ||||||
|  |  | ||||||
| 			gl = grid_peek_line(gd, i); |  | ||||||
| 			if (!join_lines || !(gl->flags & GRID_LINE_WRAPPED)) |  | ||||||
| 				buf[len++] = '\n'; |  | ||||||
|  |  | ||||||
| 			free(line); |  | ||||||
| 		} |  | ||||||
| 	} else |  | ||||||
| 		buf = xstrdup(""); |  | ||||||
|  |  | ||||||
| 	if (args_has(args, 'p')) { | 	if (args_has(args, 'p')) { | ||||||
| 		c = cmdq->client; | 		c = cmdq->client; | ||||||
| @@ -135,6 +189,8 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq) | |||||||
| 			return (CMD_RETURN_ERROR); | 			return (CMD_RETURN_ERROR); | ||||||
| 		} | 		} | ||||||
| 		evbuffer_add(c->stdout_data, buf, len); | 		evbuffer_add(c->stdout_data, buf, len); | ||||||
|  | 		if (args_has(args, 'P') && len > 0) | ||||||
|  | 		    evbuffer_add(c->stdout_data, "\n", 1); | ||||||
| 		server_push_stdout(c); | 		server_push_stdout(c); | ||||||
| 	} else { | 	} else { | ||||||
| 		limit = options_get_number(&global_options, "buffer-limit"); | 		limit = options_get_number(&global_options, "buffer-limit"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott