mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add S: to list sessions with modifiers for sorting, from Michael Grant.
This commit is contained in:
		
							
								
								
									
										91
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								format.c
									
									
									
									
									
								
							@@ -132,6 +132,18 @@ enum format_type {
 | 
			
		||||
	FORMAT_TYPE_PANE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Format loop sort type. */
 | 
			
		||||
enum format_loop_sort_type {
 | 
			
		||||
	FORMAT_LOOP_BY_INDEX,
 | 
			
		||||
	FORMAT_LOOP_BY_NAME,
 | 
			
		||||
	FORMAT_LOOP_BY_TIME,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct format_loop_sort_criteria {
 | 
			
		||||
	u_int	field;
 | 
			
		||||
	int	reversed;
 | 
			
		||||
} format_loop_sort_criteria;
 | 
			
		||||
 | 
			
		||||
struct format_tree {
 | 
			
		||||
	enum format_type	 type;
 | 
			
		||||
 | 
			
		||||
@@ -4028,7 +4040,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Now try single character with arguments. */
 | 
			
		||||
		if (strchr("mCNst=pReq", cp[0]) == NULL)
 | 
			
		||||
		if (strchr("mCNSst=pReq", cp[0]) == NULL)
 | 
			
		||||
			break;
 | 
			
		||||
		c = cp[0];
 | 
			
		||||
 | 
			
		||||
@@ -4224,6 +4236,39 @@ format_session_name(struct format_expand_state *es, const char *fmt)
 | 
			
		||||
	return (xstrdup("0"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
format_cmp_session(const void *a0, const void *b0)
 | 
			
		||||
{
 | 
			
		||||
	const struct session *const	*a = a0;
 | 
			
		||||
	const struct session *const	*b = b0;
 | 
			
		||||
	const struct session		*sa = *a;
 | 
			
		||||
	const struct session		*sb = *b;
 | 
			
		||||
	int				 result = 0;
 | 
			
		||||
 | 
			
		||||
	switch (format_loop_sort_criteria.field) {
 | 
			
		||||
	case FORMAT_LOOP_BY_INDEX:
 | 
			
		||||
		result = sa->id - sb->id;
 | 
			
		||||
		break;
 | 
			
		||||
	case FORMAT_LOOP_BY_TIME:
 | 
			
		||||
		if (timercmp(&sa->activity_time, &sb->activity_time, >)) {
 | 
			
		||||
			result = -1;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		if (timercmp(&sa->activity_time, &sb->activity_time, <)) {
 | 
			
		||||
			result = 1;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case FORMAT_LOOP_BY_NAME:
 | 
			
		||||
		result = strcmp(sa->name, sb->name);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (format_loop_sort_criteria.reversed)
 | 
			
		||||
		result = -result;
 | 
			
		||||
	return (result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Loop over sessions. */
 | 
			
		||||
static char *
 | 
			
		||||
format_loop_sessions(struct format_expand_state *es, const char *fmt)
 | 
			
		||||
@@ -4233,20 +4278,44 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt)
 | 
			
		||||
	struct cmdq_item		 *item = ft->item;
 | 
			
		||||
	struct format_tree		 *nft;
 | 
			
		||||
	struct format_expand_state	  next;
 | 
			
		||||
	char				*expanded, *value;
 | 
			
		||||
	char				 *all, *active, *use, *expanded, *value;
 | 
			
		||||
	size_t				  valuelen;
 | 
			
		||||
	struct session			 *s;
 | 
			
		||||
	int				  i, n;
 | 
			
		||||
	static struct session		**l = NULL;
 | 
			
		||||
	static int			  lsz = 0;
 | 
			
		||||
 | 
			
		||||
	if (format_choose(es, fmt, &all, &active, 0) != 0) {
 | 
			
		||||
		all = xstrdup(fmt);
 | 
			
		||||
		active = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n = 0;
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
		if (lsz <= n) {
 | 
			
		||||
			lsz += 100;
 | 
			
		||||
			l = xreallocarray(l, lsz, sizeof *l);
 | 
			
		||||
		}
 | 
			
		||||
		l[n++] = s;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        qsort(l, n, sizeof *l, format_cmp_session);
 | 
			
		||||
 | 
			
		||||
	value = xcalloc(1, 1);
 | 
			
		||||
	valuelen = 1;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions) {
 | 
			
		||||
        for (i = 0; i < n; i++) {
 | 
			
		||||
		s = l[i];
 | 
			
		||||
		format_log(es, "session loop: $%u", s->id);
 | 
			
		||||
		if (active != NULL && s->id == ft->c->session->id)
 | 
			
		||||
			use = active;
 | 
			
		||||
		else
 | 
			
		||||
			use = all;
 | 
			
		||||
		nft = format_create(c, item, FORMAT_NONE, ft->flags);
 | 
			
		||||
		format_defaults(nft, ft->c, s, NULL, NULL);
 | 
			
		||||
		format_copy_state(&next, es, 0);
 | 
			
		||||
		next.ft = nft;
 | 
			
		||||
		expanded = format_expand1(&next, fmt);
 | 
			
		||||
		expanded = format_expand1(&next, use);
 | 
			
		||||
		format_free(next.ft);
 | 
			
		||||
 | 
			
		||||
		valuelen += strlen(expanded);
 | 
			
		||||
@@ -4585,6 +4654,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
 | 
			
		||||
	struct format_modifier		 *bool_op_n = NULL;
 | 
			
		||||
	u_int				  i, count, nsub = 0, nrep;
 | 
			
		||||
	struct format_expand_state	  next;
 | 
			
		||||
	struct format_loop_sort_criteria *sc = &format_loop_sort_criteria;
 | 
			
		||||
 | 
			
		||||
	/* Make a copy of the key. */
 | 
			
		||||
	copy = copy0 = xstrndup(key, keylen);
 | 
			
		||||
@@ -4695,6 +4765,19 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
 | 
			
		||||
				break;
 | 
			
		||||
			case 'S':
 | 
			
		||||
				modifiers |= FORMAT_SESSIONS;
 | 
			
		||||
				if (fm->argc < 1)
 | 
			
		||||
					break;
 | 
			
		||||
				if (strchr(fm->argv[0], 'i') != NULL)
 | 
			
		||||
					sc->field = FORMAT_LOOP_BY_INDEX;
 | 
			
		||||
				else if (strchr(fm->argv[0], 'n') != NULL)
 | 
			
		||||
					sc->field = FORMAT_LOOP_BY_NAME;
 | 
			
		||||
				else if (strchr(fm->argv[0], 't') != NULL)
 | 
			
		||||
					sc->field = FORMAT_LOOP_BY_TIME;
 | 
			
		||||
				else sc->field = FORMAT_LOOP_BY_INDEX;
 | 
			
		||||
				if (strchr(fm->argv[0], 'r') != NULL)
 | 
			
		||||
					sc->reversed = 1;
 | 
			
		||||
				else
 | 
			
		||||
					sc->reversed = 0;
 | 
			
		||||
				break;
 | 
			
		||||
			case 'W':
 | 
			
		||||
				modifiers |= FORMAT_WINDOWS;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tmux.1
									
									
									
									
									
								
							@@ -5909,8 +5909,18 @@ or
 | 
			
		||||
.Ql L:\&
 | 
			
		||||
will loop over each session, window, pane or client and insert the format once
 | 
			
		||||
for each.
 | 
			
		||||
For windows and panes, two comma-separated formats may be given:
 | 
			
		||||
the second is used for the current window or active pane.
 | 
			
		||||
.Ql S:\& ,
 | 
			
		||||
can take an optional sort argument
 | 
			
		||||
.Ql /i\& ,
 | 
			
		||||
.Ql /n\& ,
 | 
			
		||||
.Ql /t\&
 | 
			
		||||
to sort by index, name, or time; or
 | 
			
		||||
.Ql /r\&
 | 
			
		||||
to sort in reverse order. For example,
 | 
			
		||||
.Ql S/nr:\&
 | 
			
		||||
to sort sessions by name in reverse order.
 | 
			
		||||
For each, two comma-separated formats may be given:
 | 
			
		||||
the second is used for the current window, active pane, or active session.
 | 
			
		||||
For example, to get a list of windows formatted like the status line:
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
#{W:#{E:window-status-format} ,#{E:window-status-current-format} }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user