xref: /openbsd/usr.bin/tmux/names.c (revision 6ae61da3)
1*6ae61da3Snicm /* $OpenBSD: names.c,v 1.35 2016/07/15 09:27:35 nicm Exp $ */
2311827fbSnicm 
3311827fbSnicm /*
498ca8272Snicm  * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
5311827fbSnicm  *
6311827fbSnicm  * Permission to use, copy, modify, and distribute this software for any
7311827fbSnicm  * purpose with or without fee is hereby granted, provided that the above
8311827fbSnicm  * copyright notice and this permission notice appear in all copies.
9311827fbSnicm  *
10311827fbSnicm  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11311827fbSnicm  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12311827fbSnicm  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13311827fbSnicm  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14311827fbSnicm  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15311827fbSnicm  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16311827fbSnicm  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17311827fbSnicm  */
18311827fbSnicm 
19311827fbSnicm #include <sys/types.h>
20311827fbSnicm 
21311827fbSnicm #include <ctype.h>
22311827fbSnicm #include <libgen.h>
237d053cf9Snicm #include <stdlib.h>
24311827fbSnicm #include <string.h>
25311827fbSnicm 
26311827fbSnicm #include "tmux.h"
27311827fbSnicm 
2800b2deccSnicm void	name_time_callback(int, short, void *);
2900b2deccSnicm int	name_time_expired(struct window *, struct timeval *);
30f5015e68Snicm 
31311827fbSnicm void
32d0e2e7f1Snicm name_time_callback(__unused int fd, __unused short events, void *arg)
33311827fbSnicm {
3400b2deccSnicm 	struct window	*w = arg;
35f5015e68Snicm 
3600b2deccSnicm 	/* The event loop will call check_window_name for us on the way out. */
3700b2deccSnicm 	log_debug("@%u name timer expired", w->id);
3800b2deccSnicm }
39f5015e68Snicm 
4000b2deccSnicm int
4100b2deccSnicm name_time_expired(struct window *w, struct timeval *tv)
4200b2deccSnicm {
4300b2deccSnicm 	struct timeval	offset;
4400b2deccSnicm 
4500b2deccSnicm 	timersub(tv, &w->name_time, &offset);
4600b2deccSnicm 	if (offset.tv_sec != 0 || offset.tv_usec > NAME_INTERVAL)
4700b2deccSnicm 		return (0);
4800b2deccSnicm 	return (NAME_INTERVAL - offset.tv_usec);
49f5015e68Snicm }
50f5015e68Snicm 
51f5015e68Snicm void
5200b2deccSnicm check_window_name(struct window *w)
53f5015e68Snicm {
5400b2deccSnicm 	struct timeval	 tv, next;
55203ea44bSnicm 	char		*name;
5600b2deccSnicm 	int		 left;
57311827fbSnicm 
58a3560846Snicm 	if (w->active == NULL)
59a3560846Snicm 		return;
60a3560846Snicm 
61d89252e5Snicm 	if (!options_get_number(w->options, "automatic-rename"))
6200b2deccSnicm 		return;
6300b2deccSnicm 
6400b2deccSnicm 	if (~w->active->flags & PANE_CHANGED) {
6500b2deccSnicm 		log_debug("@%u active pane not changed", w->id);
6691e80530Snicm 		return;
67f5015e68Snicm 	}
6800b2deccSnicm 	log_debug("@%u active pane changed", w->id);
69b0b8e5bfSnicm 
7000b2deccSnicm 	gettimeofday(&tv, NULL);
7100b2deccSnicm 	left = name_time_expired(w, &tv);
7200b2deccSnicm 	if (left != 0) {
7300b2deccSnicm 		if (!event_initialized(&w->name_event))
7400b2deccSnicm 			evtimer_set(&w->name_event, name_time_callback, w);
7500b2deccSnicm 		if (!evtimer_pending(&w->name_event, NULL)) {
76*6ae61da3Snicm 			log_debug("@%u name timer queued (%d left)", w->id,
77*6ae61da3Snicm 			    left);
7800b2deccSnicm 			timerclear(&next);
7900b2deccSnicm 			next.tv_usec = left;
8000b2deccSnicm 			event_add(&w->name_event, &next);
81*6ae61da3Snicm 		} else {
82*6ae61da3Snicm 			log_debug("@%u name timer already queued (%d left)",
83*6ae61da3Snicm 			    w->id, left);
84*6ae61da3Snicm 		}
855b9cc8aaSnicm 		return;
8600b2deccSnicm 	}
8700b2deccSnicm 	memcpy(&w->name_time, &tv, sizeof w->name_time);
8800b2deccSnicm 	if (event_initialized(&w->name_event))
8900b2deccSnicm 		evtimer_del(&w->name_event);
9000b2deccSnicm 
915b9cc8aaSnicm 	w->active->flags &= ~PANE_CHANGED;
925b9cc8aaSnicm 
93203ea44bSnicm 	name = format_window_name(w);
94203ea44bSnicm 	if (strcmp(name, w->name) != 0) {
9500b2deccSnicm 		log_debug("@%u new name %s (was %s)", w->id, name, w->name);
96203ea44bSnicm 		window_set_name(w, name);
97311827fbSnicm 		server_status_window(w);
9800b2deccSnicm 	} else
9900b2deccSnicm 		log_debug("@%u name not changed (still %s)", w->id, w->name);
10000b2deccSnicm 
101203ea44bSnicm 	free(name);
102311827fbSnicm }
103311827fbSnicm 
104311827fbSnicm char *
105311827fbSnicm default_window_name(struct window *w)
106311827fbSnicm {
10758034113Snicm 	char    *cmd, *s;
10858034113Snicm 
10958034113Snicm 	cmd = cmd_stringify_argv(w->active->argc, w->active->argv);
11058034113Snicm 	if (cmd != NULL && *cmd != '\0')
11158034113Snicm 		s = parse_window_name(cmd);
11258034113Snicm 	else
11358034113Snicm 		s = parse_window_name(w->active->shell);
11458034113Snicm 	free(cmd);
11558034113Snicm 	return (s);
116311827fbSnicm }
117311827fbSnicm 
118311827fbSnicm char *
119203ea44bSnicm format_window_name(struct window *w)
120203ea44bSnicm {
121203ea44bSnicm 	struct format_tree	*ft;
122203ea44bSnicm 	char			*fmt, *name;
123203ea44bSnicm 
124229bdecfSnicm 	ft = format_create(NULL, 0);
125f426771eSnicm 	format_defaults_window(ft, w);
126f426771eSnicm 	format_defaults_pane(ft, w->active);
127203ea44bSnicm 
128d89252e5Snicm 	fmt = options_get_string(w->options, "automatic-rename-format");
129203ea44bSnicm 	name = format_expand(ft, fmt);
130203ea44bSnicm 
131203ea44bSnicm 	format_free(ft);
132203ea44bSnicm 	return (name);
133203ea44bSnicm }
134203ea44bSnicm 
135203ea44bSnicm char *
13666fd4858Snicm parse_window_name(const char *in)
137311827fbSnicm {
13866fd4858Snicm 	char	*copy, *name, *ptr;
139311827fbSnicm 
140311827fbSnicm 	name = copy = xstrdup(in);
14166fd4858Snicm 	if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0)
14266fd4858Snicm 		name = name + (sizeof "exec ") - 1;
143311827fbSnicm 
144203ea44bSnicm 	while (*name == ' ' || *name == '-')
145311827fbSnicm 		name++;
146311827fbSnicm 	if ((ptr = strchr(name, ' ')) != NULL)
147311827fbSnicm 		*ptr = '\0';
148311827fbSnicm 
149311827fbSnicm 	if (*name != '\0') {
150311827fbSnicm 		ptr = name + strlen(name) - 1;
1513619f6a1Sray 		while (ptr > name && !isalnum((u_char)*ptr))
152311827fbSnicm 			*ptr-- = '\0';
153311827fbSnicm 	}
154311827fbSnicm 
155311827fbSnicm 	if (*name == '/')
156311827fbSnicm 		name = basename(name);
157311827fbSnicm 	name = xstrdup(name);
1587d053cf9Snicm 	free(copy);
159311827fbSnicm 	return (name);
160311827fbSnicm }
161