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_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 {
 | 
					struct format_tree {
 | 
				
			||||||
	enum format_type	 type;
 | 
						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. */
 | 
							/* Now try single character with arguments. */
 | 
				
			||||||
		if (strchr("mCNst=pReq", cp[0]) == NULL)
 | 
							if (strchr("mCNSst=pReq", cp[0]) == NULL)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		c = cp[0];
 | 
							c = cp[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -4224,6 +4236,39 @@ format_session_name(struct format_expand_state *es, const char *fmt)
 | 
				
			|||||||
	return (xstrdup("0"));
 | 
						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. */
 | 
					/* Loop over sessions. */
 | 
				
			||||||
static char *
 | 
					static char *
 | 
				
			||||||
format_loop_sessions(struct format_expand_state *es, const char *fmt)
 | 
					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 cmdq_item		 *item = ft->item;
 | 
				
			||||||
	struct format_tree		 *nft;
 | 
						struct format_tree		 *nft;
 | 
				
			||||||
	struct format_expand_state	  next;
 | 
						struct format_expand_state	  next;
 | 
				
			||||||
	char				*expanded, *value;
 | 
						char				 *all, *active, *use, *expanded, *value;
 | 
				
			||||||
	size_t				  valuelen;
 | 
						size_t				  valuelen;
 | 
				
			||||||
	struct session			 *s;
 | 
						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);
 | 
						value = xcalloc(1, 1);
 | 
				
			||||||
	valuelen = 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);
 | 
							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);
 | 
							nft = format_create(c, item, FORMAT_NONE, ft->flags);
 | 
				
			||||||
		format_defaults(nft, ft->c, s, NULL, NULL);
 | 
							format_defaults(nft, ft->c, s, NULL, NULL);
 | 
				
			||||||
		format_copy_state(&next, es, 0);
 | 
							format_copy_state(&next, es, 0);
 | 
				
			||||||
		next.ft = nft;
 | 
							next.ft = nft;
 | 
				
			||||||
		expanded = format_expand1(&next, fmt);
 | 
							expanded = format_expand1(&next, use);
 | 
				
			||||||
		format_free(next.ft);
 | 
							format_free(next.ft);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		valuelen += strlen(expanded);
 | 
							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;
 | 
						struct format_modifier		 *bool_op_n = NULL;
 | 
				
			||||||
	u_int				  i, count, nsub = 0, nrep;
 | 
						u_int				  i, count, nsub = 0, nrep;
 | 
				
			||||||
	struct format_expand_state	  next;
 | 
						struct format_expand_state	  next;
 | 
				
			||||||
 | 
						struct format_loop_sort_criteria *sc = &format_loop_sort_criteria;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Make a copy of the key. */
 | 
						/* Make a copy of the key. */
 | 
				
			||||||
	copy = copy0 = xstrndup(key, keylen);
 | 
						copy = copy0 = xstrndup(key, keylen);
 | 
				
			||||||
@@ -4695,6 +4765,19 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
 | 
				
			|||||||
				break;
 | 
									break;
 | 
				
			||||||
			case 'S':
 | 
								case 'S':
 | 
				
			||||||
				modifiers |= FORMAT_SESSIONS;
 | 
									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;
 | 
									break;
 | 
				
			||||||
			case 'W':
 | 
								case 'W':
 | 
				
			||||||
				modifiers |= FORMAT_WINDOWS;
 | 
									modifiers |= FORMAT_WINDOWS;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tmux.1
									
									
									
									
									
								
							@@ -5909,8 +5909,18 @@ or
 | 
				
			|||||||
.Ql L:\&
 | 
					.Ql L:\&
 | 
				
			||||||
will loop over each session, window, pane or client and insert the format once
 | 
					will loop over each session, window, pane or client and insert the format once
 | 
				
			||||||
for each.
 | 
					for each.
 | 
				
			||||||
For windows and panes, two comma-separated formats may be given:
 | 
					.Ql S:\& ,
 | 
				
			||||||
the second is used for the current window or active pane.
 | 
					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:
 | 
					For example, to get a list of windows formatted like the status line:
 | 
				
			||||||
.Bd -literal -offset indent
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
#{W:#{E:window-status-format} ,#{E:window-status-current-format} }
 | 
					#{W:#{E:window-status-format} ,#{E:window-status-current-format} }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user