xref: /openbsd/usr.bin/tmux/names.c (revision 00b2decc)
1*00b2deccSnicm /* $OpenBSD: names.c,v 1.29 2015/08/29 00:29:15 nicm Exp $ */
2311827fbSnicm 
3311827fbSnicm /*
4311827fbSnicm  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
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 
28*00b2deccSnicm void	name_time_callback(int, short, void *);
29*00b2deccSnicm int	name_time_expired(struct window *, struct timeval *);
30f5015e68Snicm 
31311827fbSnicm void
32*00b2deccSnicm name_time_callback(unused int fd, unused short events, void *arg)
33311827fbSnicm {
34*00b2deccSnicm 	struct window	*w = arg;
35f5015e68Snicm 
36*00b2deccSnicm 	/* The event loop will call check_window_name for us on the way out. */
37*00b2deccSnicm 	log_debug("@%u name timer expired", w->id);
38*00b2deccSnicm }
39f5015e68Snicm 
40*00b2deccSnicm int
41*00b2deccSnicm name_time_expired(struct window *w, struct timeval *tv)
42*00b2deccSnicm {
43*00b2deccSnicm 	struct timeval	offset;
44*00b2deccSnicm 
45*00b2deccSnicm 	timersub(tv, &w->name_time, &offset);
46*00b2deccSnicm 	if (offset.tv_sec != 0 || offset.tv_usec > NAME_INTERVAL)
47*00b2deccSnicm 		return (0);
48*00b2deccSnicm 	return (NAME_INTERVAL - offset.tv_usec);
49f5015e68Snicm }
50f5015e68Snicm 
51f5015e68Snicm void
52*00b2deccSnicm check_window_name(struct window *w)
53f5015e68Snicm {
54*00b2deccSnicm 	struct timeval	 tv, next;
55203ea44bSnicm 	char		*name;
56*00b2deccSnicm 	int		 left;
57311827fbSnicm 
58a3560846Snicm 	if (w->active == NULL)
59a3560846Snicm 		return;
60a3560846Snicm 
61*00b2deccSnicm 	if (!options_get_number(&w->options, "automatic-rename"))
62*00b2deccSnicm 		return;
63*00b2deccSnicm 
64*00b2deccSnicm 	if (~w->active->flags & PANE_CHANGED) {
65*00b2deccSnicm 		log_debug("@%u active pane not changed", w->id);
6691e80530Snicm 		return;
67f5015e68Snicm 	}
68*00b2deccSnicm 	log_debug("@%u active pane changed", w->id);
69b0b8e5bfSnicm 
70*00b2deccSnicm 	gettimeofday(&tv, NULL);
71*00b2deccSnicm 	left = name_time_expired(w, &tv);
72*00b2deccSnicm 	if (left != 0) {
73*00b2deccSnicm 		if (!event_initialized(&w->name_event))
74*00b2deccSnicm 			evtimer_set(&w->name_event, name_time_callback, w);
75*00b2deccSnicm 		if (!evtimer_pending(&w->name_event, NULL)) {
76*00b2deccSnicm 			log_debug("@%u name timer queued (%d left)", w->id, left);
77*00b2deccSnicm 			timerclear(&next);
78*00b2deccSnicm 			next.tv_usec = left;
79*00b2deccSnicm 			event_add(&w->name_event, &next);
80*00b2deccSnicm 		} else
81*00b2deccSnicm 			log_debug("@%u name timer already queued (%d left)", w->id, left);
825b9cc8aaSnicm 		return;
83*00b2deccSnicm 	}
84*00b2deccSnicm 	memcpy(&w->name_time, &tv, sizeof w->name_time);
85*00b2deccSnicm 	if (event_initialized(&w->name_event))
86*00b2deccSnicm 		evtimer_del(&w->name_event);
87*00b2deccSnicm 
885b9cc8aaSnicm 	w->active->flags &= ~PANE_CHANGED;
895b9cc8aaSnicm 
90203ea44bSnicm 	name = format_window_name(w);
91203ea44bSnicm 	if (strcmp(name, w->name) != 0) {
92*00b2deccSnicm 		log_debug("@%u new name %s (was %s)", w->id, name, w->name);
93203ea44bSnicm 		window_set_name(w, name);
94311827fbSnicm 		server_status_window(w);
95*00b2deccSnicm 	} else
96*00b2deccSnicm 		log_debug("@%u name not changed (still %s)", w->id, w->name);
97*00b2deccSnicm 
98203ea44bSnicm 	free(name);
99311827fbSnicm }
100311827fbSnicm 
101311827fbSnicm char *
102311827fbSnicm default_window_name(struct window *w)
103311827fbSnicm {
10458034113Snicm 	char    *cmd, *s;
10558034113Snicm 
10658034113Snicm 	cmd = cmd_stringify_argv(w->active->argc, w->active->argv);
10758034113Snicm 	if (cmd != NULL && *cmd != '\0')
10858034113Snicm 		s = parse_window_name(cmd);
10958034113Snicm 	else
11058034113Snicm 		s = parse_window_name(w->active->shell);
11158034113Snicm 	free(cmd);
11258034113Snicm 	return (s);
113311827fbSnicm }
114311827fbSnicm 
115311827fbSnicm char *
116203ea44bSnicm format_window_name(struct window *w)
117203ea44bSnicm {
118203ea44bSnicm 	struct format_tree	*ft;
119203ea44bSnicm 	char			*fmt, *name;
120203ea44bSnicm 
121203ea44bSnicm 	ft = format_create();
122f426771eSnicm 	format_defaults_window(ft, w);
123f426771eSnicm 	format_defaults_pane(ft, w->active);
124203ea44bSnicm 
125203ea44bSnicm 	fmt = options_get_string(&w->options, "automatic-rename-format");
126203ea44bSnicm 	name = format_expand(ft, fmt);
127203ea44bSnicm 
128203ea44bSnicm 	format_free(ft);
129203ea44bSnicm 	return (name);
130203ea44bSnicm }
131203ea44bSnicm 
132203ea44bSnicm char *
13366fd4858Snicm parse_window_name(const char *in)
134311827fbSnicm {
13566fd4858Snicm 	char	*copy, *name, *ptr;
136311827fbSnicm 
137311827fbSnicm 	name = copy = xstrdup(in);
13866fd4858Snicm 	if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0)
13966fd4858Snicm 		name = name + (sizeof "exec ") - 1;
140311827fbSnicm 
141203ea44bSnicm 	while (*name == ' ' || *name == '-')
142311827fbSnicm 		name++;
143311827fbSnicm 	if ((ptr = strchr(name, ' ')) != NULL)
144311827fbSnicm 		*ptr = '\0';
145311827fbSnicm 
146311827fbSnicm 	if (*name != '\0') {
147311827fbSnicm 		ptr = name + strlen(name) - 1;
1483619f6a1Sray 		while (ptr > name && !isalnum((u_char)*ptr))
149311827fbSnicm 			*ptr-- = '\0';
150311827fbSnicm 	}
151311827fbSnicm 
152311827fbSnicm 	if (*name == '/')
153311827fbSnicm 		name = basename(name);
154311827fbSnicm 	name = xstrdup(name);
1557d053cf9Snicm 	free(copy);
156311827fbSnicm 	return (name);
157311827fbSnicm }
158