2282 Commits
1.7 ... 2.4

Author SHA1 Message Date
Nicholas Marriott
f21cb71fbe Enter date of release. 2017-04-20 11:52:16 +01:00
Nicholas Marriott
990218739a Missing :. 2017-04-20 11:03:23 +01:00
Nicholas Marriott
e7c2f53f2a Changes to CHANGES. 2017-04-20 11:00:15 +01:00
Thomas Adam
9b2f02efbd Update CHANGES file 2017-04-20 10:39:16 +01:00
nicm
b087483538 load_cfg returns < 0 on error, not != 0. Problem reported by Kaushal Modi. 2017-04-19 22:19:22 +01:00
Nicholas Marriott
b946bf43f5 Version 2.4. 2017-04-19 13:51:49 +01:00
Nicholas Marriott
d64a815e8d Missed freezero. 2017-04-19 13:50:52 +01:00
Thomas Adam
a54309147d Merge branch 'obsd-master' 2017-04-18 18:01:17 +01:00
nicm
fb3c5efa50 Add a format for number of bytes writtent to client, useful for debugging. 2017-04-18 15:44:17 +00:00
nicm
aace1ead1e Do not check for BCE for a background colour that isn't needed, use
colour 8 instead.
2017-04-18 15:27:47 +00:00
Thomas Adam
0aa959d7a3 Merge branch 'obsd-master' 2017-04-18 16:01:18 +01:00
nicm
83ff1e9bd3 Include client name in key logging. 2017-04-18 13:34:04 +00:00
Thomas Adam
28833efb48 Merge branch 'obsd-master' 2017-04-17 10:01:13 +01:00
nicm
175d1854d4 Don't bother moving the cursor for empty lines. 2017-04-17 08:10:44 +00:00
nicm
7461c165b5 Remove a couple of redraw flags that no longer have any effect. 2017-04-17 06:40:32 +00:00
Thomas Adam
d912687be7 Merge branch 'obsd-master' 2017-04-16 22:01:19 +01:00
nicm
d566c780e5 Memory leak, from David CARLIER. 2017-04-16 20:33:46 +00:00
nicm
54bcaab70e Use EL1 to clear lines when redrawing the leftmost pane, rather than
spaces.
2017-04-16 20:32:14 +00:00
Nicholas Marriott
9583878a7b Accept NULL pointer. 2017-04-12 07:41:11 +01:00
Nicholas Marriott
d720a1487b Update imsg*.c from OpenBSD. 2017-04-11 11:51:25 +01:00
Thomas Adam
5f662d91db Merge branch 'obsd-master'
Conflicts:
	server-client.c
	tmux.1
2017-04-06 11:10:17 +01:00
nicm
94b71bcb64 Add Home and End for copy mode. 2017-04-05 12:14:18 +00:00
nicm
36882ec789 Try again to resolve problems with mistaking sessions for windows: now
do not look up windows as sessions (and panes as windows) when they are
qualified with a ':' or a '.'. So 'foo' as a window target will look for
windows and sessions called 'foo', but ':foo' will only look for
windows, and 'foo:' only for sessions. This means the common case of
using an unadorned session as a window target (send -tfoo) should
continue to work, but an explicit window will not get confused with a
session (send -t:foo).
2017-04-05 11:04:48 +00:00
nicm
9b28200578 Give each client a name. This defaults to the tty name as before but
falls back to an alternative if the tty name is not available. This is
clearer than overloading the client ttyname member and allows us to
remove the path stored in the tty struct, it should always be the same
as the client.
2017-04-05 10:49:46 +00:00
nicm
ab4a4b2ad0 cfg_file can be static. 2017-04-05 10:45:39 +00:00
Thomas Adam
05c97d7fe9 Merge branch 'obsd-master' 2017-03-25 14:01:12 +00:00
nicm
b9a4beb6e7 Write raw strings in one go rather than character at a time. 2017-03-24 14:45:00 +00:00
Nicholas Marriott
2d84ee9001 Merge branch 'master' of github.com:tmux/tmux 2017-03-24 10:06:22 +00:00
Nicholas Marriott
2e5664d2df Update imsg*.[ch] from OpenBSD, add some compat bits it needs and remove some
bits it doesn't.
2017-03-24 10:05:53 +00:00
Thomas Adam
1384525dc1 Merge branch 'obsd-master' 2017-03-24 08:01:13 +00:00
nicm
591b26e46f Show count of search results in copy mode. 2017-03-24 07:14:27 +00:00
Nicholas Marriott
e87d808594 Remove coverage and profile flags. 2017-03-22 21:59:43 +00:00
Nicholas Marriott
1cb8145dc5 Tweak some comments. 2017-03-22 21:29:07 +00:00
Nicholas Marriott
c57039bc3d Can shorten these by using LIBOBJ. 2017-03-22 19:22:32 +00:00
Nicholas Marriott
9c0520f2c5 Merge branch 'master' of github.com:tmux/tmux 2017-03-22 08:46:12 +00:00
Nicholas Marriott
c3dbbdaadf Bump automake and autoconf versions. 2017-03-22 08:45:53 +00:00
Thomas Adam
843e605b89 Merge branch 'obsd-master' 2017-03-22 08:01:17 +00:00
Nicholas Marriott
643813c6ed DEFS -> AM_CPPFLAGS. 2017-03-22 07:54:30 +00:00
Nicholas Marriott
223ed4a989 Should not need -D_POSIX_PTHREAD_SEMANTICS. 2017-03-22 07:49:27 +00:00
Nicholas Marriott
080080fa23 Use AC_USE_SYSTEM_EXTENSIONS and explicitly check for daemon() in headers. 2017-03-22 07:42:45 +00:00
nicm
df3ab87964 Add support for the strikethrough attribute (SGR 9), using the new smxx
terminfo capability. This means there are now nine attribute bits, so
anything above 0xff uses an extended cell.
2017-03-22 07:16:54 +00:00
Nicholas Marriott
3cc2486106 Merge branch 'master' of github.com:tmux/tmux 2017-03-21 21:38:03 +00:00
Nicholas Marriott
57cb6ef3a2 Add to TODO. 2017-03-21 21:28:37 +00:00
Thomas Adam
02ddd4ce70 Merge branch 'obsd-master' 2017-03-21 20:01:16 +00:00
Nicholas Marriott
b008a07ebb Do not test for term.h since we don't use the result. 2017-03-21 19:41:25 +00:00
nicm
04e17a7e11 Use uid_t for UID not u_int. 2017-03-21 19:28:03 +00:00
Nicholas Marriott
cd7550cdf1 Some __unused. 2017-03-21 19:27:18 +00:00
Nicholas Marriott
c2b53598ad Bad merge. 2017-03-21 14:48:44 +00:00
Thomas Adam
57b4d3d593 Merge branch 'obsd-master' 2017-03-21 12:01:14 +00:00
nicm
cdaa758340 Fix movement after select-line, from Omar Sandoval. 2017-03-21 09:51:00 +00:00
nicm
c916feaf29 Fix pane movement by direction (up, down, left, right) when
pane-border-status is set, from KOIE Hidetaka.
2017-03-21 09:49:10 +00:00
Thomas Adam
31ae09efa0 Merge branch 'obsd-master'
Conflicts:
	utf8.c
2017-03-20 13:45:18 +00:00
Nicholas Marriott
066575fd5a Add to TODO. 2017-03-20 11:50:54 +00:00
Nicholas Marriott
792455ce87 Tweak test for program_invocation_short_name. 2017-03-18 14:37:37 +00:00
Nicholas Marriott
4eec3270ec Clarify that release instructions will install. 2017-03-18 08:33:15 +00:00
Nicholas Marriott
640666fb36 Fix some warnings. 2017-03-17 14:55:33 +00:00
nicm
67d2335130 Fix a couple of argument types. 2017-03-17 14:51:41 +00:00
nicm
481e48d119 Add h and l for collapse and expand in choose mode with vi(1) keys, from
Gregory Pakosz.
2017-03-17 14:41:54 +00:00
Thomas Adam
1ea19245b3 Merge branch 'obsd-master' 2017-03-16 22:01:18 +00:00
nicm
b69efbdd30 Redraw after killp -a. 2017-03-16 20:05:14 +00:00
Thomas Adam
0dd694f5fd Merge branch 'obsd-master' 2017-03-15 16:01:13 +00:00
nicm
2a9d697771 Invalidate the cursor when we think we should have wrapped. 2017-03-15 15:22:14 +00:00
Thomas Adam
4e809a3130 Merge branch 'obsd-master' 2017-03-15 10:01:11 +00:00
nicm
3c3c08b6d9 Try to avoid moving the cursor to the start of the next line when
printing cells if it is already at the very end of the line and the
terminal will wrap it to the next line itself, this means terminals
still see it as a wrapped line for the purposes of their own mouse
selection. Reported by millert@.
2017-03-15 09:21:21 +00:00
Thomas Adam
cc6c6edb6f Merge branch 'obsd-master' 2017-03-13 18:01:13 +00:00
nicm
8e9b10062b Log where panes are created. 2017-03-13 17:20:11 +00:00
Thomas Adam
12c6c723a9 Merge branch 'obsd-master' 2017-03-13 12:01:13 +00:00
nicm
fd65210139 Revert previous, breaks normal short targets, reported by Theo Buehler. 2017-03-13 10:53:32 +00:00
Thomas Adam
266e662fae Merge branch 'obsd-master' 2017-03-11 16:01:12 +00:00
nicm
d455da45eb Fix calculation of size for full size splits. 2017-03-11 15:16:35 +00:00
nicm
0fe3b739a1 Only look for window and pane parts of target as a sesson and window if
they look like an ID.
2017-03-11 15:16:08 +00:00
Thomas Adam
392253f032 Merge branch 'obsd-master' 2017-03-10 00:01:16 +00:00
Nicholas Marriott
385a361bf8 Merge branch 'master' of github.com:tmux/tmux 2017-03-09 22:21:29 +00:00
Nicholas Marriott
a24cf4a5e1 Can only check for one with AC_CHECK_LIB. 2017-03-09 22:21:12 +00:00
nicm
55e73e3612 Clear the bracket paste mode when in the command prompt. 2017-03-09 22:00:46 +00:00
Thomas Adam
c5bdae466e Merge branch 'obsd-master' 2017-03-09 18:01:16 +00:00
nicm
bce1dee034 Move the client identify (display-panes) code into server-client.c. 2017-03-09 17:06:35 +00:00
nicm
dbfee6a468 Move server_fill_environ into environ.c and move some other common code
into it.
2017-03-09 17:02:38 +00:00
Nicholas Marriott
fd96ccfd80 No extra : for errx and warnx. 2017-03-09 16:49:37 +00:00
Nicholas Marriott
b79df1dc29 Compat code for strndup and strnlen. 2017-03-09 15:43:08 +00:00
Nicholas Marriott
180ebf0208 Merge branch 'master' of github.com:tmux/tmux 2017-03-09 15:39:36 +00:00
Nicholas Marriott
514a723f74 Solaris fixes, mostly from Dagobert Michelsen. 2017-03-09 15:39:13 +00:00
Thomas Adam
92434b0afd Merge branch 'obsd-master' 2017-03-08 22:01:19 +00:00
nicm
e8f2609ca4 Skip over padding cells when moving the cursor left or right. 2017-03-08 20:05:25 +00:00
Thomas Adam
41a01fc629 Merge branch 'obsd-master' 2017-03-08 16:01:15 +00:00
nicm
41b31fe240 Handle empty options correctly. 2017-03-08 14:43:40 +00:00
nicm
78ca1b0265 Always send smkx to the terminal outside, the keys we get from terminfo
are the keys when it is on.
2017-03-08 14:34:35 +00:00
Thomas Adam
3ea36830f3 Merge branch 'obsd-master' 2017-03-08 14:01:23 +00:00
nicm
6b2009ad72 Add a helper function for the most common format_create/defaults/expand
pattern.
2017-03-08 13:36:12 +00:00
Thomas Adam
5d3296c53b Merge branch 'obsd-master' 2017-03-07 15:32:28 +00:00
nicm
1e6e606f54 Need to flush before writing out cells we are not collecting, also add
some extra logging.
2017-03-07 13:48:28 +00:00
nicm
daac28febb If moving cells outside the current used count, update it. 2017-03-07 13:47:56 +00:00
Thomas Adam
69257bc0aa Merge branch 'obsd-master' 2017-03-06 10:01:21 +00:00
Nicholas Marriott
8684e60f51 Merge branch 'master' of github.com:tmux/tmux 2017-03-06 09:26:16 +00:00
Nicholas Marriott
fa27cbd035 Expand on OS X faffing, based on a diff from Kurtis Rader. 2017-03-06 09:24:41 +00:00
nicm
dc8fefe902 Collect strings correctly when on terminals that don't support UTF-8. 2017-03-06 09:02:59 +00:00
nicm
fba9ebcc0c When redrawing a combined UTF-8 characters in its existing position,
need to save and restore the cursor so that the next character goes into
the right place.
2017-03-06 09:02:36 +00:00
Thomas Adam
48a3dba6b9 Merge branch 'obsd-master' 2017-02-27 14:01:20 +00:00
Nicholas Marriott
2fa16eee53 Change to vim(1) script by Eric Pruitt. 2017-02-27 13:21:04 +00:00
nicm
e741a0bcd7 If splitw -b is used, insert the new pane before the current one in the
pane list. This means the numbering is in order (for example for
display-panes) and fixes a problem with redrawing the active pane
borders.
2017-02-27 13:07:57 +00:00
Thomas Adam
14dc2acc25 Merge branch 'obsd-master' 2017-02-22 10:01:12 +00:00
nicm
0414b1fc78 Minor bits: fix an array size, add comment, make grid_cell_entry static. 2017-02-22 09:01:32 +00:00
Thomas Adam
4b112c19f1 Merge branch 'obsd-master' 2017-02-21 18:01:12 +00:00
nicm
8a0b279c31 Change pane redraw to collect cells up as well, and simplify it a bit. 2017-02-21 16:25:04 +00:00
Thomas Adam
6b45464120 Merge branch 'obsd-master' 2017-02-21 16:01:15 +00:00
nicm
27ee34e7fa Don't need is1,is2,is3 so remove them. 2017-02-21 14:18:12 +00:00
Thomas Adam
e9819eef3c Merge branch 'obsd-master' 2017-02-21 12:01:16 +00:00
nicm
9e4c5133c8 Scrolling at least needs to be flushed before sending EL to the terminal
(but it is simpler to flush everything, so do that instead).
2017-02-21 10:30:15 +00:00
Thomas Adam
11e7915195 Reflect OBSD Makefile changes in Makefile.am 2017-02-21 09:24:53 +00:00
Thomas Adam
0ad2beae7e Merge branch 'obsd-master'
Conflicts:
	Makefile
2017-02-21 09:23:50 +00:00
Nicholas Marriott
55e76edd3c Improve NetBSD KERN_PROC2 bit, mostly from Kamil Rytarowski. 2017-02-19 08:31:05 +00:00
nicm
f27e1d07fc Add SGR 28 to clear hidden flag. 2017-02-19 07:55:11 +00:00
Nicholas Marriott
203d604bf7 Add to TODO. 2017-02-17 10:52:40 +00:00
Nicholas Marriott
ee7acde149 Update TODO. 2017-02-16 15:06:20 +00:00
nicm
82db1fa9e5 There are buggy terminals out there that do not move the cursor to 0,0
after CSR, so invalidate the cursor position rather than assuming 0,0.
2017-02-16 12:56:01 +00:00
nicm
c948c6b697 Handle insert cells when cursor at edge of screen correctly, and do a
full flush before insert.
2017-02-16 12:43:08 +00:00
nicm
c889e11375 Merge clear-history into capture-pane. 2017-02-16 12:18:38 +00:00
Thomas Adam
f734d81074 Merge branch 'obsd-master' 2017-02-16 12:01:21 +00:00
nicm
8b8d0963da Style nits. 2017-02-16 10:53:25 +00:00
Thomas Adam
c9f2dc5ee5 Merge branch 'obsd-master' 2017-02-15 12:01:15 +00:00
nicm
dd25a6cdc2 Do not clear to end of screen unless the pane is at the bottom. 2017-02-15 11:22:13 +00:00
Nicholas Marriott
47bc867ab9 Merge branch 'master' of github.com:tmux/tmux 2017-02-15 10:34:38 +00:00
Nicholas Marriott
b9b7daf3b2 Copy 24-bit-color.sh from iTerm2. 2017-02-15 10:34:20 +00:00
Thomas Adam
631a89954f Merge branch 'obsd-master' 2017-02-15 10:01:17 +00:00
Nicholas Marriott
36734afdd8 Hide or fix some warnings. 2017-02-15 08:54:21 +00:00
nicm
640d9e54b7 "status bar" -> "status line" for consistency, from Benjamin Dopplinger. 2017-02-15 08:47:55 +00:00
Nicholas Marriott
2b4c144f96 Remove vis.h. 2017-02-15 08:37:11 +00:00
Thomas Adam
ba3c1534e0 Merge branch 'obsd-master' 2017-02-14 20:01:12 +00:00
nicm
e340df2034 Make source-file look for files relative to the client working directory
(like load-buffer and save-buffer), from Chris Pickel. Also break the
where-is-this-file code out into its own function for loadb and saveb.
2017-02-14 18:13:05 +00:00
Thomas Adam
02e04477de Merge branch 'obsd-master'
Conflicts:
	server.c
2017-02-14 13:55:16 +00:00
nicm
4c2a78029d Collected cells may still need to be extended for RGB colours. 2017-02-13 16:05:30 +00:00
nicm
921880e00b Add not delete the event if more to write. 2017-02-10 15:39:43 +00:00
nicm
d22c15107b Don't use a bufferevent for the tty, so we can keep better track of what
is being written and when.

Also a manpage typo fix from jmc@.
2017-02-10 12:59:18 +00:00
nicm
c6a3446398 Instead of numbering session groups, give them a name which may be given
to -t instead of a target session. Also allow them to contain only one
session.
2017-02-09 15:04:53 +00:00
nicm
8de4c15dfa Document refresh-client -C. 2017-02-09 14:49:00 +00:00
Nicholas Marriott
c75cced07d Add to TODO. 2017-02-09 14:40:30 +00:00
Thomas Adam
96ad1d7779 Merge branch 'obsd-master' 2017-02-09 14:01:18 +00:00
nicm
b1fa3e25e4 Break the message storage function into its own function, useful for
debugging.
2017-02-09 12:09:33 +00:00
Thomas Adam
cb50a51127 Merge branch 'obsd-master' 2017-02-09 12:01:12 +00:00
nicm
b7ddfb39f3 Don't lie about the default size in the man page. 2017-02-09 12:00:42 +00:00
nicm
ddb3750c8b Combining characters need a full flush. 2017-02-09 10:09:14 +00:00
Thomas Adam
79409dc1cc Merge branch 'obsd-master' 2017-02-09 10:01:18 +00:00
nicm
fd6e46596d When an ordinary (not collected) cell is received, we need to flush any
delayed scrolling before drawing it.
2017-02-09 09:33:15 +00:00
Thomas Adam
743f772bef Merge branch 'obsd-master' 2017-02-09 02:01:17 +00:00
Thomas Adam
be033b1ed0 Merge branch 'obsd-master' 2017-02-09 00:01:12 +00:00
nicm
1811dc5271 Another helper function to write to terminal and log. 2017-02-08 23:53:03 +00:00
nicm
2f854969ff Do not adjust region lower by pane offset when scrolling up, it is
already an absolute position.
2017-02-08 22:42:07 +00:00
Thomas Adam
130b77edc7 Merge branch 'obsd-master' 2017-02-08 18:01:17 +00:00
nicm
05802a6fe3 window_copy_pagedown shouldn't reset the mode anymore, instead let the
caller do it so it can free the marks. Problem reported by attila at
stalphonsos dot com.
2017-02-08 17:33:51 +00:00
nicm
e100d465da Add support for scroll up escape sequence (CSI S) and use it when
possible instead of sending individual line feeds.
2017-02-08 17:31:09 +00:00
nicm
13a0b6bb3f Collect sequences of printable ASCII characters and process them
together instead of handling them one by one. This is significantly
faster. Sequences are terminated when we reach the end of the line, fill
the internal buffer, or a different character is seen by the input
parser (an escape sequence, or UTF-8).

Rather than writing collected sequences out immediately, hold them until
it is necessary (another screen modification, or we consume all
available data). This means we can discard changes that would have no
effect (for example, lines that would just be scrolled off the screen or
cleared). This reduces the total amount of data we write out to the
terminal - not important for fast terminals, but a big help with slow
(like xterm).
2017-02-08 16:45:18 +00:00
nicm
d4b006b9fa Fix clear start of line. 2017-02-08 16:18:20 +00:00
Thomas Adam
e09625e38b Merge branch 'obsd-master' 2017-02-08 16:01:17 +00:00
nicm
7475165cd8 Some other tidying bits. 2017-02-08 15:49:29 +00:00
nicm
ac1f294bb9 Add a helper to store a cell, and some tidying. 2017-02-08 15:41:41 +00:00
nicm
96b66f8fc3 Remove unnecessary duplicate check. 2017-02-08 15:24:48 +00:00
nicm
713f3b05f3 Improve some of the logging on resize. 2017-02-08 13:53:32 +00:00
Nicholas Marriott
9af5f3ff81 Give an example, from Timothee Cour. 2017-02-08 11:52:42 +00:00
Thomas Adam
a9a0039be4 Merge branch 'obsd-master' 2017-02-08 10:01:22 +00:00
nicm
cb80901d33 Log size of output buffer as well. 2017-02-08 08:54:45 +00:00
nicm
9cc02d1498 Trying to avoid the occasional newline by saving the last cell on screen
is not actually helping us much and just adds complexity, so don't
bother.
2017-02-08 08:50:10 +00:00
nicm
acb4bd9e56 Tweak how much we expand lines by. 2017-02-08 08:26:35 +00:00
nicm
35a0606de1 Remove event watermarks, don't work well enough to be worth it. 2017-02-08 08:25:12 +00:00
Thomas Adam
5aaf640629 Merge branch 'obsd-master' 2017-02-07 20:01:14 +00:00
nicm
c0a34821c1 Do not clear the scroll region, instead set it to the scroll region we
actually want.
2017-02-07 18:27:46 +00:00
nicm
20f5e377fb Remove a debugging leftover. 2017-02-07 18:06:42 +00:00
Thomas Adam
178289fb4c Merge branch 'obsd-master' 2017-02-07 18:01:13 +00:00
nicm
6ea36afc4b DECSLRM in xterm(1) appears to have a quirk where it can generate an
extra scroll of the entire terminal; issuing DECSTBM first prevents
this. Do that for now.
2017-02-07 17:13:28 +00:00
Thomas Adam
97fd291079 Merge branch 'obsd-master' 2017-02-07 16:01:13 +00:00
nicm
9491a5c1cf Unfortunately DECFRA does not handle default colours properly (it does
not reset colours when in SGR 0), so we can't use it without more
trouble than it is worth. Abandon the idea for now.
2017-02-07 14:33:37 +00:00
Nicholas Marriott
8872a0da8e Merge branch 'master' of github.com:tmux/tmux 2017-02-07 13:41:17 +00:00
Nicholas Marriott
0f5a2c86da Look for libtinfo before libncurses. 2017-02-07 13:40:36 +00:00
Thomas Adam
9f66fb4fd7 Merge branch 'obsd-master' 2017-02-07 00:01:13 +00:00
nicm
d60e585d9e Use DECFRA on VT420 compatible terminals (so, xterm) and ED on all
others for clearing panes.
2017-02-06 22:05:11 +00:00
Thomas Adam
dfdc23d86c Merge branch 'obsd-master' 2017-02-06 22:01:16 +00:00
Thomas Adam
7417e391d5 Merge branch 'obsd-master' 2017-02-06 20:01:15 +00:00
nicm
68e04907de Do not go through the whole attributes setting process if the new cell
is the same as the previous one.
2017-02-06 19:45:23 +00:00
nicm
10e14ae504 Add BCE for clear to start of screen, which was somehow missed. 2017-02-06 19:26:49 +00:00
Thomas Adam
1199f8fc59 Merge branch 'obsd-master' 2017-02-06 16:01:20 +00:00
nicm
e67548dc36 Cancel key table when switching session, unless the key is going to
repeat. Reported by Amos Bird.
2017-02-06 15:00:41 +00:00
Thomas Adam
446177a832 Merge branch 'obsd-master' 2017-02-06 14:01:16 +00:00
Nicholas Marriott
4eabd7ec90 Do not declare program_invocation_short_name because people can't make up their
mind what type it should be.
2017-02-06 13:34:19 +00:00
nicm
d150d9b384 Fix logging of CSI parameters. 2017-02-06 13:25:15 +00:00
nicm
3fd34e70e5 Only redraw the modified character when adding combining characters, not
the whole line.
2017-02-06 13:23:00 +00:00
Nicholas Marriott
50f25a8f05 Merge branch 'master' of github.com:tmux/tmux 2017-02-06 10:06:14 +00:00
Nicholas Marriott
c7c1018e9b Update sys/queue.h from OpenBSD. 2017-02-06 10:05:56 +00:00
Thomas Adam
7bccc82284 Merge branch 'obsd-master' 2017-02-05 02:01:12 +00:00
nicm
d091253a5d Missing va_end, from Anton Lindqvist. 2017-02-04 23:42:53 +00:00
Thomas Adam
e1c283325e Merge branch 'obsd-master' 2017-02-03 22:01:18 +00:00
nicm
5e6a8177e5 Cache status line position to reduce option lookups during output. 2017-02-03 21:01:02 +00:00
nicm
75adf8368a Expand lines more aggressively to reduce rate of allocations. 2017-02-03 20:53:03 +00:00
Thomas Adam
6c333cc486 Merge branch 'obsd-master' 2017-02-03 14:01:13 +00:00
nicm
7d23d019c0 Add a window or pane id "tag" to each format tree and use it to separate
jobs, this means that if the same job is used for different windows or
panes (for example in pane-border-format), it will be run separately for
each pane.
2017-02-03 11:57:27 +00:00
Thomas Adam
9b1f620aa0 Merge branch 'obsd-master' 2017-02-01 12:01:18 +00:00
nicm
dd0c814779 Implement "all event" (1003) mouse mode but in a way that works. The
main issue is that if we have two panes, A with 1002 and B with 1003, we
need to set 1003 outside tmux in order to get all the mouse events, but
then we need to suppress the ones that pane A doesn't want. This is easy
in SGR mouse mode, because buttons == 3 is only used for movement events
(for other events the trailing m/M marks a release instead), but in
normal mouse mode we can't tell so easily. So for that, look at the
previous event instead - if it is drag+release as well, then the current
event is a movement event.
2017-02-01 09:55:07 +00:00
Nicholas Marriott
9b9a5a292d Merge branch 'master' of github.com:tmux/tmux 2017-01-31 12:52:50 +00:00
Nicholas Marriott
c54a5d9fb3 Add wchar.h to compat.h, from Koichi Shiraishi. 2017-01-31 12:51:53 +00:00
Thomas Adam
d8da761d54 Merge branch 'obsd-master' 2017-01-31 00:01:12 +00:00
nicm
3408595f77 When a flag option is used in a format, it should use the number form
not string.
2017-01-30 21:41:17 +00:00
Thomas Adam
9094f01c6b Merge branch 'obsd-master' 2017-01-30 00:01:13 +00:00
nicm
b6099f31ea Add -n to break-pane. 2017-01-29 22:10:55 +00:00
Thomas Adam
4b482c95c3 Merge branch 'obsd-master' 2017-01-28 18:01:12 +00:00
nicm
54309cc25d Do not clear the key table when changing session on a client, so that
switch-client and friends work with bind -n.
2017-01-28 16:11:27 +00:00
Nicholas Marriott
503af3df54 This link is better. 2017-01-26 19:57:16 +00:00
Nicholas Marriott
b2e909b252 Merge branch 'master' of github.com:tmux/tmux 2017-01-26 19:55:45 +00:00
Nicholas Marriott
a4367b44fb Add ISSUE_TEMPLATE. 2017-01-26 19:55:16 +00:00
Thomas Adam
78c0b96004 Merge branch 'obsd-master' 2017-01-26 02:01:12 +00:00
nicm
776ce8a9d5 Clear option before adding to array if no -a, reported by Michael
Nickerson.
2017-01-25 23:50:51 +00:00
Nicholas Marriott
ea70e68a51 -paths.h. 2017-01-25 16:39:02 +00:00
Nicholas Marriott
0f9354eec2 Bad merge. 2017-01-25 16:38:13 +00:00
Thomas Adam
21d8f77a0d Merge branch 'obsd-master' 2017-01-25 16:01:13 +00:00
nicm
163732e89f Revert previous for now, it will break TERM=screen. 2017-01-25 14:36:08 +00:00
nicm
0a63ab4f0f If xterm-keys is on, use xterm(1) style keys for Home and End as well as
modified keys.
2017-01-25 14:24:54 +00:00
Nicholas Marriott
3e495b4001 compat/* should not include tmux.h. 2017-01-25 13:49:01 +00:00
Thomas Adam
418ab1a553 Merge branch 'obsd-master' 2017-01-24 22:01:13 +00:00
nicm
ffc28a7765 Fix set -u on array options. 2017-01-24 20:24:54 +00:00
nicm
4b2821ff98 Make update-environment an array as well. 2017-01-24 20:15:32 +00:00
nicm
b77dd75b57 Convert terminal-overrides to an array option. 2017-01-24 20:05:15 +00:00
nicm
16e43d6a42 Remove some lies about terminal-overrides from tmux.1. 2017-01-24 20:01:34 +00:00
Thomas Adam
f38a6bbd81 Merge branch 'obsd-master' 2017-01-24 20:01:12 +00:00
nicm
126d364abe server-info can become an alias rather than a command. 2017-01-24 19:59:19 +00:00
nicm
85338bb75f Add support for custom command aliases, this is an array option which
contains items of the form "alias=command". This is consulted when an
unknown command is parsed.
2017-01-24 19:53:37 +00:00
nicm
61fce272ea If given an array option without an index either show or set all items,
and support -a for array options. Allow the separator for set to be
specified in the options table (will be used for backwards compatibility
later).
2017-01-24 19:11:46 +00:00
Thomas Adam
f1282a683d Merge branch 'obsd-master' 2017-01-24 14:01:15 +00:00
Nicholas Marriott
c68ea386d1 pty.c needs compat.h. 2017-01-24 13:34:08 +00:00
nicm
3d74e89a39 Shorten a long line, and don't leak buffer in paste_add if size is zero. 2017-01-24 13:28:33 +00:00
Nicholas Marriott
a3d5bfcece Define away pledge() on !OpenBSD. 2017-01-23 12:27:58 +00:00
Nicholas Marriott
1ebe79dd62 Use forkpty() except on OpenBSD. 2017-01-23 12:26:06 +00:00
Thomas Adam
b3a724f30c Merge branch 'obsd-master'
Conflicts:
	Makefile
	tmux.c
2017-01-23 12:20:43 +00:00
nicm
98e7fbb2ac Open /dev/ptm before pledge() and save it to be used for PTMGET later
(this means inlining forkpty()).

ok deraadt
2017-01-23 10:09:43 +00:00
Thomas Adam
d2eab39ffa Merge branch 'obsd-master' 2017-01-22 20:01:12 +00:00
Nicholas Marriott
aa70f28069 Merge branch 'master' of github.com:tmux/tmux 2017-01-22 19:14:10 +00:00
Nicholas Marriott
acf331f7f1 Add b64_pton as well. 2017-01-22 19:12:15 +00:00
nicm
4ede35c48c Accept the OSC 52 escape sequence inside tmux to add a new buffer, from
harry dot gindi at live dot com.
2017-01-22 19:00:01 +00:00
Thomas Adam
c17b0a202a Merge branch 'obsd-master' 2017-01-20 16:01:11 +00:00
nicm
46572ba904 Print error rather than fatal() if tcgetattr() fails, which is much more
useful to user.
2017-01-20 14:02:33 +00:00
Nicholas Marriott
61af9d7cc2 Look for ncursesw as well as ncurses, based on a change from Bert van Hall. 2017-01-19 15:31:22 +00:00
Nicholas Marriott
b98b4e23a3 Put version in log in portable tmux. 2017-01-18 17:35:41 +00:00
Nicholas Marriott
7e4908f751 If --enable-{utf8proc,utempter} is given, do not build without it. 2017-01-18 14:32:50 +00:00
Nicholas Marriott
787f9de5d8 vis.h comes from compat.h. 2017-01-18 12:16:14 +00:00
Thomas Adam
044999ce6d Merge branch 'obsd-master' 2017-01-18 12:01:11 +00:00
nicm
faa0570309 Plain stravis() because it will mangle UTF-8 characters, so add
utf8_stravis() which calls our existing utf8_strvis() and use it instead
2017-01-18 10:08:05 +00:00
Thomas Adam
6d37984f4f Merge branch 'obsd-master' 2017-01-18 10:01:12 +00:00
nicm
4bb5a1d6a7 Run arguments through vis() as well when printing them. 2017-01-18 10:00:50 +00:00
nicm
649c0d8e91 Do not reset idx, it has just been set. 2017-01-18 08:43:21 +00:00
nicm
373541104b options_match needs to explicitly check for user options. 2017-01-18 08:40:50 +00:00
Thomas Adam
64c486ae81 Merge branch 'obsd-master' 2017-01-17 02:01:11 +00:00
nicm
6b6b0e91d0 Correctly handle -style options without all of a corresponding -fg/-bg/-attr. 2017-01-16 23:45:08 +00:00
Nicholas Marriott
c0346701df Fix VIS_DQ check. 2017-01-16 18:20:50 +00:00
Thomas Adam
7e110b9d99 Merge branch 'obsd-master' 2017-01-16 15:36:02 +00:00
Nicholas Marriott
f20e3ee62c We need VIS_DQ in vis.h as well. 2017-01-16 15:01:14 +00:00
nicm
ef15b4195f Revert WIP parts of previous I didn't mean to commit yet. 2017-01-16 14:52:25 +00:00
nicm
68db958477 getopt() has a struct option so just return to using options_entry. 2017-01-16 14:49:14 +00:00
Nicholas Marriott
997b11741c Remove vis.h which comes from compat. 2017-01-16 12:09:04 +00:00
Thomas Adam
7b60645732 Merge branch 'obsd-master' 2017-01-16 00:01:10 +00:00
Thomas Adam
c9fcb76651 Merge branch 'obsd-master' 2017-01-15 22:01:11 +00:00
nicm
52847a9518 It is silly for cmd_list_parse to return an integer error when it could
just return NULL.
2017-01-15 22:00:56 +00:00
nicm
3054846143 -q flag now needs to be checked in a couple more places. 2017-01-15 20:50:34 +00:00
nicm
2b0bc9f1c5 Major tidy up and rework of options tree and set-option/show-options
commands this pushes more of the code into options.c and ties it more
closely to the options table rather than having an unnecessary
split. Also add support for array options (will be used later). Only
(intentional) user visible change is that show-options output is now
passed through vis(3) with VIS_DQ so quotes are escaped.
2017-01-15 20:48:41 +00:00
nicm
404214b0ac Remove unused quiet option. 2017-01-15 20:16:22 +00:00
nicm
a3cf995017 Append needs to go old,new not new,old... 2017-01-15 20:14:36 +00:00
Thomas Adam
4f077fe62c Merge branch 'obsd-master' 2017-01-14 20:01:13 +00:00
nicm
e06efab9da killp -a should not kill the window if only one pane. 2017-01-14 18:53:08 +00:00
Thomas Adam
780dd7ac82 Merge branch 'obsd-master' 2017-01-13 14:01:13 +00:00
Thomas Adam
2311bbd28a Merge branch 'obsd-master' 2017-01-13 12:01:12 +00:00
nicm
08d21936e4 options_get_style return const too. 2017-01-13 11:58:49 +00:00
nicm
22a528905d Make options_get_string return const string. 2017-01-13 11:56:43 +00:00
nicm
95950bf668 Add -E to detach-client to exec a command to replace the client instead
of exiting it, useful if tmux wasn't exec'd itself. From Jenna Magius.
2017-01-13 10:12:12 +00:00
Thomas Adam
d4cb178249 Merge branch 'obsd-master' 2017-01-12 16:01:13 +00:00
nicm
24cba5907b Simplify appending to string options. 2017-01-12 15:36:35 +00:00
Thomas Adam
1eb9500644 Merge branch 'obsd-master' 2017-01-12 12:01:10 +00:00
nicm
dad3090d32 Put all palette functions together in the file. 2017-01-12 10:15:55 +00:00
Thomas Adam
4a76861925 Merge branch 'obsd-master' 2017-01-12 02:01:11 +00:00
nicm
9b6aeacdc0 aixterm colours can be used if -2 is given, as well as if TERM tells us
the terminal has >=16 colours.
2017-01-12 00:30:41 +00:00
nicm
0752fdaf6a Erm the aixterm colours should start at 8, not 7. 2017-01-12 00:24:28 +00:00
nicm
9e786030df Fix setting the palette of aixterm colours (90-97). 2017-01-12 00:19:32 +00:00
Thomas Adam
33ebb9ec39 Merge branch 'obsd-master' 2017-01-12 00:01:13 +00:00
nicm
74c40d04ea Be less aggressive about turning margins off. 2017-01-11 23:10:04 +00:00
nicm
3bb14001b9 Add some missing special keys to key_string_lookup_key, fix a mouse
check in server_client_handle_key, and tweak a comment.
2017-01-11 22:36:07 +00:00
Thomas Adam
d87ab0cadf Merge branch 'obsd-master' 2017-01-11 18:01:13 +00:00
nicm
bf6a5c056d Add a format for terminal type. 2017-01-11 16:09:57 +00:00
nicm
7497ecd979 Use a macro for looking up tty types. 2017-01-11 16:05:46 +00:00
Thomas Adam
0d19d78fff Merge branch 'obsd-master' 2017-01-11 16:01:16 +00:00
nicm
458b6eb600 Some tidying and tweaks to options code. 2017-01-11 14:56:44 +00:00
Thomas Adam
8f79b079cd Merge branch 'obsd-master' 2017-01-10 22:01:14 +00:00
Thomas Adam
db8dff6814 Merge branch 'obsd-master' 2017-01-10 20:01:12 +00:00
nicm
5526627558 Minor tidying in a couple of commands. 2017-01-10 19:45:55 +00:00
Nicholas Marriott
ba35e8f292 15 minutes is not 1800 seconds, but just remove lock-after-time because it won't work for Linux folks without additional configuration 2017-01-10 19:33:22 +00:00
Nicholas Marriott
2283f19876 -temacs-copy should now be -Tcopy-mode 2017-01-10 19:31:34 +00:00
Nicholas Marriott
152bfa02f0 Merge branch 'master' of github.com:tmux/tmux 2017-01-10 19:27:23 +00:00
Nicholas Marriott
a5c89a1802 Change around the example .tmux.conf to show some newer features. 2017-01-10 19:26:54 +00:00
nicm
aa4de2d4b2 Need to escape ; twice because the command list parser will eat one,
reported by Theo Buehler.
2017-01-10 18:10:24 +00:00
Thomas Adam
570943beb7 Merge branch 'obsd-master' 2017-01-10 14:01:12 +00:00
Thomas Adam
1e12e1d843 Merge branch 'obsd-master' 2017-01-10 12:01:10 +00:00
nicm
5ea7a00eba Quote backslash as well for %%%. 2017-01-10 11:58:30 +00:00
nicm
e78142232f Some manpage fixes: rephrase a convoluted sentence, make the names of
some keys more standard, and use Ql instead of Dq.
2017-01-10 10:08:59 +00:00
Thomas Adam
628f3ad9f4 Merge branch 'obsd-master' 2017-01-10 10:01:11 +00:00
jmc
40fddfbdd6 avoid unneccessary markup; tweaked and ok nicm 2017-01-10 07:55:48 +00:00
Thomas Adam
2c862b04af Merge branch 'obsd-master' 2017-01-09 22:01:12 +00:00
Nicholas Marriott
36619607ba Add a format for the version. 2017-01-09 21:44:19 +00:00
nicm
d2d984647e Add %if/%endif for conditionals when parsing configuration files, the
argument is a format (the new == and != are useful).
2017-01-09 21:28:56 +00:00
nicm
844f2eacf4 Add simple comparisons in formats: #{==:a,b} and #{!=:a,b} ("a" and "b"
are expanded so can compare formats). And expand the condition to
#{?a,b,c} (the "a" part) if it doesn't work as a simple lookup.

Also add FORMAT_NOJOBS flag to disable jobs in a format.
2017-01-09 21:03:25 +00:00
Thomas Adam
95f5d406e5 Merge branch 'obsd-master' 2017-01-09 20:01:12 +00:00
nicm
561b5c6fdb source-file -q needs to apply to glob(3) too. 2017-01-09 19:29:12 +00:00
nicm
5330a2a85d Run the source-file pattern through glob(3). 2017-01-09 19:27:00 +00:00
Nicholas Marriott
d90fa2ec13 Tweak TODO file. 2017-01-09 17:48:30 +00:00
Thomas Adam
325c85a5c1 Merge branch 'obsd-master' 2017-01-07 18:01:11 +00:00
Thomas Adam
29e64a8c64 Merge branch 'obsd-master' 2017-01-07 16:01:17 +00:00
nicm
c05002b0f2 Add note about ccc and initc so people who want it can see it is
possible.
2017-01-07 15:40:23 +00:00
nicm
314e933914 Add support for the OSC 4 and OSC 104 palette setting escape sequences,
from S Gilles.
2017-01-07 15:28:13 +00:00
Thomas Adam
a3428487a7 Merge branch 'obsd-master' 2017-01-06 14:01:15 +00:00
nicm
cae0fbbe8c Nits found with clang. 2017-01-06 13:26:09 +00:00
nicm
461217d0f0 Incremental search in copy mode (on for emacs keys by default) - much
the same as normal searching but updates the cursor position and marked
search terms as you type. C-r and C-s in the prompt repeat the search,
once finished searching (with Enter), N and n work as before.
2017-01-06 11:57:03 +00:00
Thomas Adam
58642011df Merge branch 'obsd-master' 2017-01-05 10:01:11 +00:00
nicm
9a56671a75 Highlight all occurrences of search string after searching in copy mode. 2017-01-05 09:07:15 +00:00
Thomas Adam
45dbbb78b0 Merge branch 'obsd-master' 2017-01-03 00:01:12 +00:00
nicm
43e8f60bc6 Escape backspace for capture-pane -P, from George Nachman. 2017-01-02 22:42:19 +00:00
Thomas Adam
f5c5847788 Merge branch 'obsd-master' 2016-12-30 16:01:15 +00:00
nicm
1015b124d5 Change the xterm-keys option to default to on, so that tmux will
generate xterm(1) escape sequences for function keys with modifiers.

With the option off most of these keys are ignored by default, except
for ctrl + arrows which use a variant that nothing else seems to use and
I don't remember why we chose. The xterm escape sequences are now the
most common.

Prompted by a question from mpi@.
2016-12-30 13:49:34 +00:00
Thomas Adam
d3328a3b1e Merge branch 'obsd-master' 2016-12-28 12:01:14 +00:00
nicm
70ba3c147f Fix the prefer unattached session behaviour of
attach-session/switch-client, reported by Thomas Sattle.
2016-12-28 10:34:34 +00:00
Nicholas Marriott
af56e50f74 utempter is no longer the default, and mention ncurses. 2016-12-20 16:28:11 +00:00
Thomas Adam
00445ebadd Merge branch 'obsd-master' 2016-12-14 20:01:11 +00:00
nicm
e36f932f62 Fix up winlink lists after swap-window. 2016-12-14 17:38:59 +00:00
Thomas Adam
dda701d95f Merge branch 'obsd-master' 2016-12-12 02:01:27 +00:00
nicm
b851c628f4 -N without arguments needs to set prefix count for the mode command, so
that M-1 etc work. Reported by Theo Buehler.
2016-12-11 22:55:25 +00:00
Thomas Adam
a64b7cfe5d Merge branch 'obsd-master' 2016-12-10 00:01:11 +00:00
nicm
bee95bf378 Spacing nits. 2016-12-09 21:39:27 +00:00
Thomas Adam
75135ded09 Merge branch 'obsd-master' 2016-12-09 00:01:12 +00:00
nicm
2a7b4bb017 Fix send-keys with UTF-8. 2016-12-08 22:15:37 +00:00
Thomas Adam
d3ede11212 Merge branch 'obsd-master' 2016-12-08 00:01:10 +00:00
nicm
5819d2a9d7 Do not clear the prompt when a message is shown, just leave it around and
return to it when the message is finished.
2016-12-07 23:03:04 +00:00
Thomas Adam
b9fa8f12d7 Merge branch 'obsd-master' 2016-12-07 10:01:12 +00:00
nicm
5ea143f521 Only skip moving the cursor if it is already in the last position _on
the same line_, fixes redraw bug reported by patrick keshishian.
2016-12-07 09:16:55 +00:00
nicm
a8f3ad4487 Make prefix work in all tables (except the prefix table). Users who want
to avoid this can set prefix to "none" and bind send-prefix
themselves. Allows C-b t be bound in the copy mode tables again, pointed
out by millert@.
2016-12-07 09:16:13 +00:00
Thomas Adam
6749a30a6e Merge branch 'obsd-master' 2016-11-30 14:01:11 +00:00
nicm
1a6156d8fd Fix check for cursor at end of line. 2016-11-30 13:20:02 +00:00
Thomas Adam
1fccfd7be5 Merge branch 'obsd-master' 2016-11-29 14:01:11 +00:00
nicm
6b46c62bb4 Make send -N work for all keys, not just in copy mode. From Artem Fokin. 2016-11-29 12:54:46 +00:00
Thomas Adam
d7837cca52 Merge branch 'obsd-master' 2016-11-28 20:01:10 +00:00
nicm
9fc925ac51 When comparing ocy to orlower in tty_cmd_cell, there is no need to add
yoff (because they are both already relative to the pane). Also fix some
other minor nits.
2016-11-28 17:50:00 +00:00
Thomas Adam
2864a31311 Merge branch 'obsd-master' 2016-11-24 20:01:10 +00:00
nicm
6f8cedb1bc The mouse valid flag needs to be correct before we fire the dragging
callback, so move the callback outside of server_client_check_mouse and
use a new special key code to indicate it.
2016-11-24 18:45:45 +00:00
Thomas Adam
a02d95a313 Merge branch 'obsd-master' 2016-11-24 16:01:11 +00:00
nicm
84319aa8f0 If in the middle of a drag, don't use an invalid key, just use
KEYC_MOUSE as a placeholder. Reported by Artem Fokin.
2016-11-24 14:38:55 +00:00
nicm
0d1be2e328 Fix so that we work out the right pane from mouse events - we were doing
so too early, before the mouse event was necessarily valid, so could end
up using the pane from the previous mouse event, or the active pane.

It is important that we use the right pane now that different panes can
have different key tables (for copy mode).

Fixes problem reported by Greg Hurrell.
2016-11-24 13:46:50 +00:00
nicm
7e6c2cb238 Make the selection able to exist independent of the cursor position, so
that it is not affected by scrolling. If MouseDragEnd1Pane is bound to
the new "stop-selection" command:

    bind -Tcopy-mode MouseDragEnd1Pane stop-selection

A selection made with the mouse will stay as it is after button 1 is
released. (It also works bound to a key.)

From Artem Fokin.
2016-11-24 13:38:44 +00:00
Thomas Adam
8a8001350d Merge branch 'obsd-master' 2016-11-23 18:01:19 +00:00
nicm
6de466cf8b For mouse keys, use the mouse pane as the default current pane. 2016-11-23 17:01:24 +00:00
nicm
24916f2f6e Error on invalid modifier keys. 2016-11-23 16:44:42 +00:00
Thomas Adam
442e49f51c Merge branch 'obsd-master' 2016-11-17 12:01:10 +00:00
nicm
3cf19d6dd0 Key running commands for #() by the unexpanded command, and run them
again if the expanded form changes (otherwise at most once per second as
usual). Fixes issues reported by Gregory Pakosz.
2016-11-17 10:06:08 +00:00
Thomas Adam
759953cb8d Merge branch 'obsd-master' 2016-11-16 14:01:11 +00:00
nicm
ddf7ac5ae4 Fix calculation of whether we need a region for drawing a cell (only if
full width and at the edge of the region), otherwise clear the region entirely.
2016-11-16 13:31:22 +00:00
Thomas Adam
06fd3b00ff Merge branch 'obsd-master' 2016-11-16 12:01:11 +00:00
nicm
a8e2d851fe Don't error if renaming a session to its current name, from shik dot
chen at gmail dot com.
2016-11-16 11:41:17 +00:00
nicm
81f1d625af Do not stop dragging when the wheel is pressed, from Artem Fokin. 2016-11-16 11:37:16 +00:00
Thomas Adam
0f5b7814b5 Merge branch 'obsd-master' 2016-11-16 10:01:10 +00:00
nicm
5636d38a9d Initialize modeprefix to 1 properly in window_pane_create, from Artem Fokin. 2016-11-16 09:22:16 +00:00
Thomas Adam
12c49fa3bd Merge branch 'obsd-master' 2016-11-16 02:01:11 +00:00
nicm
e88b74350f The target validity check used window_pane_visible but that may be false
if the pane is zoomed, so instead add a new function to just check if
the pane is actually on screen (most commands still want to accept panes
invisible by zoom). Also reject panes outside the window for various
special targets. Problem reported by Sean Haugh.
2016-11-16 00:24:03 +00:00
Thomas Adam
1afe9e98de Merge branch 'obsd-master' 2016-11-15 16:01:10 +00:00
nicm
c34a79b152 Turn on margins, with a couple of fixes (only limit to the pane for line
feeds, and do not move cursor to end for full width panes).
2016-11-15 15:17:28 +00:00
nicm
d81a5c630f And of course I just find a bug, disable previous for now. 2016-11-15 14:08:27 +00:00
nicm
0ace779cde Initial attempt to make use of left and right margins if the terminal
supports them (that is, if it advertises itself as a VT420 - probably
just xterm). These are the vertical equivalent of the scroll region and
allow much faster scrolling of panes that do not take up the full width
of the terminal.
2016-11-15 14:02:32 +00:00
Thomas Adam
fe7d9af331 Merge branch 'obsd-master' 2016-11-15 12:01:18 +00:00
nicm
9fe43d6acb Add copy-pipe-and-cancel, from Artem Fokin. 2016-11-15 09:53:23 +00:00
Thomas Adam
9908681ba8 Merge branch 'obsd-master' 2016-11-14 18:01:13 +00:00
nicm
afbf0d42a7 rotate-window needs to unzoom, problem reported by Sean Haugh. 2016-11-14 16:27:12 +00:00
Thomas Adam
7177eeaa42 Merge branch 'obsd-master' 2016-11-12 20:01:10 +00:00
nicm
db2412e2ac Apply the right fix for run -b, used the wrong diff before. 2016-11-12 19:05:53 +00:00
nicm
b7398a4918 Do not execute commands for a client until it has identified, fixes
problem reported by Frank Terbeck.
2016-11-12 19:04:41 +00:00
Thomas Adam
afdef6d122 Merge branch 'obsd-master' 2016-11-11 12:01:11 +00:00
nicm
36f8fa316d Do not crash with run-shell -b and no window pane available, reported by
Sergei Dyshel.
2016-11-11 11:37:25 +00:00
Thomas Adam
13f1a922e1 Merge branch 'obsd-master' 2016-11-04 20:01:11 +00:00
nicm
f947d25c9d Do not try to set the CHANGED flag on windows with no active pane, fixes
problem reported by Nelo-T Wallus.
2016-11-04 18:56:25 +00:00
Thomas Adam
1de107c405 Merge branch 'obsd-master' 2016-11-04 16:01:11 +00:00
nicm
353439acee enum values need to fit in 32 bits; we only use enum for numbering and
Unicode characters fit in 24 bits, so we can leave key_code as 64 bits
and change KEYC_BASE down to 0x10000000.
2016-11-04 14:47:38 +00:00
Nicholas Marriott
a44024a795 Note about TERM. 2016-11-04 13:18:09 +00:00
Thomas Adam
15b6774f9b Merge branch 'obsd-master' 2016-11-02 14:01:10 +00:00
nicm
382e09bed1 Make an empty state on error rather than leaving something partially
created (which now is now a fatal() later).
2016-11-02 13:35:36 +00:00
Thomas Adam
5da94182ae Merge branch 'obsd-master' 2016-11-01 10:01:10 +00:00
nicm
c83feeb6f8 Clear window alert flags after setting winlink alert flags, fixes problem
reported by Tommy Allen.
2016-11-01 09:07:18 +00:00
Nicholas Marriott
178894b0fe Do not force symbols to width 1, from Yen Chi Hsuan. 2016-10-28 19:58:14 +01:00
Nicholas Marriott
4dbbcff72b Merge branch 'master' of github.com:tmux/tmux 2016-10-27 18:28:53 +01:00
Nicholas Marriott
4aa5dd0ee0 Add a CONTRIBUTING file with some information on opening issues. 2016-10-27 18:28:21 +01:00
Thomas Adam
b6f00a3945 Merge branch 'obsd-master' 2016-10-26 14:01:13 +01:00
nicm
abea17afd9 Buffer name can be NULL, check before strdup(). 2016-10-26 11:48:07 +00:00
Thomas Adam
f523fddf6a Merge branch 'obsd-master' 2016-10-25 10:01:09 +01:00
nicm
99946aaaaf Do not handle activity or silence alerts in the current window, reported
by jasper@.
2016-10-25 07:24:10 +00:00
Thomas Adam
5f9ba2f223 Merge branch 'obsd-master' 2016-10-21 16:01:11 +01:00
nicm
8084a2c9e6 Add %%% to substitute with quotes escaped (convert " to \"). Use this
for the prompts in copy mode. Fixes problems with jumping to ' reported
by Theo Buehler.
2016-10-21 13:51:59 +00:00
Nicholas Marriott
b951f0621c Put AM_* back, but this time do a dance in configure.ac so that we can keep
using CFLAGS for the tests.
2016-10-19 15:20:21 +01:00
Thomas Adam
28a31201d3 Merge branch 'obsd-master' 2016-10-19 12:01:11 +01:00
nicm
99c262b7d0 Do not have a default binding for C-b in copy-mode-vi or it conflicts
with the default prefix. Reported by natano@.
2016-10-19 09:24:57 +00:00
nicm
899e629bf0 Alerts are too slow, so rather than walking all sessions and windows,
add a link of winlinks to each window and a pointer to the session to
each winlink. Also rewrite the alerts processing to return to the old
behaviour (alert in any window sets the flag on any winlink).
2016-10-19 09:22:07 +00:00
Thomas Adam
4c6eb6cc2f Merge branch 'obsd-master' 2016-10-19 10:01:10 +01:00
nicm
bc27451e15 Move session-create hook out of session_create so it works with grouped sessions. 2016-10-19 08:17:11 +00:00
Nicholas Marriott
1fbb7f1a41 Merge branch 'master' of github.com:tmux/tmux 2016-10-18 23:23:49 +01:00
Nicholas Marriott
3742f66abb Revert the AM_* change, I can't find a way to make AC_CHECK_HEADER use
LIBEVENT_CFLAGS.
2016-10-18 23:19:08 +01:00
Thomas Adam
3a6beea064 Merge branch 'obsd-master' 2016-10-18 22:01:12 +01:00
nicm
e0e9a54a32 Clear cell entry with grid_default_entry not grid_default_cell. 2016-10-18 19:52:49 +00:00
Nicholas Marriott
ec47907772 I don't remember why we have make clean in dist-hook; remove it. 2016-10-18 20:41:31 +01:00
Nicholas Marriott
bd1dc89a5d *.h can go in dist_tmux_SOURCES, from Dilyan Palauzov. 2016-10-18 20:34:18 +01:00
nicm
fb109ae97d xterm-keys was in the wrong place in the list; Dilyan Palauzov. 2016-10-18 19:25:26 +00:00
Nicholas Marriott
66d637be3d Merge branch 'master' of github.com:tmux/tmux 2016-10-18 20:21:13 +01:00
Nicholas Marriott
ba9f47c544 Rename found_debug to enable_debug. 2016-10-18 20:19:24 +01:00
Thomas Adam
9b991a7301 Merge branch 'obsd-master' 2016-10-18 18:01:11 +01:00
Thomas Adam
0041e40ca8 Merge branch 'obsd-master' 2016-10-18 16:01:11 +01:00
nicm
a0998e42b7 Make grid_clear_cell set up the entry properly for 256 and RGB cells. 2016-10-18 14:56:17 +00:00
nicm
cf7289662f Tweak a couple of log statements. 2016-10-18 12:51:26 +00:00
Thomas Adam
8576ecaf32 Merge branch 'obsd-master' 2016-10-18 12:01:10 +01:00
Thomas Adam
b3ab39c4d9 Merge branch 'obsd-master' 2016-10-18 10:01:11 +01:00
nicm
2e5c49a1fd Give each item on queue a name for better logging. 2016-10-18 08:46:43 +00:00
nicm
8763bced76 Zero dirty count after flushing. 2016-10-18 08:39:18 +00:00
nicm
c2f88373e7 Store the right size in the pipe offset for pipe-pane. 2016-10-18 07:38:16 +00:00
Nicholas Marriott
7d5fd5fcd0 Preserve existing AM_CPPFLAGS and AM_LDFLAGS values. 2016-10-17 21:51:21 +01:00
Nicholas Marriott
f6c49cecc1 One extra empty line not in OpenBSD, and tweak a #define style. 2016-10-17 19:25:45 +01:00
Nicholas Marriott
7ba845297f CFLAGS/CPPFLAGS/LDFLAGS -> AM_*, requested by Dilyan Palauzov. 2016-10-17 19:14:56 +01:00
Nicholas Marriott
733185d0a9 Can use enable_* rather than adding our own found_* variables, from Dilyan Palauzov. 2016-10-17 19:09:38 +01:00
Thomas Adam
d54e990c4f Merge branch 'obsd-master' 2016-10-17 00:01:11 +01:00
nicm
fe106842c8 Use notifys for alerts too. 2016-10-16 22:18:04 +00:00
nicm
41e633acf5 Use the notify name string instead of going via an enum and change
existing hooks to use notifys instead.
2016-10-16 22:06:40 +00:00
Thomas Adam
1a6e696b08 Merge branch 'obsd-master' 2016-10-16 22:01:14 +01:00
Nicholas Marriott
d401340c51 Update TODO. 2016-10-16 20:59:43 +01:00
nicm
d15d54c2c8 Add hook_session and hook_window formats to get information on the
affected session or window when a hook fires. Enable session-created and
session-closed hooks now that that is available.
2016-10-16 19:55:52 +00:00
nicm
3f35b5299f Provide a way for hooks to tag formats onto the commands they fire so
that the user can get at additional information - now used for the
"hook" format, more to come.
2016-10-16 19:36:37 +00:00
nicm
026ad08b56 Notifys can go via the command queue instead of using their own queue. 2016-10-16 19:15:02 +00:00
nicm
b342bd0b46 Mass rename struct cmd_q to struct cmdq_item and related. 2016-10-16 19:04:05 +00:00
Thomas Adam
c67b702588 Merge branch 'obsd-master' 2016-10-16 20:01:10 +01:00
nicm
ddc4512d2e Rewrite command queue handling. Each client still has a command queue,
but there is also now a global command queue. Instead of command queues
being dispatched on demand from wherever the command happens to be
added, they are now all dispatched from the top level server
loop. Command queues may now also include callbacks as well as commands,
and items may be inserted after the current command as well as at the end.

This all makes command queues significantly more predictable and easier
to use, and avoids the complex multiple nested command queues used by
source-file, if-shell and friends.

A mass rename of struct cmdq to a better name (cmdq_item probably) is
coming.
2016-10-16 17:55:14 +00:00
Thomas Adam
3d8efdf310 Merge branch 'obsd-master' 2016-10-16 02:01:11 +01:00
nicm
bfe14b5312 Only use pane with run-shell if -t is given. 2016-10-15 23:06:39 +00:00
Thomas Adam
a15939b502 Merge branch 'obsd-master' 2016-10-15 14:01:10 +01:00
jmc
4fbf564292 zap double .Pp; 2016-10-15 12:34:02 +00:00
Thomas Adam
59d1147469 Merge branch 'obsd-master' 2016-10-15 12:01:14 +01:00
nicm
e7990375cb Give window_create and window_create1 better names. 2016-10-15 09:27:52 +00:00
Thomas Adam
623e54788e Merge branch 'obsd-master' 2016-10-15 02:01:12 +01:00
nicm
3f138dc40c Rename a function for consistency and some spacing nits. 2016-10-15 00:12:58 +00:00
nicm
63b2547a02 Fire hooks on the simple notifys (window-renamed and session-renamed),
the complicated ones get no hooks for now (more to come).
2016-10-15 00:09:30 +00:00
nicm
9b3ae84993 Drain notifys once at the end of the server loop instead of doing it
from the end of every command queue (which could be nested).
2016-10-15 00:01:01 +00:00
Thomas Adam
3d2686a236 Merge branch 'obsd-master' 2016-10-15 00:01:10 +01:00
nicm
ed971268be Add CMD_AFTERHOOK flag to the easy commands that don't need any special handling. 2016-10-14 22:14:22 +00:00
nicm
d413a945ac Don't make assumptions about line wrap on !xenl terminals, means that
using a wrong TERM without xenl is not so broken if used on a sensible
terminal.
2016-10-14 21:48:00 +00:00
Thomas Adam
9d58febc8f Merge branch 'obsd-master' 2016-10-14 22:01:11 +01:00
Thomas Adam
33fbf82ac0 Merge branch 'obsd-master' 2016-10-14 20:01:13 +01:00
nicm
1721d1994e source-file and some other commands can recurse back into cmdq_continue,
which could potentially free the currently running command, so we need
to take a reference to it in cmdq_continue_one.

Fixes problem reported by Theo Buehler.
2016-10-14 18:41:53 +00:00
nicm
0ec18e537d Missing flags in capture-pane, and tweak choose-tree text. From Dilyan Palauzov. 2016-10-14 17:40:47 +00:00
Thomas Adam
117737c6ca Merge branch 'obsd-master' 2016-10-14 02:01:14 +01:00
Thomas Adam
a7ce19347a Merge branch 'obsd-master' 2016-10-14 00:01:13 +01:00
nicm
4289a1ebfa Trying to do hooks generically is way too complicated and unreliable and
confusing, particularly trying to automatically figure out what target
hooks should be using. So simplify it:

- drop before hooks entirely, they don't seem to be very useful;

- commands with special requirements now fire their own after hook (for
  example, if they change session or window, or if they have -t and -s
  and need to choose which one the hook uses as current target);

- commands with no special requirements can have the CMD_AFTERHOOK flag
  added and they will use the -t state.

At the moment new-session, new-window, split-window fire their own hook,
and display-message uses the flag. The remaining commands still need to
be looked at.
2016-10-13 22:48:51 +00:00
Nicholas Marriott
5d2288b22a Update TODO. 2016-10-13 22:40:20 +01:00
nicm
7a1a01feef Remove the set-remain-on-exit option, it was always a hack and can now
be done with hooks instead.
2016-10-13 21:37:03 +00:00
Nicholas Marriott
e6f7180af1 tmux no longer uses openat() so we can remove the compatibilty function. 2016-10-13 22:17:29 +01:00
Thomas Adam
ad5a561adb Merge branch 'obsd-master' 2016-10-13 22:01:12 +01:00
nicm
4179b42424 Add support for BCE (background colour erase). This makes various escape
sequences (notable EL and ED but also IL, DL, ICH, DCH) create blank
cells using the current background colour rather than the default
colour.

On modern systems BCE doesn't really have many benefits, but most other
terminals now support it, some (lazy) applications rely on it, and it is
not hard to include now that we have pane background colours anyway.

Mostly written by Sean Haugh.
2016-10-13 20:27:27 +00:00
Nicholas Marriott
f691d46a16 Update TODO. 2016-10-13 21:14:33 +01:00
nicm
1bd08f903b Remove mention of key tables than no longer exist. 2016-10-13 20:09:19 +00:00
Thomas Adam
6270392d04 Merge branch 'obsd-master' 2016-10-13 12:01:11 +01:00
nicm
4d9e6ea310 Some improvements and bug fixes for hooks:
- Prepare the state again before the "after" hooks are run, because the
  command may have killed or moved windows.

- Use the hooks list from the newly prepared target, not the old hooks
  list (only matters for new-session really).

- Correctly detect an invalid current state and ignore it in
  cmd_find_target ("killw; swapw").

- Change neww, new, killp, killw, splitw, swapp, swapw to update the
  current state (used if no explicit target is given) to something more
  useful after they have finished. For example, neww changes it to the
  newly created window.

Hooks are still relatively new and primitive so there are likely to be
more changes to come.

Parts based on bug reports from Uwe Werler and Iblis Lin.
2016-10-13 10:01:49 +00:00
nicm
05dac2e42c -f missed from splitw usage, from Felix Rosencrantz. 2016-10-13 09:06:48 +00:00
Thomas Adam
6551f4bb3b Merge branch 'obsd-master'
Conflicts:
	paste.c
2016-10-13 08:09:47 +01:00
nicm
e0add119ea Compare to see if pane status line has actually changed, not just size, and
do not draw if pane is not visible.
2016-10-12 17:36:52 +00:00
nicm
e83ebf50de Fix a couple of problems with insert mode: flush dirty cells before we
modify the screen, not after; and use grid_view_insert_cells to make
space not grid_move_cells.
2016-10-12 15:43:51 +00:00
nicm
40253048ca bind-key -c has gone, remove from man page, and unused table declarations. 2016-10-12 15:26:37 +00:00
nicm
c484c5a2a1 Drop the edit mode key tables and just use fixed key bindings for the
command prompt.
2016-10-12 14:50:14 +00:00
nicm
4160df4ca4 Redraw selection in tty_draw_line, so it appears when redrawing whole
pane. Reported by Theo Buehler.
2016-10-12 13:24:07 +00:00
nicm
68bebe1fb7 The repeat prompt in both emacs and vi (and the old one in tmux) doesn't
support line editing and instead executes a command as soon as a
non-number key is pressed. Add a -N flag to command-prompt for the same
in copy mode. Reported by Theo Buehler.
2016-10-12 13:03:27 +00:00
Nicholas Marriott
76a9e6f27b NetBSD needs _OPENBSD_SOURCE for reallocarray. 2016-10-12 10:52:04 +01:00
nicm
22a8afee9e Unused variable and missing time.h. 2016-10-12 09:07:58 +00:00
Thomas Adam
12efb40dc5 Linux: #include <time.h> for time() 2016-10-12 09:53:30 +01:00
Thomas Adam
0f7d39c410 Add missing function protype 2016-10-12 09:49:16 +01:00
Thomas Adam
b9dc855016 Merge branch 'obsd-master'
Conflicts:
	format.c
	osdep-openbsd.c
2016-10-12 09:45:49 +01:00
nicm
5c49e1d0c1 Some other stuff that can be local to one file. 2016-10-11 13:45:47 +00:00
nicm
e45401846f Add static in window-*.c and move some internal functions out of tmux.h. 2016-10-11 13:21:59 +00:00
nicm
85d7afaefc Support double and triple clicks (they are cumulative, so double is
fired then triple), and use for select-word and select-line in copy
mode. Inspired by a different solution from Omar Sandoval.
2016-10-11 09:30:36 +00:00
nicm
76d6d3641f Fundamental change to how copy mode key bindings work:
The vi-copy and emacs-copy mode key tables are gone, and instead copy
mode commands are bound in one of two normal key tables ("copy-mode" or
"copy-mode-vi"). Keys are bound to "send-keys -X copy-mode-command". So:

    bind -temacs-copy C-Up scroll-up
    bind -temacs-copy -R5 WheelUpPane scroll-up

Becomes:

    bind -Tcopy-mode C-Up send -X scroll-up
    bind -Tcopy-mode WheelUpPane send -N5 -X scroll-up

This allows the full command parser and command set to be used - for
example, we can use the normal command prompt for searching, jumping,
and so on instead of a custom one:

    bind -Tcopy-mode C-r command-prompt -p'search up' "send -X search-backward '%%'"

command-prompt also gets a -1 option to only require on key press, which
is needed for jumping.

The plan is to get rid of mode keys entirely, so more to come eventually.
2016-10-11 07:23:34 +00:00
nicm
8b804fb589 Support UTF-8 entry into the command prompt. 2016-10-11 07:11:40 +00:00
nicm
a81685bfac Add static in cmd-* and fix a few other nits. 2016-10-10 21:51:39 +00:00
nicm
c426e485e5 Loads more static, except for cmd-*.c and window-*.c. 2016-10-10 21:29:23 +00:00
Thomas Adam
27126f8797 Merge branch 'obsd-master' 2016-10-10 20:01:11 +01:00
nicm
66b5477cc1 Do not allow the opposite pane to resize when dragging with the mouse
because it is not possible to keep the mouse on the border when the
minimum size is reached.
2016-10-10 17:28:30 +00:00
Thomas Adam
226b6a2192 Merge branch 'obsd-master' 2016-10-10 16:01:12 +01:00
nicm
7d4b416fe6 Some more static. 2016-10-10 13:54:47 +00:00
Thomas Adam
215d3f8c0d Merge branch 'obsd-master' 2016-10-09 18:01:10 +01:00
nicm
b8f2dd8237 Make the CLIENT_STATUS flag imply that pane status lines are redrawn if
they are enabled and break the actual screen generation code into a
separate function. Fixes problems reported by Romain Francoise.
2016-10-09 16:24:34 +00:00
Thomas Adam
526e860a7a Merge branch 'obsd-master' 2016-10-09 10:01:12 +01:00
nicm
1db6d6fea6 Pass file/line to new command for if-shell so that errors appear
sensibly.
2016-10-09 08:06:51 +00:00
nicm
48dd250af1 Handle NULL window or session for user options. 2016-10-09 07:58:35 +00:00
nicm
44449b305b Use xsnprintf not snprintf for the prompt in window_copy_write_line
because we don't care if it is truncated to the screen width, we don't
want it to be fatal.
2016-10-09 07:30:28 +00:00
Thomas Adam
fb0b2cd37a Merge branch 'obsd-master' 2016-10-06 00:01:11 +01:00
nicm
30086e504c screen_write_copy tried to be clever and clear the line if it reached
the end of the source, but it was wrong and causes problems that are
only showing up now we are more aggressive about skipping redundant
screen updates. Remove the optimization entirely as more trouble than it
is worth to fix (and it'll have to go when BCE is done anyway).
2016-10-05 22:00:29 +00:00
Thomas Adam
5b8f033e06 Merge branch 'obsd-master' 2016-10-05 14:01:10 +01:00
nicm
f55c991a1b Wrap some long lines in screen-write.c. 2016-10-05 12:36:36 +00:00
nicm
4117a7ed19 Keep buffer creation time and add accessors for it and the order number. 2016-10-05 12:34:05 +00:00
nicm
b4f95c43fc Allow cmd_mouse_at return arguments to be NULL. 2016-10-05 12:32:13 +00:00
Thomas Adam
4740ecbeae Merge branch 'obsd-master' 2016-10-04 02:01:11 +01:00
Thomas Adam
ddfed259f6 Merge branch 'obsd-master' 2016-10-04 00:01:11 +01:00
nicm
1b31d148c9 Remove some dead code in cmd-move-window.c and make a load of local
functions static.
2016-10-03 22:52:11 +00:00
Thomas Adam
6943fbbb81 Merge branch 'obsd-master' 2016-10-03 22:01:12 +01:00
nicm
305c832a97 Document set-hook -u. 2016-10-03 20:58:39 +00:00
nicm
61dfbe702e Remove some redundant checks and make ich/dch consistent. 2016-10-03 19:19:18 +00:00
Thomas Adam
23254f59da Fix typos 2016-09-30 09:50:40 +01:00
Thomas Adam
bb7cc8e8fd Start working on 2.4 2016-09-29 22:00:00 +01:00
Thomas Adam
52869ed182 Release tmux 2.3 2016-09-29 21:54:12 +01:00
Thomas Adam
19104d592b Merge branch 'obsd-master' 2016-09-29 12:01:11 +01:00
nicm
cf7f3a436a Check padding when writing any character with width > 1, in case they
overlap after the first character (for example with cells xy and ab, y
is replacing a).
2016-09-29 08:50:43 +00:00
Thomas Adam
c41916ee16 Merge branch 'obsd-master' 2016-09-28 18:01:11 +01:00
nicm
bb5798aa0e Couple of vasprintf -> xvasprintf. 2016-09-28 14:40:07 +00:00
Thomas Adam
27591570c4 Merge branch 'obsd-master' 2016-09-28 10:01:11 +01:00
nicm
acacb718e5 Rate limit TIOCSWINSZ on a timer to avoid programs getting hammered with
SIGWINCH when the size changes rapidly. To help a problem reported by
Rui Pinheiro.
2016-09-28 08:30:44 +00:00
Thomas Adam
30f2e8ff29 Merge branch 'obsd-master' 2016-09-26 12:01:12 +01:00
nicm
69e980602b Support set -a (append) with user options, suggested by Xandor Schiefer. 2016-09-26 09:02:34 +00:00
Nicholas Marriott
cbde98f67b Merge branch 'master' of github.com:tmux/tmux 2016-09-16 18:09:51 +01:00
Thomas Adam
895f1d93d5 Merge branch 'obsd-master' 2016-09-16 16:01:16 +01:00
nicm
eb50e7a2c8 Swap watermarks from high (4096) to low (128) when we get full buffers
into the read callback several times in succession; swap back when we
see empty buffers several times. This hopefully limits how much programs
that print a lot for a long period can monopolize tmux (like large, fast
compiling), without penalizing programs that print a lot briefly (like
most curses applications). Helps a lot for me, the actual numbers may
need tweaking later.
2016-09-16 13:43:41 +00:00
Nicholas Marriott
6e8f400edc Do not use utf8proc by default. 2016-09-15 20:37:48 +01:00
Thomas Adam
a5b29a1250 Merge branch 'obsd-master' 2016-09-12 18:01:12 +01:00
nicm
2e5584c2b4 Allow repeat count to be specified in mode key tables with bind-key -R,
and set the default repeat count to 5 for WheelUp and WheelDown in
copy-mode.
2016-09-12 15:40:58 +00:00
Nicholas Marriott
060515684d Apple have changed their API again, from Gregory Pakosz. 2016-09-12 11:06:35 +01:00
Nicholas Marriott
c6cdab1f79 Use ncurses OR curses, don't mix header and library. Tested by Rob Paisley. 2016-09-08 19:28:56 +01:00
Nicholas Marriott
3ed0973493 Solaris build fixes from Rob Paisley. 2016-09-08 15:32:15 +01:00
Thomas Adam
f68a908c8a Merge branch 'obsd-master' 2016-09-04 20:01:16 +01:00
nicm
fed1e384ad Add support for performing a full width split (with splitw -f), rather
than splitting the current cell. From Stephen Kent.
2016-09-04 17:37:06 +00:00
Thomas Adam
999c1c771b Merge branch 'obsd-master' 2016-09-03 00:01:14 +01:00
Nicholas Marriott
727ce7e4bb Check for headers for ncurses and libevent as well as libraries. 2016-09-02 22:05:06 +01:00
nicm
2627ab322e Remember the number of lines scrolled into the history (versus cleared
into the history) and when resizing only use scrolled lines and not
cleared lines (which are probably not intended to reappear). From
Chaoren Lin.
2016-09-02 20:57:20 +00:00
Nicholas Marriott
6c94774b70 Add support for using utf8proc with --enable-utf8proc, useful for platforms
(like OS X) where the system implementation is crap. From Joshua Rubin.
2016-09-01 20:40:03 +01:00
Thomas Adam
ae297cb487 Merge branch 'obsd-master' 2016-08-28 02:01:11 +01:00
nicm
537964b92d Kill empty window after moving pane and updating current window, so that
index is still valid before renumber-windows happens. Fixes issue
reported by Eric Pruitt.
2016-08-27 23:35:00 +00:00
Thomas Adam
1bc467fe52 Merge branch 'obsd-master' 2016-08-25 12:01:10 +01:00
nicm
6bf033beae Do not crash if display-message used without a client, issue reported by
Serge Aleynikov, fix from Thomas Adam.
2016-08-25 09:33:14 +00:00
Thomas Adam
88eb302221 Merge branch 'obsd-master' 2016-08-22 22:01:13 +01:00
nicm
43f292b2e0 Two minor fixes from dilyan palauzov. 2016-08-22 20:07:58 +00:00
Thomas Adam
baf1550227 Merge branch 'obsd-master' 2016-08-03 12:01:11 +01:00
nicm
f811127bb6 We only replace the first %%, not multiple (use %2 for second). 2016-08-03 09:08:40 +00:00
nicm
f8cc48a43f Fix minimum size when pane status line is enabled, reported by Y Petremann. 2016-08-03 09:07:02 +00:00
Nicholas Marriott
af38936473 Merge branch 'master' of github.com:tmux/tmux 2016-07-19 10:43:10 +01:00
Nicholas Marriott
0e11036055 Add to .mailmap. 2016-07-19 10:42:44 +01:00
Thomas Adam
a24260bb23 Merge branch 'obsd-master' 2016-07-15 12:01:10 +01:00
nicm
9436a31603 Tweak output of environment logging. 2016-07-15 09:52:34 +00:00
nicm
1718420c48 Log environment to new panes. 2016-07-15 09:28:32 +00:00
nicm
68b1fd0cc6 Wrap some long lines and apply some static. 2016-07-15 09:27:35 +00:00
Thomas Adam
d4eeeb5498 Merge branch 'obsd-master' 2016-07-15 04:01:12 +01:00
nicm
0f73af876f Don't update cells in each block of data read from a pane immediately,
instead track them as change (dirty) and update them once at the end,
saves much time if repeatedly writing the same cell. Also fix comparison
of cells being equal in a few places (memcmp is not enough).
2016-07-15 00:49:08 +00:00
nicm
1fd6ca2260 Instead of representing colours in several different forms with various
cell flags, convert to use an int with flags marking 256 or RGB colours
in the top byte (except in cells, which we don't want to make any
bigger). From Brad Town.
2016-07-15 00:42:56 +00:00
Thomas Adam
2d843b5021 Merge branch 'obsd-master' 2016-07-07 12:01:11 +01:00
semarie
fc118e13a9 tmux: only consider ACCESSPERMS for setting mode on socket_path.
it explicitly removes any S_ISUID|S_ISGID|S_ISTXT bits, instead of letting
pledge(2) silenciously remove them.

ok nicm@ beck@ deraadt@
2016-07-07 09:24:09 +00:00
Nicholas Marriott
25e128d398 Remove duplicate daemon.c and time.h. 2016-06-27 10:57:02 +01:00
Thomas Adam
93f42d360b Merge branch 'obsd-master' 2016-06-16 14:01:11 +01:00
nicm
325cbe90d9 Allow a command to be specified to display-panes, similar to
command-prompt, rather than always just selecting the pane.
2016-06-16 10:55:47 +00:00
Thomas Adam
d35a9ac5f2 Linux: <time.h> 2016-06-16 11:43:05 +01:00
Thomas Adam
1ad7c6b8f8 Merge branch 'obsd-master' 2016-06-15 18:01:11 +01:00
nicm
0c7ddae2ab Add missing buffer_name format, from Awal Garg. 2016-06-15 14:43:06 +00:00
Thomas Adam
5c12230a08 Merge branch 'obsd-master' 2016-06-15 12:01:11 +01:00
nicm
bee3e3e28d Copy mode needs to keep the original grid intact so it can copy from it
if needed, so it disables reading from the pane. This can be problem
with some programs. So make tmux automatically exit all modes after 180
seconds of inactivity and if there is pending output.
2016-06-15 09:13:46 +00:00
nicm
068b8b03ad Add -F to list-commands. 2016-06-15 08:54:11 +00:00
Nicholas Marriott
150c9f3fe0 Add *.dSYM for OS X. 2016-06-15 09:51:08 +01:00
Nicholas Marriott
697b912f26 Merge branch 'master' of github.com:tmux/tmux 2016-06-10 16:38:52 +01:00
Nicholas Marriott
b9c95937ed Add to TODO. 2016-06-10 16:38:40 +01:00
Thomas Adam
1a53e79057 Merge branch 'obsd-master' 2016-06-10 14:01:10 +01:00
Nicholas Marriott
c84ed36719 Spelling, from Josh Soref. 2016-06-10 12:47:15 +01:00
nicm
17e4744459 Spelling error (incrased -> increased), from Josh Soref. 2016-06-10 11:46:15 +00:00
Thomas Adam
fa68d0a16e Merge branch 'obsd-master' 2016-06-06 12:01:10 +01:00
nicm
d9450bfccd Much faster (and smaller) method of mapping RGB colour to an xterm(1)
colour, from Avi Halachmi.
2016-06-06 10:12:58 +00:00
Thomas Adam
cc096ae929 Merge branch 'obsd-master' 2016-06-06 10:01:11 +01:00
Nicholas Marriott
1f75c98f49 Note how to subscribe to ML. 2016-06-06 09:30:39 +01:00
nicm
aba4438013 Cache selected state so that cells going from selected to unselected are not
skipped, reported by Omar Sandoval.
2016-06-06 07:28:52 +00:00
nicm
00cf5fbde6 Insert new panes after the pane being split in the list rather than
always after the active pane. This is more sensible when doing it with
commands rather than keys.
2016-06-06 07:24:31 +00:00
nicm
3c10df4f87 Allow #[] in window-status-separator. 2016-06-06 07:23:36 +00:00
Nicholas Marriott
89c17e44fb Updated link for bash(1) completions. 2016-06-01 00:06:02 +01:00
Nicholas Marriott
20d2a31b40 Update TODO. 2016-05-31 22:13:44 +01:00
Thomas Adam
c7a0f56c71 Merge branch 'obsd-master' 2016-05-30 12:01:13 +01:00
nicm
1921fac814 Cache the window styles and do not look up the window-style options
unless they have changed.
2016-05-30 09:50:20 +00:00
nicm
36ab4c7c49 Do not draw character to screen if it has not changed, and do not save
last character if it won't be used. This (and last few commits) prompted
by a report from Hubert depesz Lubaczewski.
2016-05-30 09:32:24 +00:00
nicm
7d105738b6 Send two cub1 instead of using cub for moving the cursor two left. This
is normally better because using cub1 will be ^H^H (so two bytes) but
cub would be ^[[2D (four).
2016-05-30 09:26:49 +00:00
Nicholas Marriott
5e9412608e No longer set __progname, we have getprogname(). 2016-05-30 10:02:08 +01:00
Thomas Adam
7a2fed494b Merge branch 'obsd-master' 2016-05-28 02:01:10 +01:00
nicm
344a6a6202 Padding cell is always the same so use a static. 2016-05-27 23:06:12 +00:00
nicm
382222af8e Break the save-last-cell code into a separate function (so it can be
called conditionally later).
2016-05-27 23:02:17 +00:00
nicm
9892d80d6f Most of the utf8_data is fixed so simplify utf8_set to use a memcpy. 2016-05-27 22:57:27 +00:00
Thomas Adam
c10d83b4df __progname -> getprogname()
Fix fallout from recent use of getprogname(), which deprecates __progname.
2016-05-27 20:11:32 +01:00
Thomas Adam
a2e0db67cc Merge branch 'obsd-master' 2016-05-27 20:01:11 +01:00
nicm
fcb00a4161 Use getprogname() instead of __progname to make portability easier. 2016-05-27 17:05:42 +00:00
Nicholas Marriott
762fa58ce8 Merge branch 'master' of github.com:tmux/tmux 2016-05-27 18:04:45 +01:00
Nicholas Marriott
cfef0c6658 getprogname() and setproctitle() on Linux. 2016-05-27 18:04:25 +01:00
Nicholas Marriott
f2ec81cf21 Add flag for -pg. 2016-05-27 10:37:06 +01:00
Thomas Adam
20d97eb849 Merge branch 'obsd-master' 2016-05-26 18:01:09 +01:00
nicm
ec7f5305b1 Extend 0x1234 keys form to more bits so that Unicode keys work. 2016-05-26 14:49:48 +00:00
Thomas Adam
95e304d111 Merge branch 'obsd-master' 2016-05-26 14:01:10 +01:00
nicm
cd14ac0486 Just nuke environ instead of trying to unsetenv everything because that
doesn't necessarily work if there is an entry with an empty name.
2016-05-26 12:15:42 +00:00
Thomas Adam
05ec232f3e Merge branch 'obsd-master' 2016-05-24 00:01:09 +01:00
Thomas Adam
266918a580 Merge branch 'obsd-master' 2016-05-23 22:01:10 +01:00
nicm
95a4cc3bce Use a fixed buffer for strftime() because there is no portable way to
tell if the buffer is too small, and an expanding buffer is overkill
anyway.
2016-05-23 20:39:26 +00:00
nicm
e81a92449e Remove unused variable, from Ben Boeckel. 2016-05-23 20:03:14 +00:00
Nicholas Marriott
7411f21c5f Use osdep_event_init() so that LIBEVENT_NOEPOLL and so on are set to turn off
broken event methods. Reported by Suraj N Kurapati.
2016-05-20 07:54:30 +01:00
Nicholas Marriott
2377092a70 Merge branch 'master' of github.com:tmux/tmux 2016-05-13 08:32:46 +01:00
Nicholas Marriott
af25cab11b Fix a typo, issue 406. 2016-05-13 08:31:45 +01:00
Thomas Adam
6cb74f4b7d Merge branch 'obsd-master' 2016-05-12 18:01:10 +01:00
tim
fdd368a294 - Rework load_cfg() error handling a little.
- Add -q to source-file to suppress errors about nonexistent files.

Input and OK nicm@
2016-05-12 16:05:33 +00:00
Thomas Adam
3ec7e3c006 Merge branch 'obsd-master' 2016-05-12 16:01:10 +01:00
nicm
9715c61de0 set-hook needs CANFAIL like the other set commands. 2016-05-12 13:21:56 +00:00
Thomas Adam
e76d44a640 Merge branch 'obsd-master' 2016-05-12 00:01:10 +01:00
nicm
373b13b240 Add on alerts rather than ignoring them if the event has already been
queued, for example bell and activity together. From Marcel Lippmann via
Romain Francoise.
2016-05-11 20:56:58 +00:00
Nicholas Marriott
fe4e9470bb Add --static to PKG_CONFIG rather than replacing it. 2016-05-05 15:18:58 +01:00
Nicholas Marriott
29763d006a Do not mention OpenBSD FAQ. 2016-05-05 13:09:22 +01:00
Thomas Adam
f4648c1ca1 Merge branch 'obsd-master' 2016-05-05 00:01:11 +01:00
nicm
9f045787a5 Fix up a couple of long lines. 2016-05-04 21:29:47 +00:00
Thomas Adam
ce1ec90fcc Merge branch 'obsd-master' 2016-05-03 16:01:10 +01:00
nicm
28e0658fa9 Some tidying of copy mode search functions, based on a diff from Lukasz
Piatkowski (initial changes to help some more to come).
2016-05-03 13:40:50 +00:00
Thomas Adam
96538b489b Merge branch 'obsd-master' 2016-05-01 16:01:11 +01:00
nicm
4a6eca5bd7 Use the same code for half page scrolling as full, from Michal Mazurek. 2016-05-01 13:39:05 +00:00
Thomas Adam
fe4ef307b7 Merge branch 'obsd-master' 2016-05-01 14:01:12 +01:00
nicm
87be2da4e1 Missing format (window_activity_flag) and a missing Ta. 2016-05-01 11:46:12 +00:00
Nicholas Marriott
2b9f8ae485 Update TODO. 2016-04-30 20:04:41 +01:00
nicm
88bd5b15ff tty_client_ready can not be internal to tty.c again. 2016-04-30 18:59:02 +00:00
Thomas Adam
5849c950d0 Merge branch 'obsd-master' 2016-04-30 00:01:10 +01:00
jmc
0c7895076e tweak previous; 2016-04-29 20:57:10 +00:00
Thomas Adam
bc4f725820 Merge branch 'obsd-master' 2016-04-29 20:01:09 +01:00
nicm
975aa3ccd6 Expand client formats (like run-shell), from Stephen M Coakley. 2016-04-29 17:12:12 +00:00
Thomas Adam
55d472a9fe Merge branch 'obsd-master' 2016-04-29 18:01:09 +01:00
nicm
eb8e76d433 Compact a small table into text. 2016-04-29 15:58:52 +00:00
Thomas Adam
ba9f32b464 Merge branch 'obsd-master' 2016-04-29 16:01:12 +01:00
nicm
0509be0740 Add option to include status text in the pane borders. If
pane-border-status is set to "top" or "bottom" (rather than "off"),
every pane has a permanent top or bottom border containing the text from
pane-border-format.

Based on a diff sent long ago by Jonathan Slenders, mostly rewritten and
simplified by me.
2016-04-29 15:00:48 +00:00
nicm
0d84fdd953 Final parts of command hooks, add before- and after- hooks to each command. 2016-04-29 14:05:24 +00:00
nicm
c5443da2d3 The backoff timer is causing no end of trouble with disconnected clients
stopping data in attached ones. So get rid of it and see how we get on
with just a high watermark on each pane.
2016-04-29 13:36:10 +00:00
nicm
5f2bfd9807 Make the grid_cell passed into screen_write_* const. 2016-04-29 13:21:33 +00:00
Thomas Adam
e7de2fe552 Merge branch 'obsd-master' 2016-04-29 14:01:09 +01:00
Nicholas Marriott
65e4c57d3a Only assume width 1 when wcwidth() returns -1 on non-OpenBSD platforms. 2016-04-29 12:47:15 +01:00
Thomas Adam
a9d501e975 Merge branch 'obsd-master' 2016-04-29 12:01:09 +01:00
nicm
97417a1813 Fix keys parsing again to correctly accept Unicode when not prefixed
with Escape.
2016-04-29 10:42:16 +00:00
nicm
7abdfbe20e OpenBSD wcwidth() is sensible and complete so if it returns -1 it means
that a character is not printable, so return to ignoring such
characters.
2016-04-29 09:11:19 +00:00
Thomas Adam
7a02910feb Merge branch 'obsd-master' 2016-04-28 10:01:10 +01:00
nicm
dd8ba0b5a8 memmove() the right size when expanding tree. 2016-04-28 07:20:26 +00:00
nicm
36976ce5e6 After unlock, Update activity time after recalculate_sizes() so that the
session attached flag is correct.
2016-04-28 06:51:56 +00:00
Thomas Adam
bac7a68023 Merge branch 'obsd-master' 2016-04-27 20:01:10 +01:00
nicm
fc70ac4d59 Apply backspace check after working out the actual key, so that M-BSpace
can work.
2016-04-27 16:46:21 +00:00
Nicholas Marriott
fb4585bbe0 Merge branch 'master' of github.com:tmux/tmux 2016-04-27 13:10:55 +01:00
Nicholas Marriott
61f231a496 Add to TODO. 2016-04-27 13:10:34 +01:00
Thomas Adam
55fdaab365 Merge branch 'obsd-master' 2016-04-27 12:01:10 +01:00
nicm
1cedf78284 Add next/previous paragraph, from J Raynor. 2016-04-27 09:39:09 +00:00
nicm
23fdbc9ea6 Loads of platforms appear to have old or broken Unicode character type
information and are missing widths for relatively common Unicode
characters (so mbtowc() works, but wcwidth() fails). So if wcwidth()
returns -1, assume a width of 1 instead of ignoring the character.
2016-04-27 09:36:25 +00:00
Thomas Adam
394589d493 Merge branch 'obsd-master' 2016-04-27 00:01:09 +01:00
nicm
d3546cc85c Simplify next key matching and fix problems with meta and Unicode keys. 2016-04-26 22:19:22 +00:00
Nicholas Marriott
447ead940e No more array.h. 2016-04-26 12:06:35 +01:00
Thomas Adam
7b9c0ced21 Merge branch 'obsd-master' 2016-04-26 12:01:09 +01:00
nicm
fb1c929dc6 Remove last uses of array.h. 2016-04-26 10:18:57 +00:00
Thomas Adam
819ad1a007 Merge branch 'obsd-master' 2016-04-26 10:01:16 +01:00
nicm
d303e55258 Log wcwidth() and mbtowc() failure to make it easier to debug a Unicode
codepoint not appearing.
2016-04-26 07:33:36 +00:00
Thomas Adam
3b833a0c01 Merge branch 'obsd-master' 2016-04-25 20:01:10 +01:00
nicm
6bf2a43e67 Don't overwrite modifiers in the buffer when making UTF-8 strings,
append instead.
2016-04-25 17:05:53 +00:00
Thomas Adam
5391342b08 Start working on 2.3 2016-04-11 01:07:07 +01:00
Thomas Adam
9a4b45dc0f Add CHANGES notes for 2.2 release 2016-04-11 01:00:35 +01:00
Thomas Adam
ad2532c3f4 Merge branch 'obsd-master' 2016-04-04 18:01:11 +01:00
nicm
075c086d29 fatalx() not fatal(). 2016-04-04 16:19:43 +00:00
Nicholas Marriott
7b8dcbaa86 Merge branch 'master' of github.com:tmux/tmux 2016-04-03 23:55:56 +01:00
Nicholas Marriott
75b2c1693e Add --disable-utempter to build without it. 2016-04-03 23:55:38 +01:00
Thomas Adam
1394420c37 Merge branch 'obsd-master' 2016-03-30 16:01:19 +01:00
nicm
ec82fcdfea Bump the listen() backlog up, some people have scripts that run up a lot
of clients quickly.
2016-03-30 13:20:07 +00:00
Nicholas Marriott
5658b628b9 Look for utempter_add_record to be sure we have the new utempter API, the old
utempter API was also using utempter.h.
2016-03-26 20:17:17 +00:00
Nicholas Marriott
b429a00cce Add to TODO. 2016-03-20 08:14:14 +00:00
Thomas Adam
410ccce4a3 Merge branch 'obsd-master' 2016-03-18 16:01:15 +00:00
nicm
312a7a1e62 Make scrolling behaviour more sensible and maintain cursor position, as
if the same had been done line-by-line. From Michal Mazurek.
2016-03-18 14:27:24 +00:00
Thomas Adam
ed598e9fe1 Merge branch 'obsd-master' 2016-03-18 08:01:18 +00:00
nicm
fa97b0a95b Instead of reusing MouseUp at the finish of a drag, add a new key
MouseDragEnd. It can be useful to bind them separately in copy mode.
2016-03-18 07:28:27 +00:00
Nicholas Marriott
3dfc79fb09 Tweak a comment. 2016-03-17 15:11:40 +00:00
Thomas Adam
5fc5c03dad Merge branch 'obsd-master'
Conflicts:
	tmux.c
2016-03-05 17:58:12 +00:00
nicm
0d6de44a37 If setlocale("en_US.UTF-8") succeeds, then don't do the check for UTF-8
locale since if it isn't UTF-8 the system is broken anyway. If it fails,
try "" and check for UTF-8 with nl_langinfo(CODESET) rather than
wcwidth(). Based on a diff from schwarze@, nl_langinfo also suggested by
stsp@.
2016-03-05 16:08:38 +00:00
Thomas Adam
81f78f0da7 Merge branch 'obsd-master' 2016-03-05 10:01:09 +00:00
nicm
c38e0a4bbc Do not use c->cwd or s->cwd if it is NULL, found by Ben Boeckel. 2016-03-05 07:47:52 +00:00
nicm
1f0b317088 Although we always have en_US.UTF-8 on OpenBSD, some platforms do not,
so fall back to setlocale(LC_CTYPE, ""). tmux requires a UTF-8 locale,
so check with wcwidth() on a UTF-8 character after setlocale().
2016-03-05 07:44:31 +00:00
Thomas Adam
6c35d17800 Merge branch 'obsd-master' 2016-03-03 16:01:11 +00:00
nicm
df0983af39 show-* and set-* need to handle a missing target. 2016-03-03 14:15:22 +00:00
nicm
fa81d838da Accept clients as sessions in cmd_find_get_session. 2016-03-03 14:14:46 +00:00
Thomas Adam
45d62482da Merge branch 'obsd-master' 2016-03-03 14:01:10 +00:00
nicm
bcb41a09b3 RGB colours shouldn't be mixed up with aixterm colours, return before
that happens when working out if they are supported.
2016-03-03 12:58:15 +00:00
Nicholas Marriott
9e2fbb31ec +wchar.h 2016-03-02 18:19:13 +00:00
Nicholas Marriott
985504ff2c Merge branch 'next' 2016-03-02 18:16:51 +00:00
Thomas Adam
e304673c65 Merge branch 'obsd-master'
Conflicts:
	utf8.c
2016-03-02 18:10:51 +00:00
nicm
b8a102d26f Handle wcwidth() and mbtowc() failures in better style and drop
characters where we can't find the width (wcwidth() fails) on input, the
same as we drop invalid UTF-8. Suggested by schwarze@.
2016-03-02 15:36:02 +00:00
nicm
d980d965dd Limit x, y and b to 0x7ff for UTF-8 mouse input, suggested by schwarze@. 2016-03-02 15:33:36 +00:00
nicm
f0239a8fe9 Remove some more unused variables, and use RB_FOREACH_SAFE in
key_bindings_unref_table.
2016-03-01 12:06:07 +00:00
nicm
2e4503ad4e Redraw status on mode entry and exit. 2016-03-01 12:05:15 +00:00
nicm
54ea8f74ae When a mouse drag is finished, fire a MouseUp key press, instead of
doing the drag end in code. From Stephen Coakley.
2016-03-01 12:04:43 +00:00
nicm
e647eeb0c9 Remove unused variables, from Michal Mazurek. 2016-03-01 12:02:54 +00:00
nicm
26945d7956 Use system wcwidth() instead of carrying around UTF-8 width tables. 2016-03-01 12:02:08 +00:00
nicm
c7851e0ee7 Fix break-pane synopsis and some other tmux.1 bits. 2016-03-01 11:58:45 +00:00
Nicholas Marriott
a011b67f56 Remove unused variables. 2016-02-19 16:45:35 +00:00
Nicholas Marriott
c3f93e7178 Add to TODO. 2016-02-19 16:45:15 +00:00
Nicholas Marriott
931b1c6d59 Merge branch 'master' into next 2016-02-19 13:37:18 +00:00
Nicholas Marriott
e9d369a09e Fixed fgetln(3) implementation (from Joerg Jung) which does not depend on *BSD
fgets(3) semantics.
2016-02-19 13:35:46 +00:00
Nicholas Marriott
6adf561507 Redraw status on mode entry and exit. 2016-02-19 13:29:59 +00:00
Nicholas Marriott
95adc0e6ba When a mouse drag is finished, fire a MouseUp key press, instead of doing the
drag end in code. From Stephen Coakley.
2016-02-19 13:28:03 +00:00
Nicholas Marriott
02753ba9ea Remove unused variables, from Michal Mazurek. 2016-02-19 13:15:22 +00:00
Nicholas Marriott
acc1090e77 Use system wcwidth() instead of carrying around UTF-8 width tables. 2016-02-19 13:14:17 +00:00
Nicholas Marriott
fc864529f5 Remove malloc_options debug bit (already gone from OpenBSD). 2016-02-19 13:11:10 +00:00
Nicholas Marriott
782dd941da Fire SIGCHLD after utempter_add_record since it probably eats it. 2016-02-17 23:21:58 +00:00
Thomas Adam
ba8290aeae Merge branch 'obsd-master' 2016-02-12 14:01:14 +00:00
nicm
4f6bc0a0a9 Expand client formats in run-shell. 2016-02-12 12:24:52 +00:00
Thomas Adam
f7c8f1ae29 xmalloc: define __bounded__ where necessary 2016-02-07 00:04:46 +00:00
Thomas Adam
ba97ae1737 EXTRA_DIST: add example_tmux.conf / xmalloc.h 2016-02-06 19:04:21 +00:00
Thomas Adam
7669cfb330 Merge branch 'obsd-master' 2016-02-05 12:01:10 +00:00
nicm
bc0c9c7920 Do not wrap cursor at start or end of history, from Michal Mazurek. 2016-02-05 10:20:06 +00:00
Nicholas Marriott
07c23ccc05 Merge branch 'master' of github.com:tmux/tmux 2016-02-05 10:08:55 +00:00
Nicholas Marriott
2130a07b70 Add to TODO. 2016-02-05 10:08:39 +00:00
Thomas Adam
26f899be10 Merge branch 'obsd-master' 2016-02-04 16:01:13 +00:00
nicm
bdb8bb790e Set up -t flag properly when passing new-session -A off to
attach-session, GitHub issue 295.
2016-02-04 14:11:20 +00:00
Thomas Adam
8760f877e1 Merge branch 'obsd-master' 2016-01-31 16:01:09 +00:00
nicm
97882f9ce2 Clear RGB flags during selection. 2016-01-31 14:11:49 +00:00
Thomas Adam
5fce21728e Merge branch 'obsd-master' 2016-01-31 12:01:09 +00:00
nicm
fa64b89ad7 Whoops, need this for the previous reverse trim commit too. 2016-01-31 09:57:41 +00:00
nicm
49e9f93738 Add RGB escape sequences for capture-pane -e. 2016-01-31 09:57:09 +00:00
nicm
8028560f82 Support negative trim values (#{=-10:pane_title}) to trim from the end,
suggested by Kevin Brubeck Unhammer.
2016-01-31 09:54:46 +00:00
nicm
225a384dbb Fix new-session with -t after command flags changes, reported by Michael Graczyk. 2016-01-31 09:52:01 +00:00
Nicholas Marriott
404379049a examples/ has gone, so delete some text about it. 2016-01-29 15:45:32 +00:00
Nicholas Marriott
2a1bb91bf7 Remove old examples in favour of one example configuration file. 2016-01-29 14:53:28 +00:00
Nicholas Marriott
a33bb3e876 Link to the bash(1) completion file from README rather than including it in
examples.
2016-01-29 14:40:30 +00:00
Thomas Adam
8cf1504ba6 Merge branch 'obsd-master' 2016-01-29 12:01:16 +00:00
nicm
427b820426 Support for RGB colour, using the extended cell mechanism to avoid
wasting unnecessary space. The 'Tc' flag must be set in the external
TERM entry (using terminal-overrides or a custom terminfo entry), if not
tmux will map to the closest of the 256 or 16 colour palettes.

Mostly from Suraj N Kurapati, based on a diff originally by someone else.
2016-01-29 11:13:56 +00:00
Nicholas Marriott
1d6bd50343 libevent.org URL. 2016-01-29 10:58:08 +00:00
Nicholas Marriott
ca29dc9abc Update my email address. 2016-01-19 18:07:25 +00:00
Thomas Adam
dc42c35f1f Merge branch 'obsd-master' 2016-01-19 18:01:15 +00:00
nicm
b5b5221c13 Split out getting the current state from the target search so it can be
replaced if we already know the current.
2016-01-19 16:01:30 +00:00
nicm
995af0e2b7 I no longer use my SourceForge address so replace it. 2016-01-19 15:59:12 +00:00
Thomas Adam
5d21faa99c Merge branch 'obsd-master' 2016-01-16 02:01:10 +00:00
nicm
c9815307eb Add hooks for alerts (bell, silence, activity), from Thomas Adam. 2016-01-16 00:36:53 +00:00
Thomas Adam
506adf3764 Merge branch 'obsd-master' 2016-01-15 12:01:11 +00:00
nicm
d551ab8e5c Clear the environment properly by looping until it is empty rather than
looping over it (which may skip entries), from Brad King.
2016-01-15 11:33:41 +00:00
nicm
68d797587e A couple of missing printflike attributes, from Andrey Starodubtsev. 2016-01-15 11:31:47 +00:00
Thomas Adam
ea9873e60e Merge branch 'obsd-master' 2016-01-02 18:01:12 +00:00
nicm
cfb78654c2 clock-mode needs CMD_PANE. 2016-01-02 17:16:25 +00:00
Thomas Adam
051cf5437a Merge branch 'obsd-master' 2016-01-01 10:01:11 +00:00
nicm
311be04d61 Don't rely on a calculation wrapping when applying message-limit, and
break out of the loop early. From Nicolas Viennot.
2016-01-01 08:04:20 +00:00
Thomas Adam
5e59c301b7 Merge branch 'obsd-master' 2015-12-31 20:01:09 +00:00
nicm
7e67db79dc Remove an extra unzoom call which was probably a merge error. 2015-12-31 18:34:47 +00:00
nicm
f84d32ca5e Use saved pipe buffer offset when writing to pipe, from Nicolas Viennot. 2015-12-31 18:14:13 +00:00
Thomas Adam
5dd0e82809 Merge branch 'obsd-master' 2015-12-28 16:01:09 +00:00
nicm
2a1f27eb1a Couple of trivial style nits. 2015-12-28 14:02:52 +00:00
Nicholas Marriott
e15a8a7c46 Keith Smiley is going to maintain the vim syntax file. 2015-12-24 16:59:12 +00:00
Thomas Adam
ed65535c41 Merge branch 'obsd-master' 2015-12-23 02:01:14 +00:00
nicm
60cbdf9ccd Repair switch-client -l and switch-client with a window target. 2015-12-23 00:12:57 +00:00
Thomas Adam
5083e93957 Merge branch 'obsd-master' 2015-12-21 10:01:08 +00:00
nicm
f2ec911b8a Detach the right session with -d. 2015-12-21 09:20:13 +00:00
Nicholas Marriott
c83d6ee0b1 Merge branch 'master' of github.com:tmux/tmux 2015-12-20 11:26:12 +00:00
Nicholas Marriott
83c96d2685 No need to set cwd on Cygwin now, from Yuya Adachi. 2015-12-20 11:25:13 +00:00
Thomas Adam
58b3d66229 Merge branch 'obsd-master' 2015-12-19 10:01:08 +00:00
nicm
bdbec099cc Make input off flag (selectp -d) apply to synchronize-panes too. 2015-12-19 08:43:04 +00:00
Thomas Adam
2ad9caad3f Merge branch 'obsd-master' 2015-12-18 00:01:08 +00:00
nicm
a337403868 As well as setting up the state, actually use it in cmd_find_target. 2015-12-17 23:08:22 +00:00
Thomas Adam
e0cae08c04 Merge branch 'obsd-master' 2015-12-17 00:01:08 +00:00
nicm
99e9a4c786 send-keys -R should reset the input parser to ground state (so it can be
used to escape from, for example, printf '\033]2;').
2015-12-16 22:05:35 +00:00
Thomas Adam
7c94dae702 Merge branch 'obsd-master' 2015-12-16 22:01:08 +00:00
nicm
021c64310d Add infrastructure to work out the best target given a pane or window
alone and use it to add pane_died and pane_exited hooks.
2015-12-16 21:50:37 +00:00
nicm
8eb1a7d5dc showenv and setenv need to be CANFAIL. 2015-12-16 21:47:00 +00:00
Thomas Adam
f7a6482e6b Merge branch 'obsd-master' 2015-12-15 16:01:12 +00:00
nicm
909b737289 Copy state directly rather than dereferencing wl (which could be NULL). 2015-12-15 14:32:55 +00:00
Thomas Adam
e5caf64815 Merge branch 'obsd-master' 2015-12-15 14:01:12 +00:00
nicm
ac9778395f Some hooks API changes to fire a hook while waiting another cmdq and
infrastructure that will be needed soon.
2015-12-15 13:43:07 +00:00
Thomas Adam
1a33ea9671 Merge branch 'obsd-master' 2015-12-15 02:01:14 +00:00
nicm
9d88d82d5e Allow list-keys and list-commands to be run without a running server. 2015-12-15 00:52:17 +00:00
nicm
6f417ec943 We changed somewhat recently to us the pty when tmux was run inside
itself to work out the current pane. This is confusing in many cases
(particularly notable is that "tmux neww\; splitw" would not split the
new window), and the few advantages do not make up for the confusion.

So drop this behaviour and return to using the current window and pane;
keep the pty check but only use it to limit the list of possible current
sessions.
2015-12-15 00:45:02 +00:00
nicm
56d097cfe0 Don't copy marked pane when can just point to it. 2015-12-15 00:11:24 +00:00
Thomas Adam
6ab17e3e15 Merge branch 'obsd-master' 2015-12-15 00:01:08 +00:00
nicm
12da13c9d1 Make the marked pane a cmd_find_state. 2015-12-15 00:00:01 +00:00
nicm
d5999f8b5c Use cmd_find_clear_state instead of an extra function doing the same. 2015-12-14 23:30:58 +00:00
Thomas Adam
bc6137f9e4 Merge branch 'obsd-master' 2015-12-14 01:30:15 +00:00
nicm
a585a1b81a Remove some stray debug code. 2015-12-14 00:32:19 +00:00
nicm
a3129fd4e8 Instead of combined flags for -c, -s, -t, split into different sets
using an enum and simplify the parsing code.
2015-12-14 00:31:54 +00:00
Thomas Adam
5caec3020d Merge branch 'obsd-master' 2015-12-13 23:46:58 +00:00
Thomas Adam
f4adcfa0e2 Merge branch 'obsd-master' 2015-12-13 22:01:08 +00:00
nicm
ecfeee2e82 Use member names in cmd_entry definitions so I stop getting confused
about the order.
2015-12-13 21:53:57 +00:00
nicm
899bee0056 Actually I thought cmd_get_state_client was unnecessary but it will be
needed.
2015-12-13 21:17:37 +00:00
Thomas Adam
00da99f2c4 Merge branch 'obsd-master' 2015-12-13 20:01:09 +00:00
nicm
72948d9f1d -c needs to be able for fail for display-message. 2015-12-13 18:31:47 +00:00
nicm
66d1193a00 Remove an unnecessary function. 2015-12-13 18:27:47 +00:00
nicm
fd47084224 show-options and environment need CANFAIL flag. 2015-12-13 18:15:13 +00:00
Thomas Adam
d37a580085 Merge branch 'obsd-master' 2015-12-13 18:01:11 +00:00
nicm
50f8ead4e6 Don't log an error when doing the first check for move-window. 2015-12-13 17:58:26 +00:00
nicm
9f5aca62a9 Use struct cmd_find_state directly and remove cmd_state_flag, also
change so that winlink is set even if an index is too.
2015-12-13 17:55:14 +00:00
nicm
9b7697db62 Change cmd_find_target to use a state struct from the caller. 2015-12-13 16:44:35 +00:00
nicm
208e2dad1e If command returns error, report it. 2015-12-13 16:11:42 +00:00
Thomas Adam
ae5ddfdc1a Merge branch 'obsd-master' 2015-12-13 16:01:13 +00:00
nicm
ff599f4004 Remove the cmd_find_{session,window,pane,index} functions (which are
just wrappers around cmd_find_target) and just use cmd_find_target
directly.
2015-12-13 15:32:12 +00:00
nicm
9d191a6093 Move logging into cmd_find_target rather than each function. 2015-12-13 15:00:37 +00:00
nicm
4a4daf1303 Instead of every command resolving the target (-t or -s) itself, prepare
the state (client, session, winlink, pane) for it it before entering the
command. Each command provides some flags that tell the prepare step
what it is expecting.

This is a requirement for having hooks on commands (for example, if you
hook "select-window -t1:2", the hook command should to operate on window
1:2 not whatever it thinks is the current window), and should allow some
other target improvements.

The old cmd_find_* functions remain for the moment but that layer will
be dropped later.

Joint work with Thomas Adam.
2015-12-13 14:32:38 +00:00
Nicholas Marriott
92f187d1c2 Need to use pkg-config --static when doing a static build. 2015-12-12 22:04:25 +00:00
Thomas Adam
845a664bb2 Merge branch 'obsd-master' 2015-12-12 20:01:15 +00:00
nicm
5ed17e84fa Add key-table option to set the default key table for a session, allows
different key bindings for different sessions and a few other things.
2015-12-12 18:32:24 +00:00
nicm
6a50cf89b4 Return after changing key table. 2015-12-12 18:28:47 +00:00
nicm
39cf9c9d31 Allow prefix and prefix2 to be set to None to disable (useful if you
would rather bind the prefix in the root table).
2015-12-12 18:19:00 +00:00
Nicholas Marriott
5a5db02b85 Merge branch 'master' of github.com:tmux/tmux 2015-12-11 19:59:08 +00:00
Nicholas Marriott
38cc1a1843 Look for ncurses with PKG_CONFIG, and remove libtinfo because it just causes
confusion.
2015-12-11 19:58:41 +00:00
Thomas Adam
2a6b215328 Merge branch 'obsd-master' 2015-12-11 18:01:11 +00:00
nicm
88bc8f3528 Style nits and line wrapping of function declarations. 2015-12-11 16:37:21 +00:00
nicm
f2be3ad46f Mention {src,dst}-{window,pane} where we define target-{window,pane}. 2015-12-11 16:27:01 +00:00
Thomas Adam
2a3456cd3b Merge branch 'obsd-master' 2015-12-11 16:01:16 +00:00
nicm
bd5918760e We cannot do hooks_find and then hooks_remove because it might have come
from the parent (global) tree, instead make it remove by name like options.

While here, also tidy up a few bits of options and hooks handling (use
RB_FOREACH_SAFE, and a helper function for the free).
2015-12-11 15:46:57 +00:00
Thomas Adam
4909a70174 Merge branch 'obsd-master' 2015-12-11 13:24:45 +00:00
nicm
d7e11d0af7 Check alerts when session changes, from Patrick Palka. 2015-12-11 12:39:47 +00:00
nicm
01831da5f5 Add cmdq as an argument to format_create and add a format for the
command name (will also be used for more later).
2015-12-11 12:27:36 +00:00
Thomas Adam
af8134a6ff Merge branch 'obsd-master' 2015-12-08 10:01:16 +00:00
Nicholas Marriott
a988c36ccb Add to .mailmap, and sort. 2015-12-08 08:46:06 +00:00
nicm
e0f26dcda3 Remove format_create_flags and just pass flags to format_create. 2015-12-08 08:34:18 +00:00
nicm
8f671d3eef Spacing nits. 2015-12-08 08:14:04 +00:00
Thomas Adam
3182728b70 Merge branch 'obsd-master' 2015-12-08 07:12:13 +00:00
Thomas Adam
5862f59ed7 Conflicts:
Makefile
2015-12-08 07:11:09 +00:00
jmc
1f94274b92 Ed was meant to be El; 2015-12-08 06:42:07 +00:00
nicm
d2fb0efcd1 Add hooks infrastructure, basic commands (set-hook, show-hooks) and a
couple of not very useful client hooks. This will eventually let
commands be run at various points and on notifications. Joint work with
Thomas Adam.
2015-12-08 01:10:31 +00:00
mmcc
dbfce2a4d8 Use ^= instead of a verbose alternative. ok nicm@ 2015-12-08 00:51:17 +00:00
Nicholas Marriott
98994a8bb1 termios(4) 2015-12-08 00:49:10 +00:00
Nicholas Marriott
b580a55191 pty(7) -> pty(4) 2015-12-08 00:48:22 +00:00
Nicholas Marriott
ff16836d1d pty is in section 4 2015-12-08 00:47:27 +00:00
Nicholas Marriott
5411033f66 Update tmux.vim from Teubel Gyorgy. 2015-12-07 12:54:34 +00:00
Nicholas Marriott
8383409e88 Merge branch 'master' of github.com:tmux/tmux 2015-12-07 12:51:20 +00:00
Nicholas Marriott
d20a3ef57c Update .mailmap file. 2015-12-07 12:51:06 +00:00
Thomas Adam
bac8c72381 Merge branch 'obsd-master' 2015-12-07 10:01:09 +00:00
nicm
b9563340b7 Fix bell indicators across detach, reported by Torbjorn Lonnemark, diff
from Thomas Adam.
2015-12-07 09:47:41 +00:00
Thomas Adam
8ae9329aa8 Merge branch 'obsd-master' 2015-12-05 14:01:09 +00:00
claudio
0417f1f2be EAGAIN handling for imsg_read. OK henning@ benno@ 2015-12-05 13:18:24 +00:00
Nicholas Marriott
4d5cab4085 Merge branch 'master' of github.com:tmux/tmux 2015-12-03 14:43:33 +00:00
Nicholas Marriott
3cdb2f0bb7 Add to TODO. 2015-12-03 14:43:24 +00:00
Thomas Adam
66bad2e979 Merge branch 'obsd-master' 2015-12-03 00:01:08 +00:00
nicm
7236838dea Mark new active pane changed after pane lost in window, and after
break-pane. Reported by tim@.
2015-12-02 23:09:22 +00:00
Thomas Adam
eb5ee80c74 Merge branch 'obsd-master' 2015-12-01 10:01:13 +00:00
nicm
a785a7f700 Do not deref wp if window_get_active_at returns NULL which can happen on
very large terminals, from Michael Graczyk.
2015-12-01 09:41:03 +00:00
Thomas Adam
742976893e Merge branch 'obsd-master' 2015-11-29 18:01:08 +00:00
guenther
1d331c7e62 Delete a duplicated line
ok jmc@
2015-11-29 17:06:59 +00:00
Thomas Adam
9fe8b28746 Merge branch 'obsd-master' 2015-11-27 15:41:28 +00:00
nicm
6a2ca34216 Do not set a limit on the length of commands when printing them. 2015-11-27 15:06:43 +00:00
Nicholas Marriott
3b83bda29c Add to TODO. 2015-11-25 23:35:24 +00:00
Thomas Adam
a1bc339340 log_open() isn't conditional on proctitle 2015-11-25 16:51:17 +00:00
Thomas Adam
260de2cb5e Remove logfile() 2015-11-25 16:48:47 +00:00
Thomas Adam
890d8da2e3 Merge branch 'obsd-master'
Conflicts:
	log.c
	proc.c
	tmux.c
2015-11-25 16:37:30 +00:00
nicm
ac8678aefe Don't print error if none to print. 2015-11-25 07:58:55 +00:00
nicm
62d3af17f9 Make environ_set va_args and use it to tidy up some calls. Also add a
missing word in manpage (from jmc).
2015-11-24 23:46:15 +00:00
nicm
3ff46b2e43 Shell command from -c doesn't have to be global, pass it as an argument. 2015-11-24 23:22:51 +00:00
nicm
dca93c56e0 Do lock failures slightly better, return a special value so we don't
unlink the wrong thing.
2015-11-24 23:01:51 +00:00
nicm
73e30cbda8 Actually show something (even if it not that helpful) if the server
fails to start (for example if it can't create the socket), rather than
hanging or showing nothing.
2015-11-24 22:45:44 +00:00
nicm
c18fbefe93 Document socket_path format. 2015-11-24 22:27:59 +00:00
nicm
c913fb99b6 Tidy the code that works out the socket path, and just use the full path
in the global socket_path rather than copying it.
2015-11-24 22:27:22 +00:00
nicm
8976dac9e0 Remove malloc_options DEBUG bit. 2015-11-24 22:09:53 +00:00
nicm
bef217b241 Switch a fprintf to a fatal, and wrap some long lines. 2015-11-24 22:04:36 +00:00
nicm
1e2df2d464 Remove the -I part of show-messages which isn't really that useful; the
server start time can now be accessed with a new start_time format (use:
tmux display -p '#{t:start_time}')
2015-11-24 21:52:06 +00:00
nicm
9fd3318dd8 All kill-session -C to clear alerts in all windows, suggested by Aaron
U'Ren.
2015-11-24 21:50:06 +00:00
nicm
4e3015a892 Log some system and libevent information at startup. 2015-11-24 21:32:36 +00:00
nicm
bdbbd9711c Show libevent version in showmsgs -I. 2015-11-24 21:23:44 +00:00
nicm
9cccb8c115 Make the log stuff a bit tidier with some helper functions. 2015-11-24 21:19:46 +00:00
nicm
4ec61bef46 Fix usage of detach-client. 2015-11-24 20:40:51 +00:00
Nicholas Marriott
0a2ef2b932 Merge branch 'master' of github.com:tmux/tmux 2015-11-24 18:50:24 +00:00
Nicholas Marriott
7b085136a7 -sys/queue.h in proc.c, and nuke the unnecessary C++ header guards stuff and
sys/cdefs.h in vis.h (it causes problems on some platforms). Reported by
someone on GitHub, issue 212.
2015-11-24 18:48:07 +00:00
Thomas Adam
534f9e3ab1 Merge branch 'obsd-master' 2015-11-24 10:01:13 +00:00
nicm
b32ce34cf2 Don't allow options in table without scope set. 2015-11-24 09:34:55 +00:00
Thomas Adam
3f47ff6ecd Merge branch 'obsd-master' 2015-11-24 00:01:16 +00:00
nicm
2adf3f42ee Partly revert previous, it is harmless to keep support for UTF-8 mouse
mode inside tmux, just no longer support it for tmux itself.
2015-11-23 23:47:57 +00:00
Thomas Adam
b642b3c8e3 Merge branch 'obsd-master' 2015-11-23 21:21:12 +00:00
Thomas Adam
d63de1e407 Merge branch 'obsd-master'
Conflicts:
	server.c
	tmux.c
2015-11-23 21:20:54 +00:00
nicm
32e510bd70 Remove support for the UTF-8 mouse extension. This was a briefly used,
poor idea that was fairly quickly replaced by SGR mouse input (which is
now widespread). It is impossible to tell the difference between UTF-8
and non-UTF-8 mouse input; since the mouse-utf8 option was removed tmux
has not handled it correctly in any case; and it is ridiculous to have
three different forms of mouse input.
2015-11-23 20:53:09 +00:00
nicm
28e72ae34d Don't leak extddata, memset after freeing it, not before. From Patrick
Palka.
2015-11-22 19:42:57 +00:00
nicm
01a2ddf3f8 Add getpw to pledge, makes tmux work in YP environments, discovered by
matthieu, ok deraadt
2015-11-22 19:41:19 +00:00
tim
4fcc02ee9d If display-time is set to 0, show status messages until a key is pressed;
OK nicm@
2015-11-22 18:28:01 +00:00
Thomas Adam
78a00c845c Merge branch 'obsd-master'
Conflicts:
	tmux.h
2015-11-21 14:24:33 +00:00
Nicholas Marriott
2c482939fd Move tmux.h below system includes. 2015-11-21 08:03:18 +00:00
nicm
933929cd62 Memory leaks and an uninitialized part of utf8_data, from Patrick Palka. 2015-11-20 22:02:54 +00:00
nicm
40fefe2cbc The alerts callback should be fired for bells even if bell-action is
none because it also affects the status line bell indicator (and
bell-action does not). Fixes a problem reported by tim@.
2015-11-20 16:33:46 +00:00
nicm
fce56c56ef Instead of separate tables for different types of options, give each
option a scope type (server, session, window) in one table.
2015-11-20 12:01:19 +00:00
nicm
374e273df5 Only assume pasting with at least two characters, reduces problems for
people who can type ^B c very fast, or who are using tmux inside
something else that buffers.
2015-11-19 22:46:46 +00:00
Thomas Adam
cf688db4b5 Merge branch 'obsd-master' 2015-11-19 16:01:12 +00:00
nicm
98967c5ec9 The activity flag could already be set, so queue the callback always (if
not already queued) rather than only if the flag is being added. Fixes a
problem reported by tim@
2015-11-19 14:55:25 +00:00
Thomas Adam
45b4e337cb Merge branch 'obsd-master' 2015-11-18 18:01:13 +00:00
nicm
82760a9960 Use format_expand_time for display-message. 2015-11-18 16:49:13 +00:00
Nicholas Marriott
c15487318b unused -> __unused. 2015-11-18 16:45:44 +00:00
Nicholas Marriott
a58eaec540 Merge branch 'master' of github.com:tmux/tmux 2015-11-18 16:42:25 +00:00
Thomas Adam
7fe8edc396 Merge branch 'obsd-master' 2015-11-18 16:01:23 +00:00
Nicholas Marriott
8b4b3ff4fc Add __unused, will be needed shortly. 2015-11-18 14:37:08 +00:00
nicm
577c0e3e5a Use __unused rather than rolling our own. 2015-11-18 14:27:44 +00:00
nicm
5a5b950e8b Add s/foo/bar/: prefix for formats to substitute bar for foo. 2015-11-18 14:13:55 +00:00
Nicholas Marriott
f8a1f8843c Add -Wno-attributes. 2015-11-18 14:10:48 +00:00
Nicholas Marriott
9bba26f8c5 Add reallocarray prototype. 2015-11-18 14:09:17 +00:00
Thomas Adam
8fa822b521 Merge branch 'obsd-master' 2015-11-18 14:01:12 +00:00
nicm
64571368dc Sync the entire xmalloc.[ch] with the other users, but with the addition
of xrealloc, xvasprintf, xvsnprintf.
2015-11-18 13:06:54 +00:00
Nicholas Marriott
93742ed5df Merge branch 'master' of github.com:tmux/tmux 2015-11-18 12:55:22 +00:00
Nicholas Marriott
a77960c540 Add reallocarray to compat. 2015-11-18 12:54:29 +00:00
Thomas Adam
4b703d3049 Merge branch 'obsd-master' 2015-11-18 10:01:11 +00:00
nicm
ca5e6bf5f2 Don't update activity time twice for new sessions, and add some logging. 2015-11-18 09:22:29 +00:00
Thomas Adam
44cad8f4ed Merge branch 'obsd-master' 2015-11-17 20:01:12 +00:00
tobias
d0505fd042 Merge xmalloc.[ch] files across base, skipping OpenSSH for now.
ok nicm
2015-11-17 18:25:03 +00:00
Thomas Adam
349a62ed4f Merge branch 'obsd-master' 2015-11-17 00:01:09 +00:00
nicm
775fb562bd 0x7f is a valid key. 2015-11-16 22:57:51 +00:00
Thomas Adam
1686a15fb6 Merge branch 'obsd-master' 2015-11-16 00:01:10 +00:00
nicm
661d0dfac9 Make key_code unsigned long long not uint64_t which is more portable for
printf formats, and move UTF8_SIZE define down to near the rest of the
UTF-8 bits.
2015-11-15 22:50:38 +00:00
Thomas Adam
8213558cc7 Merge branch 'obsd-master'
Conflicts:
	server.c
	tmux.c
2015-11-15 22:49:25 +00:00
nicm
a582b62287 Accidentally turned off pledge, turn it back on. 2015-11-15 14:32:48 +00:00
Thomas Adam
bb820fa761 Merge branch 'obsd-master' 2015-11-14 14:01:08 +00:00
nicm
14d90e4901 The character is an int so use %x not %hhx. 2015-11-14 12:20:19 +00:00
nicm
3db0d50df4 The private use area at U+E000 to U+F8FF is not very useful if it is
width 0, make it width 1 instead.
2015-11-14 12:03:23 +00:00
Thomas Adam
f12d7f0d4b Merge branch 'obsd-master' 2015-11-14 12:01:09 +00:00
nicm
205d15e82d All these return values from utf8_* are confusing, use an enum. 2015-11-14 11:45:43 +00:00
Thomas Adam
7b4b78b419 Merge branch 'obsd-master' 2015-11-14 11:38:52 +00:00
Thomas Adam
7b749eff35 Merge branch 'obsd-master'
Conflicts:
	server.c
	tmux.c
2015-11-14 11:38:30 +00:00
nicm
f401791a56 Rename a variable in utf8_combine for consistency and use 0xfffd for
unknown Unicode.
2015-11-14 11:13:44 +00:00
nicm
dab63b029e Couple of assignments to remove compiler warnings. 2015-11-14 10:57:59 +00:00
nicm
64333e3ef8 Be more strict about invalid UTF-8. 2015-11-14 10:56:31 +00:00
nicm
c56b81a2ce Push stdout and stderr to clients more aggressively, and add an event to
continue if the send fails.
2015-11-14 09:41:06 +00:00
Nicholas Marriott
23266e8e09 Merge branch 'master' of github.com:tmux/tmux 2015-11-14 09:04:41 +00:00
Nicholas Marriott
31d880f751 Update the TODO file. 2015-11-14 09:04:13 +00:00
nicm
908e6bb68f Log more of UTF-8 input. 2015-11-14 08:25:12 +00:00
Thomas Adam
276ca5f04c Merge branch 'obsd-master' 2015-11-13 18:01:13 +00:00
nicm
c4893d8efd Log option names in fatal() for missing option. 2015-11-13 16:06:43 +00:00
Nicholas Marriott
1016f112bf Merge branch 'master' of github.com:tmux/tmux 2015-11-13 16:06:11 +00:00
Nicholas Marriott
b7397bf413 utf8 option is gone. 2015-11-13 16:05:58 +00:00
Thomas Adam
45a10dde95 Merge branch 'obsd-master' 2015-11-13 14:01:10 +00:00
nicm
88aa1c8dc3 Two spacing and spelling nits. 2015-11-13 12:18:52 +00:00
Thomas Adam
e2917b2627 Merge branch 'obsd-master' 2015-11-13 10:43:07 +00:00
Thomas Adam
3df4959f51 Merge branch 'obsd-master'
Conflicts:
	Makefile
2015-11-13 10:42:45 +00:00
nicm
531869bd92 Add window_visible_layout which ignores zoomed panes and use it for
control mode (which needs to know all panes), from George Nachman.
2015-11-13 10:00:26 +00:00
nicm
c5689a5a40 Long overdue change to the way we store cells in the grid: now, instead
of storing a full grid_cell with UTF-8 data and everything, store a new
type grid_cell_entry. This can either be the cell itself (for ASCII
cells), or an offset into an extended array (per line) for UTF-8
data.

This avoid a large (8 byte) overhead on non-UTF-8 cells (by far the
majority for most users) without the complexity of the shadow array we
had before. Grid memory without any UTF-8 is about half.

The disadvantage that cells can no longer be modified in place and need
to be copied out of the grid and back but it turned out to be lot less
complicated than I expected.
2015-11-13 08:09:28 +00:00
Thomas Adam
a7027ed8e5 Merge branch 'obsd-master' 2015-11-13 00:01:15 +00:00
nicm
e71a915412 Rename overly-long utf8data to ud throughout. 2015-11-12 22:04:37 +00:00
Thomas Adam
b2f19c9d06 Merge branch 'obsd-master' 2015-11-12 16:01:09 +00:00
nicm
f2d03f4fdd grid_put_utf8 is unused, remove it. 2015-11-12 14:50:57 +00:00
Thomas Adam
4f88344df3 Merge branch 'obsd-master' 2015-11-12 14:01:14 +00:00
nicm
a209ea3953 Add utf8_padcstr and use it to align columns in list-keys. 2015-11-12 12:43:36 +00:00
jmc
1da7475d0e tweak previous; ok nicm 2015-11-12 12:36:34 +00:00
nicm
d6daf37df4 Tidy utf8.c a little: build table on first use, and make utf8_width take
a u_int rather than splitting and then combining again in utf8_split.
2015-11-12 12:19:57 +00:00
Thomas Adam
5f483499f3 Merge branch 'obsd-master' 2015-11-12 12:01:17 +00:00
nicm
0cc812ae34 tmux is UTF-8, so if $TMUX is set (tmux running in tmux), the client is
UTF-8. Also try to make the existing checks more readable.
2015-11-12 11:24:08 +00:00
nicm
c41673f3fa If we know the terminal outside tmux is not UTF-8, replace UTF-8 in
error messages and whatnot with underscores the same as we do when we
draw UTF-8 characters as part of the screen.
2015-11-12 11:10:50 +00:00
nicm
1b86f520ea Nuke the utf8 and status-utf8 options and make tmux only a UTF-8
terminal. We still support non-UTF-8 terminals outside tmux, but inside
it is always UTF-8 (as when the utf8 and status-utf8 options were on).
2015-11-12 11:09:11 +00:00
nicm
a0f3999ce7 Remove the mouse_utf8_flag format as well. 2015-11-12 11:07:10 +00:00
nicm
69e0b8326a Support UTF-8 key bindings by expanding the key type from int to
uint64_t and converting UTF-8 to Unicode on input and the reverse on
output. (This allows key bindings, there are still omissions - the
largest being that the various prompts do not accept UTF-8.)
2015-11-12 11:05:34 +00:00
Thomas Adam
333da3b64b Merge branch 'obsd-master' 2015-11-12 10:01:09 +00:00
nicm
7062b0e65d Default history-file should be "" not NULL, from Greg Onufe. 2015-11-12 08:19:18 +00:00
Thomas Adam
f2e4aa8d1c Merge branch 'obsd-master' 2015-11-12 00:01:10 +00:00
nicm
00c34df186 Drop mouse-utf8 option and always turn on UTF-8 mouse if the client says
it supports UTF-8.
2015-11-11 23:23:33 +00:00
Thomas Adam
35fd6d134a Merge branch 'obsd-master'
Conflicts:
	utf8.c
2015-11-11 08:14:36 +00:00
nicm
6f3475c6c7 If realpath() fails just try the original path. 2015-11-10 22:33:47 +00:00
nicm
005e462e01 Handle absolute paths properly, and don't use resolved path in
realpath() fails.
2015-11-10 22:29:33 +00:00
nicm
dcdccf8333 Same bug as last commit, but in the other copy of the loop in this file... 2015-11-05 23:32:21 +00:00
schwarze
e9b58d9de4 Update the internal wcwidth(3) table of tmux(1) to match the data
in /usr/src/share/locale/ctype/en_US.UTF-8.src, with one single
exception:  Keep U+00AD SOFT HYPHEN at width 1 rather than moving
it to width 0, a tradition already observed in the old
https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c .
While here, manually rebalance the btree for optimal lookup speed.
OK nicm@
2015-11-05 16:44:25 +00:00
Thomas Adam
896581628d Merge branch 'obsd-master' 2015-11-05 12:01:08 +00:00
nicm
5577535891 Pass through right click if mouse is on, from Patrick Palka. 2015-11-05 11:05:30 +00:00
Thomas Adam
696826913c Merge branch 'obsd-master' 2015-11-03 16:01:11 +00:00
nicm
455284f1c0 Detach the client we are looping over, from Thomas Adam. 2015-11-03 15:07:36 +00:00
Thomas Adam
c975de2e07 Merge branch 'obsd-master'
Conflicts:
	server.c
2015-10-31 23:56:35 +00:00
nicm
ba7fb49fb9 Fall back silently to ~ or / rather than checking -c with access(), this
was the old behaviour.
2015-10-31 14:51:15 +00:00
nicm
b0a99e85b6 Don't shift version out of peerid, it is needed later. 2015-10-31 13:43:38 +00:00
nicm
abb4e9e2fa The output log is only useful once and it means creating a file, so open
it once at startup instead of in every call to tty_open.
2015-10-31 13:12:03 +00:00
Thomas Adam
17f6c3be8e Merge branch 'obsd-master' 2015-10-31 10:01:12 +00:00
nicm
01defc9f49 Because pledge(2) does not allow us to pass directory file descriptors
around, we can't use file descriptors for the working directory because
we will be unable to pass it to a privileged process to tell it where to
read or write files or spawn children. So move tmux back to using
strings for the current working directory. We try to check it exists
with access() when it is set but ultimately fall back to ~ if it fails
at time of use (or / if that fails too).
2015-10-31 08:13:58 +00:00
Thomas Adam
e8bb385d6d Merge branch 'obsd-master' 2015-10-29 10:01:09 +00:00
nicm
45f3cea263 Break version check into a separate function, and limit version to 8 bits. 2015-10-29 09:35:31 +00:00
Thomas Adam
a5e4d3a2d8 Merge branch 'obsd-master' 2015-10-28 12:01:11 +00:00
nicm
bf9c933cae Like options, move the environ struct into environ.c. 2015-10-28 09:51:55 +00:00
Thomas Adam
da1f6fc2c8 Merge branch 'obsd-master'
Conflicts:
	Makefile
	client.c
	server-client.c
	server.c
	tmux.c
	tmux.h
2015-10-27 23:27:26 +00:00
nicm
44657bf932 Move struct options into options.c. 2015-10-27 15:58:42 +00:00
nicm
67c3a014b9 No more TMPDIR. 2015-10-27 14:51:35 +00:00
nicm
07b0ea03c3 Break the common process set up, event loop and imsg dispatch code
between server and client out into a separate internal API. This will
make it easier to add another process.
2015-10-27 13:23:24 +00:00
Thomas Adam
147b5ae514 Merge branch 'obsd-master' 2015-10-27 10:01:13 +00:00
nicm
9952201ca7 Count brackets in #{?...} so that nested conditional formats work, from
Daniel De Graaf.
2015-10-27 09:28:31 +00:00
nicm
17c2c4219d The format callback may not always succeed, so we need to check for
NULL. From Patrick Palka.
2015-10-27 09:18:06 +00:00
nicm
3fc001d0a2 Use copy-mode -et= in WheelUpPane binding, from Patrick Palka. 2015-10-27 09:15:21 +00:00
Thomas Adam
9c69a79f9a Merge branch 'obsd-master' 2015-10-27 00:01:09 +00:00
nicm
640c6fdd5f If a mouse event has no key binding, pass it through to the pane it
happened in, not the active pane like normal key presses. Fixes problems
seen by Enrico Ghirardi.
2015-10-26 23:16:18 +00:00
nicm
380a1ea8ef Default bindings for mouse wheel on status line to change window (like
we had before), from Patrick Palka.
2015-10-26 23:06:18 +00:00
nicm
b85be36d1c Handle unknown keys more gracefully, return a string instead of NULL. 2015-10-26 22:03:04 +00:00
Thomas Adam
54a3ed751e Merge branch 'obsd-master' 2015-10-26 18:01:12 +00:00
nicm
a22fe33aa0 Some extra logging of where keys are actually going. 2015-10-26 17:17:06 +00:00
Thomas Adam
e95df0bc39 Merge branch 'obsd-master' 2015-10-26 02:01:09 +00:00
jmc
c582f7d177 space before punctuation; 2015-10-26 00:15:37 +00:00
Thomas Adam
ca29903c82 Merge branch 'obsd-master' 2015-10-26 00:01:10 +00:00
nicm
e65306d8e7 Extend the modifiers allowed before formats: as well as the existing
#{=10:...}  length limit, add #{t:...} to convert a time_t format to a
string, #{b:...} for basename and #{d:...} for dirname. Remove all the
foo_string time formats as they can now be replaced by "t:", for example
#{window_activity_string} becomes #{t:window_activity}.
2015-10-25 22:29:17 +00:00
Nicholas Marriott
c14fb5b633 -sys/types.h 2015-10-25 09:38:08 +00:00
Thomas Adam
ad437f13d5 Add missing headers for getpid() 2015-10-25 09:34:56 +00:00
Thomas Adam
4681415a15 Merge branch 'master' of github.com:tmux/tmux 2015-10-25 09:33:11 +00:00
Nicholas Marriott
7930cb54c0 ifdef __OpenBSD__ around pledge(). 2015-10-25 09:31:46 +00:00
Thomas Adam
91f53d590b __OpenBSD__ around pledge() 2015-10-25 09:31:07 +00:00
Thomas Adam
3e0d31c4e9 Merge branch 'obsd-master' 2015-10-25 09:22:20 +00:00
Thomas Adam
4acc8d0ff5 Merge branch 'obsd-master'
Conflicts:
	cmd-find.c
2015-10-25 09:21:37 +00:00
nicm
3faa51a0ca Pass output from jobs through format_expand() so they are expanded again
(this was the previous behaviour).
2015-10-25 08:59:26 +00:00
deraadt
3034a71488 Let's see if anyone screams about not being able to specify $TMPDIR
for their tmux sockets.

(Over the years, I have seen $TMPDIR set up worse than /tmp many times,
and don't know how this practice infected other parts of the system.
Nothing uses tmpdir(3), nor a huge-temporary-file program like sort.)
ok nicm
2015-10-25 07:48:16 +00:00
nicm
2e2b8a95bd Pasting mouse escape sequences is unlikely, so skip them when working
out whether the user is pasting.
2015-10-23 23:46:36 +00:00
nicm
26a55ddcf9 Remove some unnecessary checks before free(). 2015-10-23 16:30:15 +00:00
nicm
1a4ddfa8a7 If $TMUX is set, and we are unsure about the session, use it. 2015-10-23 16:29:07 +00:00
nicm
5383b047d1 tmux can call pledge() in main with large set and then reduce it
slightly in the server to "stdio rpath wpath cpath fattr unix recvfd
proc exec tty ps".
2015-10-23 16:07:29 +00:00
nicm
14da999408 Format for scroll position, from Jorge Morante. 2015-10-23 16:02:21 +00:00
nicm
63a3fd3c0f Use tty_term_flag not _has for XT, and make -2 force direct use of
256-colour escape sequences (so setaf/setab can be bypassed if needed).
2015-10-23 15:52:54 +00:00
Thomas Adam
8c39813665 Merge branch 'obsd-master' 2015-10-22 14:01:12 +01:00
nicm
3ebcf25149 If the pane is still on all_window_panes but not actually connected to
window or session (which can happen if it is killed during a command
sequence and something else has a reference), fall back to the best
effort. Fixes "tmux killw\; detach" for Rudis Muiznieks.
2015-10-22 11:23:00 +00:00
nicm
a05c27a7e1 Unzoom before -LRUD, reported by Andy Weidenbaum. 2015-10-22 11:19:31 +00:00
Thomas Adam
6bc3902f5d Merge branch 'obsd-master' 2015-10-22 12:01:09 +01:00
nicm
c2c2d44c72 Log identify messages. 2015-10-22 11:00:51 +00:00
nicm
515dfea4b7 This should not be changed. 2015-10-22 10:48:30 +00:00
nicm
31fd071faa Rename shutdown to exit. 2015-10-22 10:46:24 +00:00
Thomas Adam
0bfa615997 Merge branch 'obsd-master' 2015-10-21 16:01:08 +01:00
nicm
60ca29df64 client_key_table was missing. 2015-10-21 13:14:36 +00:00
Thomas Adam
35f582583a Merge branch 'obsd-master' 2015-10-21 14:01:09 +01:00
nicm
ddbc4a0f6c By popular demand add a default binding for mouse wheel up to scroll
into history (if the mouse is, on of course).
2015-10-21 11:13:47 +00:00
Thomas Adam
1f4a5b5dfe Merge branch 'obsd-master' 2015-10-21 00:01:19 +01:00
nicm
076034345a Use client pointer not file descriptor in logging. 2015-10-20 21:12:08 +00:00
Thomas Adam
af2d48f4d2 Merge branch 'obsd-master' 2015-10-20 16:01:11 +01:00
nicm
8c8cddbe02 The table could change when retrying so don't save it at start of
server_client_handle_key.
2015-10-20 14:19:27 +00:00
Thomas Adam
bbdc08780c Merge branch 'obsd-master' 2015-10-18 22:01:08 +01:00
nicm
174a2ad731 Pass current directory as a string rather than a file descriptor because
pledge doesn't let us pass directory file descriptors.
2015-10-18 20:42:42 +00:00
Thomas Adam
7c78b2b756 Start working on tmux 2.2 2015-10-18 18:19:08 +01:00
Thomas Adam
310f0a960c Update for 2.1 release. 2015-10-18 18:10:43 +01:00
Nicholas Marriott
6c3ade76df __OpenBSD__ around pledge(). 2015-10-17 20:16:12 +01:00
Thomas Adam
487285b325 Merge branch 'obsd-master' 2015-10-17 20:01:08 +01:00
nicm
9c601ebde8 Add pledge "stdio unix sendfd proc exec tty" to tmux client process,
"sendfd" is dropped after first message from the server.
2015-10-17 18:30:43 +00:00
Nicholas Marriott
0273d809d0 Merge branch 'master' of github.com:tmux/tmux 2015-10-17 18:48:45 +01:00
Nicholas Marriott
e0527d7731 time.h is not needed now tzset() is not in log.c. 2015-10-17 18:48:22 +01:00
Thomas Adam
a204595e4c Merge branch 'obsd-master' 2015-10-16 10:01:09 +01:00
nicm
cf89abb013 Don't free after calling paste_set but do after evbuffer_add, from Theo
Buehler.
2015-10-16 07:43:29 +00:00
Nicholas Marriott
c06c14fb29 Some header fixes. 2015-10-15 21:42:17 +01:00
Nicholas Marriott
716550021e Merge branch 'master' of github.com:tmux/tmux 2015-10-15 09:25:21 +01:00
Nicholas Marriott
f199fb6a2b Fix available_fds when there is no AF_INET, reported by Mathieu Arnold. 2015-10-15 09:24:25 +01:00
Thomas Adam
f69e09a67e Merge branch 'obsd-master' 2015-10-11 02:01:14 +01:00
guenther
241fd72f75 Userspace doesn't need to use SUN_LEN(): connect() and bind() must accept
sizeof(struct sockaddr_un), so do the simple, portable thing

ok beck@ deraadt@
2015-10-11 00:26:23 +00:00
Thomas Adam
5b13dafbab Merge branch 'obsd-master' 2015-10-07 12:01:21 +01:00
nicm
7340d5adfd Couple of memory leaks in error paths, from Frederik Vanderstraeten. 2015-10-07 09:52:58 +00:00
Thomas Adam
7120ab2f16 Merge branch 'obsd-master' 2015-09-26 02:01:16 +01:00
nicm
695a591f8e Adding colors=256 to *256color* was always pretty stupid and now it
won't work (without adding setaf@:setab@ too).
2015-09-25 23:30:24 +00:00
nicm
03d7dba5d8 If the terminal has colors=256, only try to use setaf/setab if they
exist, reported by Filipe Brandenburger.
2015-09-25 23:30:12 +00:00
Thomas Adam
20c3adca41 Merge branch 'obsd-master' 2015-09-25 18:01:09 +01:00
nicm
28f23f18e9 Free the history when it is cleared, based on a diff from Carlo Cannas. 2015-09-25 15:53:07 +00:00
Thomas Adam
b0372840e7 Merge branch 'obsd-master' 2015-09-24 14:01:10 +01:00
nicm
2a62917444 Don't leak fd and path on failure. 2015-09-24 12:06:20 +00:00
nicm
69ea6b9373 Do not leak log file descriptor. 2015-09-24 12:03:58 +00:00
Thomas Adam
ed17760a52 Merge branch 'obsd-master' 2015-09-24 10:01:09 +01:00
nicm
ddb2d1221b Assign flag not number for flag types (we got away with it so far
because that are a union). From Filipe Brandenburger.
2015-09-24 07:02:18 +00:00
Nicholas Marriott
06d4553a15 Merge branch 'master' of github.com:tmux/tmux 2015-09-23 14:27:11 +01:00
Nicholas Marriott
1caebaa49a Add to TODO. 2015-09-23 14:26:53 +01:00
Thomas Adam
7e9b87f396 Merge branch 'obsd-master' 2015-09-23 00:01:09 +01:00
nicm
dc66795e35 Don't update last session when the session is unchanged, from Sina Siadat. 2015-09-22 21:56:16 +00:00
Thomas Adam
d6d05883ad Merge branch 'obsd-master' 2015-09-21 12:01:11 +01:00
nicm
d5f223a3fe Reset the alerts timer always on activity, from Thomas Adam. 2015-09-21 09:34:52 +00:00
Thomas Adam
983357603a Merge branch 'obsd-master' 2015-09-18 12:01:07 +01:00
nicm
6b709e655e -l should apply to the new not the old pane with -b, from "MadMaverick9"
on GitHub.
2015-09-18 09:55:22 +00:00
Thomas Adam
c624382929 Merge branch 'obsd-master' 2015-09-17 16:01:08 +01:00
nicm
8b5d5dca9f Redraw both src and dst sessions in break-pane. 2015-09-17 14:11:55 +00:00
Thomas Adam
a3bce7a322 Merge branch 'obsd-master' 2015-09-17 00:01:08 +01:00
nicm
c1d0b6a6ee Log when cmdq_continue is called. 2015-09-16 22:41:00 +00:00
nicm
232a0ffc34 Give some variables less silly names. 2015-09-16 22:40:27 +00:00
nicm
ecb257f0ef A few minor style nits. 2015-09-16 22:40:05 +00:00
nicm
d1b73be6e1 Hoist some common code out of both branches of an if/else. 2015-09-16 22:29:30 +00:00
nicm
a4b4b29987 Rename cmd_q dead flag to a general flags bitmask (will be more flags later). 2015-09-16 22:24:54 +00:00
Nicholas Marriott
57ad1f6ddf Merge branch 'master' of github.com:tmux/tmux 2015-09-15 13:57:57 +01:00
Nicholas Marriott
54bd761286 Add BCE to TODO. 2015-09-15 13:57:46 +01:00
Thomas Adam
b5d789a531 Merge branch 'obsd-master' 2015-09-14 16:01:08 +01:00
Nicholas Marriott
166aa97f75 No more $Id$. 2015-09-14 15:59:21 +01:00
Thomas Adam
d47789620b Add missing <time.h> 2015-09-14 14:39:51 +01:00
nicm
16ee4de5df Remove some extra blank lines. 2015-09-14 13:22:02 +00:00
Thomas Adam
4afe26fa82 Merge branch 'obsd-master' 2015-09-14 14:01:09 +01:00
nicm
62bb6e37e0 Should add buffer if no -b. 2015-09-14 12:52:22 +00:00
nicm
216ddf3da5 Move tzset() from log_open to main. 2015-09-14 12:12:24 +00:00
nicm
8da6de3e66 Style nit, int for flags not u_int. 2015-09-14 11:57:22 +00:00
Thomas Adam
74b958ecbe Merge branch 'obsd-master'
Conflicts:
	Makefile
2015-09-14 12:42:19 +01:00
nicm
af16ce6ad9 When the active pane changes, redraw panes if the style has
changed. From Cam Hutchison.
2015-09-14 11:34:50 +00:00
nicm
16efa84838 Make refresh-client force update of jobs, from Sina Siadat. 2015-09-14 10:25:52 +00:00
nicm
901c2eb20a Add copy-mode -e to exit copy mode when scrolling off the bottom, useful
for quick view of history, from Cam Hutchison.
2015-09-13 13:31:40 +00:00
nicm
ede0f2f633 Set woken flag when flushing so that the channel is freed, while here
use the same loop construct for both loops.
2015-09-13 10:45:55 +00:00
nicm
a3de5dbab1 Merge delete-buffer into cmd-set-buffer.c and change the paste buffer
API so it has one paste_free() rather than free_top and free_name
(everywhere that uses it already has the right pointer).
2015-09-11 14:41:50 +00:00
Nicholas Marriott
ef35c9f765 Add --enable-coverage for gcov. 2015-09-11 13:16:35 +01:00
Nicholas Marriott
66c4ed98d6 Fix bad merge. 2015-09-10 14:59:16 +01:00
Nicholas Marriott
eb1084754c Merge branch 'master' of github.com:tmux/tmux 2015-09-10 12:42:25 +01:00
Nicholas Marriott
79e5b62907 osdep_event_init not event_init. 2015-09-10 12:41:49 +01:00
Thomas Adam
1fd756066c Merge branch 'obsd-master' 2015-09-10 12:01:08 +01:00
nicm
cfabe30bec Add session_last_attached time and format, from Sina Siadat. 2015-09-10 08:58:14 +00:00
Thomas Adam
5af2f68a2c Merge branch 'obsd-master' 2015-09-09 14:01:08 +01:00
nicm
67ee995cc1 No need to keep global options around for client which doesn't use them. 2015-09-09 12:09:21 +00:00
Thomas Adam
fe536457cc Fix includes
Let compat/ work out the includes; otherwise works on OpenBSD.
2015-09-06 21:29:36 +01:00
Thomas Adam
76688d2040 Merge branch 'obsd-master'
Conflicts:
	cfg.c
	tmux.c
2015-09-06 20:47:50 +01:00
nicm
aceae73b9a Change wait-for to work when the signal comes before the wait, also use
some helper functions and add some logging.
2015-09-04 12:02:44 +00:00
nicm
82326dcbe2 A couple of style nits. 2015-09-03 14:30:23 +00:00
nicm
6c10fc659a Log pane which received input data. 2015-09-02 17:52:57 +00:00
nicm
38e3baab2a A one line helper function is a little silly. 2015-09-02 17:43:25 +00:00
nicm
8121127606 We no longer need the terminal service class, so don't bother asking for it. 2015-09-02 17:37:54 +00:00
nicm
a45164f2e0 Fix indentation of grid_string_cells_fg. 2015-09-02 17:12:07 +00:00
Nicholas Marriott
2ebef95994 Sync up vis.* for stravis(). 2015-09-01 21:08:19 +01:00
nicm
93b946ee50 Tweak some error messages/comments. 2015-09-01 19:50:09 +00:00
nicm
66a2720c56 Log the whole new input buffer once rather than each byte. 2015-09-01 19:16:00 +00:00
nicm
364a885b0c Pass logging through vis(3). 2015-09-01 19:14:43 +00:00
nicm
fa3d4fab85 Fix a spelling error, sesson -> session. 2015-09-01 18:50:16 +00:00
nicm
69a2d46ee5 Remove dead_clients which is no longer used. 2015-09-01 11:13:39 +00:00
nicm
952ba84611 Work out config file when needed not at startup. 2015-09-01 10:10:59 +00:00
nicm
83157c02d6 Move initial conf load into cfg.c. 2015-09-01 10:01:56 +00:00
nicm
2a836bc306 All the cmd_*_entry declarations do not need to be in tmux.h. 2015-09-01 09:48:34 +00:00
Nicholas Marriott
2c6ea705fd Bring back pane_current_path. 2015-08-31 19:57:37 +01:00
nicm
6a539c00df Path from $TMUX does not need to be global anymore. 2015-08-30 22:56:36 +00:00
nicm
c6e9160c67 Login shell can be a client flag, and move the exec code into client.c. 2015-08-30 22:40:25 +00:00
nicm
dd92b6e83d Event base does not need to be global. 2015-08-30 22:19:07 +00:00
Thomas Adam
29f2120e5b Linux: get_proc_name() -> osdep_get_name() 2015-08-30 21:47:50 +01:00
Thomas Adam
cb89f2f2a1 Merge branch 'obsd-master'
Conflicts:
	Makefile
	format.c
2015-08-30 21:44:01 +01:00
nicm
b87dc608d9 Some style nits and dead assignments. 2015-08-30 15:43:40 +00:00
nicm
5047670693 Remove some old prototypes and unused functions. 2015-08-29 23:55:55 +00:00
nicm
52bbac506c struct args_entry can go into arguments.c. 2015-08-29 23:19:52 +00:00
nicm
373ef850e0 paste_send_pane can be merged into cmd-paste-buffer.c now. 2015-08-29 09:36:46 +00:00
nicm
b569585000 Move struct paste_buffer out of tmux.h. 2015-08-29 09:25:00 +00:00
nicm
b9f0571780 We already loop over the windows in server_client_loop, so don't do it
again in server_loop just to check names.
2015-08-29 08:54:41 +00:00
nicm
b5aaefc727 Move alerts onto events rather than checking every loop. 2015-08-29 08:30:54 +00:00
nicm
5267ce8ff4 Treat entering or leaving a mode as pane changed. 2015-08-29 00:39:18 +00:00
nicm
b7861f34ba Better take on reducing the name timer. Again check for name changes in
the main loop after events that may have changed the pane, but do so at
most once every 500 millis. If the pane changed too soon, use a timer to
ensure that a check happens later.
2015-08-29 00:29:15 +00:00
nicm
73bd816076 Microseconds in log time. 2015-08-29 00:24:44 +00:00
nicm
d9b3133321 Only set default title to hostname on screens that are being used for a
window pane, no point in calling gethostname() for temporary screens.
2015-08-28 17:11:12 +00:00
nicm
5f122af556 Make a few more expensive (ish) formats functions instead of inline. 2015-08-28 17:01:42 +00:00
nicm
983ebb2689 Allow formats to be specified as functions (in the code) so they are
only evaluated on demand rather than each time a format tree is
constructed. Use this for expensive formats like pane_current_command.
2015-08-28 16:46:40 +00:00
nicm
55b8d74561 Revert previous; we do need a timer, until I have a better idea. We
can't do the name check every loop, because that is too expensive, and
we can't make sure it only happens infrequently because we have no idea
when the next change will happen.
2015-08-28 16:10:46 +00:00
nicm
e2100c5f5f We now only checking for name changes when the active pane has changed,
but that can only happen when we have already been woken up by a read
event, so there is no need for a timer, we can just check the changed
flag on the end of that read event (we already loop over the windows to
check for bells etc anyway).
2015-08-28 15:51:48 +00:00
Thomas Adam
486421ceff Merge branch 'obsd-master' 2015-08-28 16:01:09 +01:00
nicm
b0940bdf54 Check changed flag after restarting timer. 2015-08-28 13:26:41 +00:00
nicm
f957db81d9 Remove unused prototypes. 2015-08-28 13:21:25 +00:00
nicm
ed2a486f46 Don't leak name when freeing session, from Kuang-che Wu. 2015-08-28 13:16:03 +00:00
nicm
f6a0f8730e Per-session timers for locking, and remove the global one-second timer. 2015-08-28 13:12:20 +00:00
Thomas Adam
84eabb2658 Merge branch 'obsd-master' 2015-08-28 14:01:11 +01:00
nicm
57cc4d45d5 Make session_update_activity more useful and use it in more places. 2015-08-28 13:01:03 +00:00
nicm
675def0396 Remove the lock-server option which is a bit redundant, it isn't that
different without it.
2015-08-28 12:31:55 +00:00
nicm
6419f66523 Give clock mode its own timer. 2015-08-28 12:25:42 +00:00
nicm
75d10058a4 Run status update on a per-client timer at status-interval. 2015-08-28 12:16:28 +00:00
nicm
18d4802a7b Log time with message. 2015-08-28 12:15:54 +00:00
nicm
b6618b631b Move format job cleanup onto its own timer. 2015-08-28 11:38:27 +00:00
Thomas Adam
31c027a37a Merge branch 'obsd-master' 2015-08-28 12:01:07 +01:00
nicm
ee9f708500 Allow environment variables in #{}. 2015-08-28 10:06:52 +00:00
Thomas Adam
031d7ce840 Merge branch 'obsd-master' 2015-08-28 10:01:08 +01:00
nicm
25faca41eb Error messages should not have a trailing period. 2015-08-28 07:55:43 +00:00
nicm
fc58e44f89 Only do the automatic-rename dance if the pane has changed (seen output,
or new active pane).
2015-08-28 07:49:24 +00:00
Thomas Adam
ce20572ace Merge branch 'obsd-master' 2015-08-25 18:01:07 +01:00
nicm
2ffbd5b5f0 When searching for tabs, start from screen width, fixes out-of-bounds
read found by Kuang-che Wu.
2015-08-25 15:00:05 +00:00
Thomas Adam
429f86397b Merge branch 'obsd-master' 2015-08-25 02:01:16 +01:00
nicm
3219e0314e In grid_duplicate_lines, if the line is empty (cellsize == 0) then clear
the destination celldata pointer rather than leaving a stale copy of the
source pointer (which may later be freed). Fixes a crash found by
Kuang-che Wu.
2015-08-24 22:49:13 +00:00
Thomas Adam
65b45c9c32 Merge branch 'obsd-master' 2015-08-16 12:01:06 +01:00
nicm
58b659a26e Come out of copy mode when history is cleared. 2015-08-16 08:57:34 +00:00
Nicholas Marriott
f5357ed940 Handle \ at EOL from Daniel Hahler. 2015-08-15 09:53:19 +01:00
Thomas Adam
778612d152 Merge branch 'obsd-master' 2015-08-13 18:01:07 +01:00
nicm
46aa92420a right-up should be right-of, also rename the values too. 2015-08-13 15:02:23 +00:00
Thomas Adam
6447404cc2 Merge branch 'obsd-master' 2015-08-12 12:01:09 +01:00
nicm
13b7fd82c1 Rename left/right/up/down relative to active pane to add -of suffix
(left-of/right-of/etc) to remove conflict with left/right meaning
leftmost or rightmost pane. From Ben Boeckel.
2015-08-12 08:55:20 +00:00
Nicholas Marriott
3c9b8a28c6 Merge branch 'master' of github.com:tmux/tmux 2015-08-07 15:08:26 +01:00
Nicholas Marriott
736d8350e9 +history-file, from Ben Boeckel. 2015-08-07 15:06:17 +01:00
Thomas Adam
73b4d098ce Merge branch 'obsd-master' 2015-07-29 14:01:09 +01:00
nicm
5ec3621101 status_out and associated data structures are no longer used. 2015-07-29 11:56:02 +00:00
Thomas Adam
a568aaa0c0 Merge branch 'obsd-master' 2015-07-28 18:01:08 +01:00
nicm
b254115acd Tidy up the way terminals are described and move some structs out of tmux.h. 2015-07-28 15:18:10 +00:00
Thomas Adam
ff18787b2c Merge branch 'obsd-master' 2015-07-27 10:01:08 +01:00
nicm
d33adc4fd0 Make -q suppress ambiguous option warnings too, from Cam Hutchison. 2015-07-27 08:45:45 +00:00
Nicholas Marriott
e4cdc9fa0b Merge branch 'master' of github.com:tmux/tmux 2015-07-24 09:10:21 +01:00
Nicholas Marriott
669059aa19 Fix a warning, from Kosta Zertsekel. 2015-07-24 09:06:15 +01:00
Thomas Adam
18a64ad52d Merge branch 'obsd-master' 2015-07-20 18:01:10 +01:00
nicm
92af3766ec Add an option (history-file) for a file to save/restore command prompt
history, from Olof-Joachim Frahm.
2015-07-20 15:50:04 +00:00
Thomas Adam
dedd9edf7f Merge branch 'obsd-master' 2015-07-20 12:01:07 +01:00
nicm
d4ce210713 Correct the tsl/fsl sequence to ]0 not ]2 (from Marcel Korpel). While
here, Xr xterm and remove some advice about elinks that is better
elsewhere.
2015-07-20 10:34:11 +00:00
Nicholas Marriott
e6facdcb0c Merge branch 'master' of github.com:tmux/tmux 2015-07-19 08:10:07 +01:00
Nicholas Marriott
96dcbe217b Update tmux.vim from Ben Boeckel. 2015-07-19 08:07:55 +01:00
Thomas Adam
e45f42db29 Merge branch 'obsd-master' 2015-07-17 16:01:07 +01:00
nicm
bad8d0fd20 Do not call window_unzoom from window_destroy because it will try to add
a notification which will get confused because the reference count is
already zero and end up back in window_destroy and a double
free. Instead, just destroy the layouts directly. Noticed by Thomas
Adam.
2015-07-17 13:09:07 +00:00
Thomas Adam
b886393042 Merge branch 'obsd-master' 2015-07-17 10:01:09 +01:00
nicm
3192178f15 Initialize client fd to -1 as well, from Bobby Powers. 2015-07-17 06:53:47 +00:00
Nicholas Marriott
8c96e2a6d9 Implement osdep_get_name and osdep_get_cwd for AIX, from J Raynor. 2015-07-15 08:46:35 +01:00
Nicholas Marriott
5ffb869e1a Merge branch 'master' of github.com:tmux/tmux 2015-07-14 08:15:05 +01:00
Nicholas Marriott
bed3069fd7 Add _LINUX_SOURCE_COMPAT on AIX. 2015-07-14 08:14:35 +01:00
Thomas Adam
dcc28434f4 Merge branch 'obsd-master' 2015-07-13 20:01:08 +01:00
nicm
8dcea2cc14 Reset G0/G1 state when resetting everything else with send-keys -R. 2015-07-13 18:45:18 +00:00
nicm
4e637b1b61 Ignore environment variables that are too long to send to the server. 2015-07-13 18:10:26 +00:00
Thomas Adam
07aef38591 Merge branch 'obsd-master' 2015-07-13 18:01:09 +01:00
nicm
e45d624df2 Fix line endings. 2015-07-13 15:51:31 +00:00
nicm
c7374c31c4 Initialize cwd fd to -1 so that we don't close fd 0 if the client is
destroyed before it is changed. Also allow ttyname() to fail. Fixes
problems when running out of file descriptors reported by Bruno Sutic.
2015-07-13 15:49:31 +00:00
nicm
81069f66f9 Add a format to show if client is a control client. From Bruno Sutic. 2015-07-13 15:37:26 +00:00
Thomas Adam
38d4d69639 Merge branch 'obsd-master' 2015-07-13 16:01:09 +01:00
nicm
6308c48efd Add a -s flag to show-environment to output Bourne shell commands a la
ssh-agent. Mostly from Cam Hutchison with some changes by me.
2015-07-13 13:36:29 +00:00
nicm
cc768d77ec Revert to marking lines as wrapped on newlines, fixes problems with
capturep -J.
2015-07-13 13:28:50 +00:00
Nicholas Marriott
73f9f0334c Check for flock in libbsd for AIX, and remove some getopt.h includes. From J
Raynor.
2015-07-13 14:19:50 +01:00
Nicholas Marriott
28c33f67bc Merge branch 'master' of github.com:tmux/tmux 2015-07-12 19:47:47 +01:00
Nicholas Marriott
235e0bd65a Update imsg*.[ch] from OpenBSD, including bzero->memset. 2015-07-12 19:46:58 +01:00
Thomas Adam
9a0ce98c54 Merge branch 'obsd-master' 2015-07-06 16:01:10 +01:00
nicm
b298478435 Update environment with -E when attach-session used on an already
attached session or switch-client used on the current session. From Cam
Hutchison.
2015-07-06 14:24:57 +00:00
Thomas Adam
78723af99f README: Clarify SYNCING is under the ISC 2015-06-28 12:01:19 +01:00
Nicholas Marriott
8b8a007e8e Merge branch 'master' of github.com:tmux/tmux 2015-06-20 08:45:19 +01:00
Nicholas Marriott
8abcea18a2 Remove monitor-content options which have been removed, from Guy Hughes. 2015-06-20 08:43:55 +01:00
Thomas Adam
0ef3e28609 Merge branch 'obsd-master' 2015-06-19 02:01:10 +01:00
nicm
f557c7d8ca Use the SRCDST define for usage. 2015-06-18 23:56:01 +00:00
nicm
b43b13faf9 Use xsnprintf. 2015-06-18 23:55:24 +00:00
nicm
164ba041c9 Remove a stray : and tweak paragraph. 2015-06-18 23:53:56 +00:00
Thomas Adam
86018a3947 Merge branch 'obsd-master' 2015-06-17 22:01:13 +01:00
nicm
85120b37ea Change break-pane to take target and source panes (-t and -s) in line
with other commands, from Thomas Adam.
2015-06-17 19:56:08 +00:00
Thomas Adam
21a2ccc5f1 Merge branch 'obsd-master' 2015-06-17 20:01:12 +01:00
nicm
84f0622c85 Break cmdq_continue inner loop into a helper function. 2015-06-17 17:02:15 +00:00
Thomas Adam
a584e11d6b Merge branch 'obsd-master' 2015-06-17 18:01:07 +01:00
nicm
0ff335961e Move the shuffle code from new-window -a into a function and add a -a
flag for move-window too. From Thomas Adam.
2015-06-17 16:50:28 +00:00
nicm
021cdbe1c0 Use an explicit job state instead of avoid closing our side of the
socketpair and setting it to -1 to mark when the other side is
closed. This avoids closing it while the libevent bufferevent still has
it (it could try to add it to the polled set which some mechanisms don't
like). Fixes part a problem reported by Bruno Sutic.
2015-06-17 16:44:49 +00:00
Thomas Adam
9fdc3a069a Merge branch 'obsd-master' 2015-06-15 14:01:09 +01:00
nicm
d96ab34019 Add window_activity format, from Thomas Adam based on a diff originally
from propos6 at gmail dot com.
2015-06-15 10:58:01 +00:00
Thomas Adam
37005d04a9 Merge branch 'obsd-master' 2015-06-14 12:01:10 +01:00
nicm
29c29e7717 Add a format for client PID (client_pid) and server PID (pid). Diff for
client_pid from Thomas Adam.
2015-06-14 10:07:44 +00:00
Thomas Adam
48a46e066e Merge branch 'obsd-master' 2015-06-10 16:01:08 +01:00
Nicholas Marriott
ba665e24e3 Merge branch 'master' of github.com:tmux/tmux 2015-06-10 15:41:35 +01:00
Nicholas Marriott
dca084e703 Don't leak dotfd if fchdir fails. From ettl dot martin78 at gmail dot com. 2015-06-10 15:39:23 +01:00
nicm
bbc0898060 wp->tty is a char [] not a char * so it can't be NULL. From Thomas Adam. 2015-06-10 12:56:04 +00:00
Thomas Adam
0ff172fabf Merge branch 'obsd-master' 2015-06-09 10:01:10 +01:00
nicm
a412dd616f Fix loop comparison broken in last commit, from Thomas Adam. 2015-06-09 07:07:06 +00:00
Nicholas Marriott
02a848d77c It isn't supposed to... 2015-06-08 09:46:14 +01:00
Thomas Adam
7acc4addb5 Merge branch 'obsd-master'
Conflicts:
	client.c
	tmux.1
	tmux.c
2015-06-07 23:42:25 +01:00
nicm
c4e811e519 Add -E flag when attaching or switching client to bypass
update-environment, from Steven Lu.
2015-06-07 21:39:39 +00:00
Nicholas Marriott
a5c55e4393 Update TODO. 2015-06-07 08:36:03 +01:00
nicm
ed6c036ee3 Use ints for the calculations rather than u_char, they could end up
signed.
2015-06-05 22:50:27 +00:00
nicm
55b96a5bd5 Handle the RGB colour escape sequence (\033[38;2;<r>;<g>;<b>m and 48;2)
like xterm(1) does, by mapping to the nearest in the 256 colour palette.
2015-06-05 22:33:39 +00:00
nicm
1cb073d48e Use fixed colour tables rather than generated and do a quick search for
exact match before doing the distance comparison.
2015-06-05 22:01:17 +00:00
nicm
641a9cd3f5 Similarly, for sessions use a callback to free rather than checking
every loop.
2015-06-05 18:18:32 +00:00
nicm
10e90ae01f Change deref to the more sensible unref, and add a couple I missed before. 2015-06-05 18:06:30 +00:00
nicm
8c93b768e4 Instead of putting dead clients on a list and checking it every loop,
use event_once to queue a callback to deal with them. Also dead clients
with references would never actually be freed because the wrap-up
functions (the callback for stdin, or status_prompt_clear) would never
be called. So call them in server_client_lost.
2015-06-05 18:01:12 +00:00
nicm
b0782df8a6 Do not use the key variable uninitialized (in a debug log statement),
reported by jungleboogie0 at gmail dot com.
2015-06-05 15:10:13 +00:00
Nicholas Marriott
f7598b8a26 Only need *.ch in compat. 2015-06-05 12:44:15 +01:00
nicm
2f586905fc Fix a warning. 2015-06-05 09:09:08 +00:00
nicm
4219939c10 Make it so that if a window or session target is prefixed with an =,
only an exact name or index match is accepted, no special character,
prefix match, or fnmatch.
2015-06-05 08:14:16 +00:00
nicm
6b2129696f Move the nested check from client to server and compare the client tty
name to all the pane pty names instead of comparing socket paths. This
means that "new -d" will work without unsetting $TMUX.
2015-06-04 23:27:51 +00:00
jmc
dc0d34e137 tweak SYNOPSIS and usage(); 2015-06-04 20:34:22 +00:00
Thomas Adam
83a70172a4 Merge branch 'obsd-master' 2015-06-04 16:01:07 +01:00
nicm
4a6c06d6a9 Make unsetting a global option restore it to the default. Diff lying
around for a while, I have forgotten who suggested it :-/.
2015-06-04 14:29:33 +00:00
Thomas Adam
02e348c069 Merge branch 'obsd-master' 2015-06-04 12:59:41 +01:00
nicm
a863834574 Add support for a single "marked pane". There is one marked pane in the
server at a time; it may be toggled or cleared with select-pane -m and
-M (the border is highlighted). A new target '~' or '{marked}' specifies
the marked pane to commands and it is the default target for the
swap-pane and join-pane -s flag (this makes them much simpler to use -
mark the source pane and then change to the target pane to run swapp or
joinp).
2015-06-04 11:43:51 +00:00
Nicholas Marriott
1de74e27e5 Spaces -> tabs. 2015-06-04 11:40:27 +01:00
Nicholas Marriott
d058e963fd Update mailmap. 2015-06-04 11:36:44 +01:00
Thomas Adam
13808ccede Merge branch 'obsd-master' 2015-06-04 11:17:39 +01:00
nicm
a3edfd9e84 teminal -> terminal, from Corey Farwell. 2015-06-04 09:42:29 +00:00
Nicholas Marriott
75b70be4a6 Merge branch 'master' of github.com:tmux/tmux 2015-06-04 10:38:04 +01:00
Nicholas Marriott
b67db455a8 Update TODO with some items from old SF tickets. 2015-06-04 10:37:39 +01:00
Thomas Adam
2c29b3e82c SYNCING: Few tweaks 2015-06-04 10:35:40 +01:00
Thomas Adam
8fcac1b794 SYNCING: Update for GH
Explain the release process now that we're using GH.
2015-06-04 09:26:35 +01:00
Nicholas Marriott
75061cb45d I no longer need to care about GCC 3. 2015-06-04 08:50:20 +01:00
Nicholas Marriott
20598dff25 Note version this happened. 2015-06-04 08:47:23 +01:00
Nicholas Marriott
0b22d574e0 Update FAQ for new behaviour. 2015-06-04 08:46:49 +01:00
Nicholas Marriott
1df39aa962 I don't think we should carry around scripts. I'm not too sure about examples/
at all, nobody is maintaining it...
2015-06-04 08:26:50 +01:00
Nicholas Marriott
9d80ad16f9 Remove old tools. 2015-06-04 08:25:39 +01:00
Nicholas Marriott
c0a790453c Add a couple of presentations I wrote a few years ago. One for the ill-fated
AsiaBSDCon in 2011 (canceled due to Fukushima) and the other for LinuxTag 11 in
Berlin.
2015-06-04 08:23:40 +01:00
Nicholas Marriott
dbc5d7b331 Fix clone URL. 2015-06-04 01:27:47 +01:00
Nicholas Marriott
3ed03df23f Remove this file. 2015-06-04 01:26:03 +01:00
Nicholas Marriott
32bc8f4dd4 HTML bits are now elsewhere. 2015-06-04 01:21:41 +01:00
Nicholas Marriott
d2b35e19cd No more SF. 2015-06-04 00:44:22 +01:00
Nicholas Marriott
89131c3e90 No $Id$. 2015-06-04 00:38:01 +01:00
Nicholas Marriott
fc2fb0eb95 Update mailing list addresses. 2015-06-03 18:57:35 +01:00
Nicholas Marriott
dfd72f5250 -$Id$. 2015-06-03 18:42:36 +01:00
Nicholas Marriott
11ae6d16e5 $Id$ -> $OpenBSD$. 2015-06-03 18:35:44 +01:00
Nicholas Marriott
09bcbc57da $Id$ -> $OpenBSD$. 2015-06-03 18:28:26 +01:00
Nicholas Marriott
1c3e1bae41 Remove $Id$. 2015-06-03 18:26:25 +01:00
Nicholas Marriott
3821ca4917 Update TODO. 2015-06-02 15:16:13 +01:00
Thomas Adam
7bf5d4b946 Merge branch 'obsd-master' 2015-06-01 16:01:19 +01:00
nicm
a3c6172495 Missing t at end of response, from Vincent Bernat. 2015-06-01 13:59:57 +00:00
Thomas Adam
b675e6b2d5 Merge branch 'obsd-master' 2015-06-01 12:01:17 +01:00
nicm
58b50fb543 Clear signal handlers before event_reinit as apparently it can otherwise
cause libevent to go strange.
2015-06-01 09:20:19 +00:00
Thomas Adam
7712e6f82b Merge branch 'obsd-master' 2015-06-01 02:01:17 +01:00
deraadt
7e067cb9dc does not need syslog.h 2015-05-31 23:27:06 +00:00
Thomas Adam
c39dfb17ae Merge branch 'obsd-master' 2015-05-30 02:01:18 +01:00
nicm
2a8c2648f0 Don't use special strings if #() commands fail, just remove the format
(as if the command produced nothing). Makes constructions that can fail
like '#(test whatever && echo foo)' work as they did before.
2015-05-29 23:26:52 +00:00
nicm
74c755f2ab Expand formats again inside #(), and free the temporaries. 2015-05-29 23:12:38 +00:00
nicm
a55e569af5 Use RB_MIN to get the lowest index for the current window when creating
grouped sessions, rather than using RB_ROOT.
2015-05-29 23:02:27 +00:00
Thomas Adam
beffdf6575 Merge branch 'obsd-master' 2015-05-27 16:01:22 +01:00
nicm
379400cfa6 Move the jobs output cache into the formats code so that #() work more
generally (for example, again working in set-titles-string).
2015-05-27 13:28:04 +00:00
Thomas Adam
f538f2ae9b Merge branch 'obsd-master' 2015-05-20 10:01:19 +01:00
nicm
7140cce7f3 Return empty string if format is empty rather than attempting to
allocate zero bytes.
2015-05-20 06:39:02 +00:00
n6tadam
1ec93570bf Merge branch 'obsd-master' 2015-05-19 12:01:20 +01:00
nicm
2c53b23d59 In terminfo, sometimes cvvis implies cnorm and sometimes it doesn't, so
don't assume it does. Fixes missing cursor with emacs-in-tmux-in-tmux.
2015-05-19 08:48:37 +00:00
Thomas Adam
4123d69b51 README.md: github-specific readme
This is the same as the current README, but allows for markdown to be used.
We could switch this over to using the README file at some point.
2015-05-17 14:52:58 +01:00
Thomas Adam
35d21be19a TRAVIS-CI: correct path to configure
Specify path to ./configure
2015-05-17 14:39:04 +01:00
Thomas Adam
beb0c01c27 Hook repo to Travis-CI
From now on, all pushes to master will result in tmux compiling against a
linux-based distribution (Debian).  This will make it easier for automatic
merges between OpenBSD and portable to be tested, without the need for so
much manual syncing.

Any build failures will be reported to me, and fixed accordingly.
2015-05-17 14:36:34 +01:00
Thomas Adam
00471dc783 Merge branch 'obsd-master' 2015-05-13 09:44:11 +01:00
nicm
3f4ee98162 To replace c0-*, add a high watermark to the pty event, and also backoff
when the any of the ttys the pane is going to write to has buffered
enough data.
2015-05-12 22:40:38 +00:00
nicm
37ae8a9e0f Tidy blank lines when outputting server info. 2015-05-12 19:36:08 +00:00
nicm
ec34439f9c Add a session_alerts format which is a list of all the alerts in the
current session in symbolic form (something like "0!,4~,5!"). Use this
in the default set-titles-string. Prompted by a request from Jan ONDREJ.
2015-05-12 15:29:29 +00:00
nicm
e958db09a7 Add bell-action "other" to pass through bells in all windows except the
current, suggested by Jan ONDREJ.
2015-05-12 15:27:46 +00:00
nicm
b833fabeb2 Left the c0-* options behind in the table. 2015-05-11 10:58:22 +00:00
nicm
44364d7112 Remove the c0-* options which never really worked satisfactorily. Going
to try something else...
2015-05-11 10:10:16 +00:00
Thomas Adam
4165ed96f8 Add back __CYGWIN__ block
This went missing during the merge from OpenBSD.
2015-05-09 20:03:24 +01:00
Thomas Adam
c11f628342 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2015-05-09 12:53:53 +01:00
Thomas Adam
504b97b6a4 Merge branch 'obsd-master'
Conflicts:
	tmux.h
2015-05-09 12:52:38 +01:00
nicm
92faa2eaeb Put the tty structs together, and tabify. 2015-05-08 16:48:12 +00:00
nicm
592cb73a69 grid_marker_cell is no longer used. 2015-05-08 16:44:03 +00:00
nicm
74b2c40b1b mode_key_entry can go into mode-key.c; also a few spaces->tabs. 2015-05-08 16:33:29 +00:00
nicm
a538141a72 window_choose_mode_item can move into window-choose.c. 2015-05-08 16:23:34 +00:00
nicm
c4a4bd6ac5 Move input parser structs into input.c (removing fairly useless
saved_cursor_[xy] formats as a side-effect).
2015-05-08 16:18:04 +00:00
nicm
879de25583 Remove some stuff that accidentally ended up here from portable, and
remove a little-used debug function.
2015-05-08 15:56:49 +00:00
nicm
d174b9cfcc Update environment when switching sessions as well as attaching, from Si
Beaumont.
2015-05-07 14:07:16 +00:00
nicm
8e9b6e0948 Style spacing nits. 2015-05-07 11:42:56 +00:00
Nicholas Marriott
63b7a031a5 queue.h should come from compat.h. 2015-05-07 11:43:52 +01:00
nicm
1282bb81fe array.h can be local to window-choose.c now. 2015-05-07 08:08:54 +00:00
nicm
7becf326e3 Use a TAILQ not array for find-window. 2015-05-07 07:59:52 +00:00
nicm
73c871ba0a Simplify environ_push so it doesn't need the ARRAY_* functions. 2015-05-07 07:35:31 +00:00
nicm
b6be03f01a If status line is at the top, the offset needs to be adjusted when
drawing pane numbers.  Based on a diff from John O'Meara.
2015-05-07 07:16:14 +00:00
nicm
0b39e6427f Remove ARRAY_* from history and expand completion to complete a) layout
names and b) targets beginning with -t or -s.
2015-05-06 23:56:46 +00:00
Thomas Adam
6525ca5158 Start working on 2.1 2015-05-07 00:00:44 +01:00
Thomas Adam
e362d42dc6 CHANGES for tmux 2.0 2015-05-07 00:00:44 +01:00
Thomas Adam
f10d3675f8 Merge branch 'obsd-master' 2015-05-06 10:03:52 +01:00
nicm
31b1ab4852 Add a format window_linked which is 1 if a window has been linked
multiple times, also remove the default space in window_flags and use a
conditional to add it in window-status-format (this means additional
flags can be added in the option without extra spaces). From Thomas Adam
with tweaks by me.
2015-05-06 08:35:39 +00:00
nicm
33a585c47f Turn cursor off during redraw, pointed out by George Nachman. 2015-05-06 07:52:06 +00:00
nicm
672df72b71 Use the right index when expanding/collapsing tree, from Thomas Adam. 2015-05-04 13:04:10 +00:00
Thomas Adam
c0cf4843e5 Merge branch 'obsd-master' 2015-04-29 18:42:12 +01:00
nicm
69b8f100b7 Do not complain when directions fail. 2015-04-29 16:26:17 +00:00
nicm
7382ba82c5 If default-terminal is set to "screen" or "screen-*", emulate screen's
historical (incorrect) behaviour for SGR 3 and send smso
(standout). Previously, we would send sitm (italics) if the terminal
outside had it and smso otherwise. This was acceptably until recently
because xterm's terminfo entry lacked sitm, so most users got smso.

People who want italics should set default-terminal to the forthcoming
"tmux" entry (and be prepared to deal with it being missing on older
hosts).

As a side-effect this changes default-terminal to be a server rather
than a session option.

suggested by and ok naddy
2015-04-29 15:59:08 +00:00
Nicholas Marriott
8794562a85 Add tmux4.png. 2015-04-28 16:04:07 +01:00
Nicholas Marriott
31ab5caa35 Renumber screenshots. 2015-04-28 15:34:09 +01:00
Nicholas Marriott
1ed5326f5a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2015-04-28 15:18:53 +01:00
Nicholas Marriott
ab5f9ab55b Update two of the screenshots. 2015-04-28 15:12:45 +01:00
Thomas Adam
dc2adc6bc1 Merge branch 'obsd-master' 2015-04-28 14:57:15 +01:00
Nicholas Marriott
7981e653d8 But this does work. 2015-04-28 14:01:03 +01:00
Nicholas Marriott
bc9198072b Upload all the files. 2015-04-28 13:58:17 +01:00
Nicholas Marriott
e88c48ce0e This doesn't work. 2015-04-28 13:58:00 +01:00
Nicholas Marriott
f54f3e2abe Add logo to www, also centre the page. 2015-04-28 13:47:54 +01:00
Nicholas Marriott
bb210ce773 Add tmux logo, createed by Jason Long. 2015-04-28 13:46:47 +01:00
nicm
e36fab2f70 If looking for an index, don't fill in window when given a session. 2015-04-28 12:09:24 +00:00
nicm
14d8cd6445 Do not do a search for the tty path if there isn't one. 2015-04-28 11:57:20 +00:00
nicm
094a047ddf If can't find pane as a pane, try as a window; likewise if can't find
window as a session.
2015-04-28 11:33:17 +00:00
nicm
771744426e Add select-layout -o to undo the last layout change (apply the previously
set layout).
2015-04-28 10:43:13 +00:00
Nicholas Marriott
3eb40a520a No paths.h on Solaris. 2015-04-28 10:36:17 +01:00
Thomas Adam
7d98c51805 Merge branch 'obsd-master' 2015-04-28 09:10:51 +01:00
nicm
c2bc84aa4d Do not include unattached clients when trying to find one for target. 2015-04-27 22:58:58 +00:00
nicm
b7777e7ef3 Reset cfg_ncauses to 0 as well or we could allocate the wrong size if
called again.
2015-04-27 22:50:35 +00:00
nicm
91f6347485 Assign to the right variable when comparing clients. 2015-04-27 22:42:10 +00:00
Thomas Adam
94a8ef1cae Merge branch 'obsd-master'
Conflicts:
	Makefile
	tmux.1
2015-04-27 21:21:55 +01:00
nicm
95195f5258 Rewrite of the target resolution internals to be simpler and more
consistent but with much less duplication, but keeping the same internal
API. Also adds more readable aliases for some of the special tokens used
in targets (eg "{start}" instead of "^"). Some behaviours may have
changed, for example prefix matches now happen before fnmatch.
2015-04-27 16:25:57 +00:00
nicm
a70762c9b5 If the requested pane is already active, do not unzoom the window (or do
anything else). Prevents mouse clicking when zoomed causing unzoom,
reported by Jose Antonio Delgado Alfonso (with a different fix).
2015-04-27 07:49:36 +00:00
nicm
5bd5c9c84e Remove panes from layout if spawning them fails, reported by Anthony J
Bentley.
2015-04-26 20:25:20 +00:00
Thomas Adam
72e9ebf2ec Merge branch 'obsd-master' 2015-04-25 20:45:02 +00:00
nicm
05e7fbd60f Get rid of window_choose_list type. 2015-04-25 18:56:05 +00:00
nicm
1d1208e335 Fix some char* -> char *. 2015-04-25 18:49:01 +00:00
nicm
a568b9cadc Use a char **,u_int pair for cfg_causes. 2015-04-25 18:47:01 +00:00
nicm
07dfdb974d Make message log a TAILQ. 2015-04-25 18:33:59 +00:00
nicm
6dbd63ba4f Move the functions to convert ids from strings into session.c and window.c. 2015-04-25 18:09:28 +00:00
nicm
d23af6cca0 Explicitly cancel mouse "button" mode, this happens implicitly with some
one of the other things we send with xterm, but not with urxvt. Reported
by sthen@.
2015-04-25 15:57:48 +00:00
Thomas Adam
56e1132db4 Merge branch 'obsd-master' 2015-04-25 10:02:46 +00:00
nicm
aeedb464a6 Convert clients list into a TAILQ. 2015-04-24 23:17:11 +00:00
nicm
583b4ab72b Set working directory for run-shell and if-shell. 2015-04-24 22:19:36 +00:00
nicm
5a2d0533a8 Allow choice options (multiple states) to be toggled between states 0
and 1.
2015-04-24 21:38:18 +00:00
nicm
a5a873dccc Set up signal handler earlier so that we don't get zombies, reported by
sobrado@.
2015-04-24 20:58:44 +00:00
deraadt
ab73997cc5 use reallocarray instead of calloc; avoid the zero before infill
ok nicm
2015-04-23 07:45:50 +00:00
nicm
9a453dd354 Make session_has return a flag, returning the first winlink found is a
recipe for errors.
2015-04-22 15:32:33 +00:00
nicm
8d66f4fba4 Change the windows array into an RB tree and fix some places where we
were only looking at the first winlink for a window in a session.
2015-04-22 15:30:11 +00:00
nicm
89e80cabd5 window_index is only used in one place (window_destroy) so inline it there. 2015-04-22 15:05:03 +00:00
Thomas Adam
0a88377086 Merge branch 'obsd-master' 2015-04-22 10:05:54 +01:00
nicm
3909aff06a Look up indexes as number before name, makes more sense if windows are
named starting with numbers. From Thomas Adam.
2015-04-21 22:42:27 +00:00
nicm
69f292a90e Always format real layout even when zoomed. 2015-04-21 22:38:49 +00:00
nicm
93b2871cab Do not die on USR1 if any of the socket parent directories are
missing. Reported by Robin Powell.
2015-04-21 22:32:40 +00:00
nicm
7a72eff4a4 Simplify error messages when socket connect fails, suggested by "Karthik K". 2015-04-21 22:21:41 +00:00
nicm
d16b640fe8 The free callback could end up being fired before the done callback
(happens on Cygwin), so use a reference count instead of a single
flag. SF bug 188 reported by "iceboy".
2015-04-21 21:31:02 +00:00
nicm
0e7219d437 Fix moving windows to nonexistent indexes when renumber-windows is
off. From Thomas Adam, reported by Daniel Levai and Theo Buehler.
2015-04-21 21:24:49 +00:00
nicm
d1337053b6 Bind mouse dragging so that it is passed through to applications if they
want it rather than entering copy mode.
2015-04-21 15:34:32 +00:00
nicm
4cf4302962 Don't eat the mouse event that triggers a drag end because we may want
to pass it on to application inside the pane.
2015-04-21 15:21:41 +00:00
nicm
1f404f6a23 Put mouse_any_flag back, don't know where it went to (still in man page). 2015-04-21 15:18:38 +00:00
nicm
bc3786ece9 Pass mouse events through to commands for if-shell. 2015-04-21 15:18:06 +00:00
nicm
0610f44380 cmd_mouse_pane can return NULL, check for that. 2015-04-21 15:16:06 +00:00
nicm
07d93db427 Remove unused-but-set variables, from Thomas Adam. 2015-04-20 15:41:32 +00:00
nicm
bded743706 Support for multiple key tables to commands to be bound to sequences of
keys. The default key bindings become the "prefix" table and -n the
"root" table. Keys may be bound in new tables with bind -T and
switch-client -T used to specify the table in which the next key should
be looked up. Based on a diff from Keith Amling.
2015-04-20 15:34:56 +00:00
nicm
3497843f02 Style nit - unnecessary brackets. 2015-04-20 14:48:55 +00:00
Thomas Adam
b25dc423b0 Merge branch 'obsd-master' 2015-04-20 15:44:27 +01:00
nicm
0fd9a97202 Make jump-to-backward/jump-to-forward repeatable with
jump-reverse/jump-again, from Jacob Niehus.
2015-04-20 09:39:21 +00:00
nicm
6f587570ed Use a more sensible buffer size for flags string. 2015-04-20 07:50:49 +00:00
Nicholas Marriott
acb8248ba6 +. 2015-04-20 08:46:21 +01:00
jmc
8101f1ef16 tweak previous; 2015-04-19 22:10:30 +00:00
nicm
bbac2aee1f Honour renumber-windows when unlinking a window, from Thomas Adam. 2015-04-19 21:46:52 +00:00
nicm
bf635e7741 Rewrite of tmux mouse support which was a mess. Instead of having
options for "mouse-this" and "mouse-that", mouse events may be bound as
keys and there is one option "mouse" that turns on mouse support
entirely (set -g mouse on).

See the new MOUSE SUPPORT section of the man page for description of the
key names and new flags (-t= to specify the pane or window under mouse
as a target, and send-keys -M to pass through a mouse event).

The default builtin bindings for the mouse are:

    bind -n   MouseDown1Pane select-pane -t=; send-keys -M
    bind -n MouseDown1Status select-window -t=
    bind -n   MouseDrag1Pane copy-mode -M
    bind -n MouseDrag1Border resize-pane -M

To get the effect of turning mode-mouse off, do:

    unbind -n MouseDrag1Pane
    unbind -temacs-copy MouseDrag1Pane

The old mouse options are now gone, set-option -q may be used to
suppress warnings if mixing configuration files.
2015-04-19 21:34:21 +00:00
nicm
ee123c2489 Support setting the default window and pane background colours (window
and active pane via window-style and window-active-style options, an
individual pane by a new select-pane -P flag). From J Raynor.
2015-04-19 21:05:27 +00:00
Nicholas Marriott
24c8f523eb +. 2015-04-19 19:40:12 +01:00
Nicholas Marriott
aaad44bbe7 +. 2015-04-19 19:34:58 +01:00
Thomas Adam
370cf75458 Merge branch 'obsd-master' 2015-04-19 14:44:56 +01:00
nicm
4a7587931c Fix some issues in bright colour handling. Bold background doesn't exist
so there is no reason for tty_check_bg to mess with the BRIGHT flag at
all, ever. Also use aixterm colours for 256-to-16 translation if the
terminal supports them. And there is no reason for tty_colours_bg to
worry about whether the terminal supports them - tty_check_bg has
already taken care of it.
2015-04-15 22:34:46 +00:00
nicm
eec27f9257 Use tty_term_flag not _has for flags, also fix a typo (position not
permission).
2015-04-15 22:10:13 +00:00
nicm
f922920609 Fix setting old-style window -fg/-bg/-attr options that aren't global. 2015-04-15 15:44:40 +00:00
nicm
0cd55eb1e7 Add a -x flag to copy-selection, append-selection and start-named-buffer
to prevent it exiting copy mode after copying. From J Raynor with a few
tweaks by me.
2015-04-10 16:00:08 +00:00
nicm
009a5e4213 in the case -> in this case. 2015-04-10 07:23:14 +00:00
nicm
6920be311b When replacing, don't free the old paste until after the new one's name
has been copied. Fixes a use-after-free in window-copy.c. Bug reported
by J Raynor (who also provided a different fix).
2015-04-07 13:06:22 +00:00
nicm
3aa72b42b2 Add a helper function to convert time, and add session_activity formats
(the latter from Takatoshi Matsumoto).
2015-03-31 17:58:36 +00:00
nicm
02df86079b Fix some format specifier nits, from Ben Boeckel. 2015-03-31 17:45:10 +00:00
Nicholas Marriott
5e956f1148 Make place const to avoid a warning, from Ben Boeckel. 2015-03-31 09:26:37 +01:00
nicm
cd9ccbc1e9 set-titles-string now uses formats, not the status bits (so no #() for
now). Reported by landry.
2015-03-11 08:17:37 +00:00
Nicholas Marriott
7536d690fd Explicitly look for cpp and egrep to avoid AC_EGREP_CPP messing up output. 2015-03-01 21:46:05 +00:00
Thomas Adam
b8aec17af1 Merge branch 'obsd-master' 2015-02-24 23:05:08 +00:00
Nicholas Marriott
f4196138ce Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2015-02-18 22:36:53 +00:00
Nicholas Marriott
fe1aa9299e Merge branch 'tmp' 2015-02-18 22:36:31 +00:00
nicm
568f5ef3c6 When given an invalid style, don't set the option to the default. Fix
from J Raynor. Also make style_parse not alter the grid_cell when it
fails.
2015-02-18 15:32:37 +00:00
Nicholas Marriott
bafe6f5a7c Remove LocalWords. 2015-02-16 17:19:37 +00:00
Thomas Adam
be6dc83277 Revert "Add -Wno-format-nonliteral to Makefile.am"
Oh well.  This will hide legitimate programming errors, which I knew, so I'll
just have to accept that when looking through the compiler output.

This reverts commit c2bbaab2ac.
2015-02-15 21:19:51 +00:00
Thomas Adam
c2bbaab2ac Add -Wno-format-nonliteral to Makefile.am
Shut GCC up about non-literal arguments to functions which make use of
placeholder expansions (printf, strftime, etc.)
2015-02-15 20:07:48 +00:00
Thomas Adam
ffb83d23e1 Merge branch 'obsd-master'
Conflicts:
	Makefile
2015-02-14 23:54:07 +00:00
nicm
4d05d88304 Take a reference to prevent cmdq being freed during the command. Can
happen to cfg_cmd_q (possibly others) when source-file recurses into
cmdq_continue. Fixes bug reported by Ismail Donmez and Theo Buehler.
2015-02-12 09:56:19 +00:00
nicm
9ae2284726 Merge clock-mode command into copy-mode. 2015-02-09 23:18:19 +00:00
Nicholas Marriott
b4750e4c35 Add a note about cmd_find_*. 2015-02-09 13:12:25 +00:00
nicm
1b2c62afe9 Entries in the window list can be NULL, prompted by a crash seen by Ben
Boeckel.
2015-02-09 12:47:18 +00:00
nicm
f28032b031 Check for \0 in the right place, from J Raynor. 2015-02-07 23:43:41 +00:00
nicm
52756fb3c5 Use the same time for both calls to format_expand_time. 2015-02-06 23:28:52 +00:00
Nicholas Marriott
cb018a4212 No paths.h on Solaris. 2015-02-06 23:24:44 +00:00
Thomas Adam
833fe5bdee Merge branch 'obsd-master'
Conflicts:
	cmd-pipe-pane.c
2015-02-06 19:07:43 +00:00
nicm
313f2263f8 status_replace can now become local to status.c and it no longer needs
the jobsflag argument. While here there is no need to repeat work that
format_defaults already does.
2015-02-06 17:21:08 +00:00
nicm
8d94bb67ab Use formats not status_replace for set-titles-string. 2015-02-06 17:17:12 +00:00
nicm
03758a50dc Add format_expand_time and use it instead of status_replace where
command execution is not needed.
2015-02-06 17:11:39 +00:00
nicm
83a8e1fd20 Move pane border options to window options rather than session, from Marc Finet. 2015-02-06 15:09:34 +00:00
nicm
90bf7026f6 Reset bracket paste mode on detach. 2015-02-05 11:46:57 +00:00
nicm
f1e68bfdd2 Remove a couple of now-unused variables. 2015-02-05 10:32:39 +00:00
nicm
4946f74253 Wrap all the individual format_* calls in a single format_defaults
functions.
2015-02-05 10:29:43 +00:00
nicm
e5d9ceff18 There is no need to save the guard state because the function checks it
again anyway.
2015-02-05 10:26:29 +00:00
nicm
c9642ee213 Remove two unused arguments from status_replace. 2015-02-01 23:43:23 +00:00
nicm
4e03239d1f Tidy up detach-client a bit. 2015-01-30 15:57:30 +00:00
nicm
144025e3e6 Focus off needs to be sent with tty_raw, reported by Geoff Nixon. 2015-01-30 12:33:03 +00:00
Nicholas Marriott
93c3fb78a3 has-session is now part of new-session. 2015-01-29 12:56:30 +00:00
Nicholas Marriott
51233d8b2a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2015-01-25 20:31:22 +00:00
nicm
adcc71d4d5 Don't leak the individual strings when copying environment. 2015-01-25 16:53:46 +00:00
Nicholas Marriott
68429cd0d3 Spaces to tabs. 2015-01-25 16:51:49 +00:00
sthen
c38f0d85da In options-table.c r1.51 an extra space was added to the default status-right,
overrunning status-right-length with long window titles. Allow for the extra
space so the last digit of the year isn't lost.  ok nicm@
2015-01-21 12:20:56 +00:00
sthen
f9c7f9a17a typo in comment ;) ok nicm 2015-01-20 10:57:10 +00:00
nicm
16bdd970dc Support blinking cursor mode, both the xterm CSI ?12 h/l and (the
backwards) screen CSI 34 h/l. From Guanpeng Xu.
2015-01-20 08:18:04 +00:00
nicm
d451502676 Make a tmux-%u directory under TMUX_TMPDIR, like TMPDIR. 2015-01-19 09:58:34 +00:00
Thomas Adam
df6488a470 Merge branch 'obsd-master' 2015-01-16 19:17:31 +00:00
deraadt
776eef49d8 Replace <sys/param.h> with <limits.h> and other less dirty headers where
possible.  Annotate <sys/param.h> lines with their current reasons.  Switch
to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, LOGIN_NAME_MAX, etc.  Change
MIN() and MAX() to local definitions of MINIMUM() and MAXIMUM() where
sensible to avoid pulling in the pollution.  These are the files confirmed
through binary verification.
ok guenther, millert, doug (helped with the verification protocol)
2015-01-16 06:40:13 +00:00
nicm
6e764fb53e Remove an unnecessary variable and shorten a line. 2015-01-15 13:43:13 +00:00
nicm
86207ee676 Shorten some long lines. 2015-01-15 13:35:13 +00:00
Nicholas Marriott
66e8811c64 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2015-01-12 22:46:44 +00:00
Nicholas Marriott
a9644c1f8b We do not need to add /usr/local to CPPFLAGS; if configure managed to pass then
the dependencies must already be in the search path. Reported by Romain Naour.
2015-01-12 22:46:06 +00:00
deraadt
8a8e2eb04a correctly use HOST_NAME_MAX.
Some notes:
POSIX HOST_NAME_MAX doesn't include the NUL.
POSIX LOGIN_NAME_MAX and TTY_NAME_MAX do include the NUL.

BSD MAXHOSTNAMELEN includes the NUL.  Actually, most of the historical
BSD MAX* defines did include the NUL, except for the historical
mistake of utmp fields without NULs in the string, which directly led
to strncpy..  just showing how error prone this kind of accounting is.
CSRG did right.  Somehow POSIX missed the memo on the concepts of
carefulness and consistancy, and we are still paying the price when
people trip over this.  Of course, glibc is even more amazing (that is
a hint to blackhats)

ok guenther
2015-01-11 04:14:40 +00:00
Thomas Adam
da72a0b7a8 Merge branch 'obsd-master' 2015-01-10 21:38:50 +00:00
nicm
aae2b7aa89 Revert to r1.16 since this is still clearly broken and I can't see how
right now.
2015-01-06 21:14:42 +00:00
nicm
fee096a406 Unzoom before kill, from Thomas Adam. 2015-01-06 09:12:53 +00:00
nicm
be0ad01b7c Add missing default bindings, from Theo Buehler. 2015-01-06 09:12:02 +00:00
Nicholas Marriott
daea0e4fff Need param.h, from Ismail Donmez. 2014-12-31 10:00:47 +00:00
Nicholas Marriott
cc1bc9717c Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-12-21 15:47:21 +00:00
Nicholas Marriott
9cb5afe114 t_kP is the same as PageUp, so no need for it, from Daniel Hahler. 2014-12-21 15:46:43 +00:00
Thomas Adam
2a9a75a569 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-12-19 19:23:08 +00:00
Thomas Adam
5f8138faf5 Merge branch 'obsd-master'
Conflicts:
	format.c
2014-12-19 19:22:19 +00:00
nicm
160e3e2be3 Notify on zoom/unzoom, from George Nachmann. 2014-12-15 10:04:18 +00:00
nicm
d88c381ce9 Only redraw affected lines when selection changes with mouse. From
Michael Graczyk.
2014-12-15 10:02:55 +00:00
Nicholas Marriott
f495b150fa Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-12-15 09:24:15 +00:00
Nicholas Marriott
3771ab7c67 Add missing va_end, from Thomas Jarosch. 2014-12-15 09:23:34 +00:00
nicm
7a0c94b28a Add pane_dead_status for exit status of dead panes. 2014-12-09 19:23:35 +00:00
Nicholas Marriott
32f1ceddc9 Tweak ordering and whitespace. 2014-12-06 00:07:55 +00:00
Thomas Adam
ccbe2545d9 Merge branch 'obsd-master' 2014-12-03 08:41:08 +00:00
nicm
54ca7b230d Add -F to if-shell to allow it to be used to check for format or option
values rather than executing a command.
2014-12-02 23:39:02 +00:00
nicm
575fd1e322 Permit option values to be used in formats. 2014-12-02 23:19:45 +00:00
nicm
e52d791212 Another fix for insertion from Balazs Kezes. On insertion, size the line
just enough for the inserted characters.
2014-12-01 22:22:14 +00:00
nicm
c8bf8ee931 Check ZOOMED flag on window. 2014-12-01 14:30:18 +00:00
nicm
c403bfc894 Remove dead code, from Thomas Adam. 2014-11-30 08:03:29 +00:00
millert
a3612a5472 Prefer setvbuf() to setlinebuf() for portability; ok deraadt@ 2014-11-26 18:34:51 +00:00
Thomas Adam
3e8efcc555 Merge branch 'obsd-master' 2014-11-19 09:22:03 +00:00
nicm
e0929262db Label windows which are smaller than expected with a reason. 2014-11-14 02:19:47 +00:00
nicm
7cc4706646 Restore change in r1.17 but add checks to prevent the line length
overflowing, from Balazs Kezes.
2014-11-12 22:59:45 +00:00
nicm
d37f266524 Add -b to splitw like joinw, from Felix Rosencrantz. 2014-11-12 22:57:06 +00:00
Thomas Adam
bd803e82e9 Merge branch 'obsd-master' 2014-11-12 21:58:05 +00:00
nicm
f9308bc244 Don't let force-width or force-height be < PANE_MINIMUM. 2014-11-12 16:00:03 +00:00
nicm
7697f5aa8f Revert r1.17 as it breaks inserting in some cases. 2014-11-10 19:53:32 +00:00
nicm
4429941668 Expand formats in copy-pipe command, suggested by Suraj N Kurapati. 2014-11-09 15:13:01 +00:00
Thomas Adam
fc05bf255a Merge branch 'obsd-master' 2014-11-09 00:15:51 +00:00
nicm
8f1302282b Two improvements to reflow from Balazs Kezes:
- Don't extend the line to full width on insert/delete character which
  means leaves extra spaces when reflowing.

- Only mark a line wrapped when the cursor actually goes off the end,
  not on newlines which can be used for positioning.
2014-11-08 12:58:31 +00:00
nicm
c6129f9c09 Empty strings should be false too for #{?}, from Marc Finet. 2014-11-08 12:50:38 +00:00
Nicholas Marriott
747cab4281 No need for $Id$ now. 2014-11-08 12:27:43 +00:00
nicm
3c12b477d3 V should be vi not emacs, also sort. From Theo Buehler. 2014-11-07 12:28:28 +00:00
Nicholas Marriott
d2c9168954 +. 2014-11-06 23:30:02 +00:00
Nicholas Marriott
218b181985 Use KERN_PROC_CWD if supported, from Tiwei Bie. 2014-11-06 14:00:56 +00:00
nicm
7445d303e0 Wrap when copy mode is used for output, from Balazs Kezes. 2014-11-06 10:56:44 +00:00
Nicholas Marriott
6ca8c58462 Use -a for terminal-overrides from Daniel Hahler. 2014-11-06 10:30:05 +00:00
nicm
e4bf1e5128 Add V for select line with vi(1) keys. From Juho Pohjala. 2014-11-06 09:17:25 +00:00
nicm
79f52825b5 Tidy up mode-mouse check. 2014-11-05 23:25:02 +00:00
nicm
d24c9d7d3e Do not put a space between status-left/status-right and the window list,
instead move the space into the defaults for the options (so status-left
now defaults to "[#S] ". From Balazs Kezes.
2014-11-05 23:15:11 +00:00
Thomas Adam
35ffd093d7 Merge branch 'obsd-master'
Conflicts:
	Makefile
	cmd-link-window.c
	cmd-unlink-window.c
2014-10-29 12:51:21 +00:00
nicm
10a9440055 Merge linkw and movew which are virtually identical. 2014-10-27 22:40:29 +00:00
nicm
b496b1fe11 Move cfg_causes local into cfg.c and remove struct causelist. 2014-10-27 22:23:47 +00:00
nicm
428b51e031 Add pane_input_off format, from Anish R Athalye. 2014-10-25 08:47:04 +00:00
nicm
abfb9656ef Fix some spacing nits. 2014-10-22 23:18:53 +00:00
nicm
68cb1c0e6b Merge unlink-window into kill-window. 2014-10-22 23:11:41 +00:00
nicm
a02c2e55c0 Only redraw pane when it has actually changed. 2014-10-21 22:22:04 +00:00
nicm
85671a5bed Save next item after firing command in case it has added to the queue. 2014-10-21 22:06:46 +00:00
Nicholas Marriott
201036ad80 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-10-21 12:35:58 +01:00
Nicholas Marriott
65257b8e9b OS X lacks HOST_NAME_MAX, reported by Christian Ebert. 2014-10-21 11:00:16 +01:00
Thomas Adam
696b5a628f Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-10-21 07:12:18 +01:00
Thomas Adam
562af864bd Merge branch 'obsd-master'
Conflicts:
	Makefile
	cmd-list-commands.c
	cmd-suspend-client.c
	job.c
	tmux.h
	xmalloc.c
2014-10-21 07:11:44 +01:00
nicm
0a1a88d63c Better format for printf format attributes. 2014-10-20 23:57:13 +00:00
nicm
4c42381410 Move template defines back into .c files. 2014-10-20 23:35:28 +00:00
nicm
900f6fc17e Tidy up some includes. 2014-10-20 23:27:14 +00:00
nicm
30bacf6f30 Move suspend-client code into detach-client. 2014-10-20 23:01:51 +00:00
nicm
8a5ceac3a9 Argh, meant to remove this file... 2014-10-20 22:45:37 +00:00
nicm
f5bc85591a Move list-commands into list-keys. 2014-10-20 22:44:30 +00:00
nicm
7afe417a60 Missed a couple of cmd_entry struct members from previous. 2014-10-20 22:34:31 +00:00
nicm
45dfc5a074 Instead of setting up the default keys by building the key struct
directly with a helper function in the cmd_entry, include a table of
bind-key commands and pass them through the command parser and a
temporary cmd_q.

As well as being smaller, this will allow default bindings to be command
sequences which will probably be needed soon.
2014-10-20 22:29:25 +00:00
nicm
f0b69c7711 Fix description of Ss and Se. 2014-10-18 20:28:19 +00:00
Thomas Adam
e44bdcce4c Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-10-16 16:52:49 +01:00
Thomas Adam
2e8f6805eb OSdep: Update for xrealloc() change
This updates the code for xrealloc() which now only takes two parameters.
2014-10-16 16:50:23 +01:00
Thomas Adam
a77355b6bf Merge branch 'obsd-master' 2014-10-16 16:46:31 +01:00
nicm
a27ba6e380 Add xreallocarray and remove nmemb argument from xrealloc. 2014-10-08 17:35:58 +00:00
nicm
77efcf8bdd Use xrealloc(NULL, n, m) instead of xmalloc(n * m) to get overflow
check.
2014-10-08 17:14:04 +00:00
nicm
6610e89689 Top function key is F12 now. 2014-10-02 14:21:06 +00:00
nicm
d306bbe11e Take account of window-status-separator when checking window position,
based on diff from Balazs Kezes.
2014-10-02 10:39:43 +00:00
nicm
c011446e78 Update status when pane selected with mouse, from Balazs Kezes. 2014-10-02 09:31:30 +00:00
Nicholas Marriott
b6aef2490f Ignore ENXIO on Solaris as well, from Peter Schow. 2014-10-02 09:47:00 +01:00
nicm
2f19df09b1 Copy ACS characters as UTF-8, from Balazs Kezes. 2014-10-02 08:36:26 +00:00
Nicholas Marriott
931c17ed4f Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-10-02 09:29:48 +01:00
Nicholas Marriott
24d9dc518d Fix osdep_get_cwd on Solaris 11, from J Raynor. 2014-10-02 09:25:15 +01:00
nicm
045d0c3b9f Call waitpid on SIGCHLD even if client not attached, it is possible (on
very slow platforms) for the first daemon() child to still be running
when client_attached is set so we end up with a zombie. From J Raynor.
2014-10-01 23:23:19 +00:00
nicm
a54b0055f6 Support using pane id as part of session or window specifier (so %1
means session-of-%1 or window-of-%1) and window id as part of session
(so @1 means session-of-@1).
2014-09-25 12:51:40 +00:00
nicm
304f86cdbb Support ! for last pane. 2014-09-25 12:45:35 +00:00
Thomas Adam
2874a431c0 Merge branch 'obsd-master' 2014-09-25 11:29:54 +01:00
Nicholas Marriott
5e7f1b9f0a Don't close random file descriptor on error, from J Raynor. 2014-09-25 10:53:29 +01:00
Nicholas Marriott
16670410ca I broke last change, fix so it works, from J Raynor. 2014-09-23 10:50:11 +01:00
Nicholas Marriott
054a825ee2 cdefs.h -> types.h. 2014-09-23 10:46:46 +01:00
Nicholas Marriott
b2224947fa Solaris doesn't have flock and fcntl is useless so make a no-op flock. Reported
by Dagobert Michelsen.
2014-09-23 10:44:45 +01:00
Nicholas Marriott
4d53fd98a6 Synchronize forkpty master and child to avoid hang on AIX with fast exiting
child and output left in the queue, from J Raynor.
2014-09-22 14:07:00 +01:00
nicm
21062d74d5 Fix some comments (c -> colour) and join unnecessary line splits. 2014-09-17 15:31:38 +00:00
Nicholas Marriott
938d91d2c3 Tweak www and add RELEASE variable for current release version so we don't need
to turn it back and forth when updating.
2014-09-16 04:33:34 +01:00
Nicholas Marriott
93fe1b8659 Stupid comment. 2014-09-08 23:33:41 +01:00
nicm
9bda7e881a Add window_last_flag and window_zoomed_flag. From John Morrissey. 2014-09-08 14:29:05 +00:00
nicm
8a473b5757 Fix typo (paneas -> panes). 2014-09-01 22:00:42 +00:00
nicm
733cea8847 Wake up any clients waiting with the wait-for command when the server
exits.
2014-09-01 21:58:41 +00:00
nicm
4e956d545a Various minor style and spacing nits. 2014-09-01 21:50:18 +00:00
nicm
e075198049 Don't allow pasting into input-disabled panes, from Anish R Athalye. 2014-08-25 13:13:19 +00:00
nicm
2b79d36652 No need to repeat other-end more than once, from Juho Pohjala. Also add
it to the commands list while here.
2014-08-11 22:39:57 +00:00
nicm
29d20a55b6 Fix two copy mode problems:
1. In vi mode the selection doesn't include the last character if you
   moved the cursor up or left.
2. In emacs mode the selection includes the last character if you moved
   the cursor to the left.

From Balazs Kezes.
2014-08-11 22:18:16 +00:00
nicm
f518a077b1 Add flags to selectp to enable and disable input to a pane, from Anish
Athalye.
2014-08-11 22:14:30 +00:00
Thomas Adam
72797074f3 Add compat/fparseln.c 2014-08-09 21:16:21 +01:00
Thomas Adam
fab8ca0737 SYNCING: Make a note about libutils
Don't forget that compat/* needs updating periodically as well.
2014-08-09 20:32:09 +01:00
Thomas Adam
0e23ab4cce Sync libutil from OpenBSD (imsg)
Changes in the imsg API need to be reflected here as tmux wasn't creating
any clients because of it.
2014-08-09 20:32:01 +01:00
Thomas Adam
92997b781a Add compat/fparseln() for non-BSD systems
Linux and friends don't natively have fparseln() so add it to compat/ and
ensure autotools can pick it up.
2014-08-09 20:31:48 +01:00
Thomas Adam
a131b82e95 Merge branch 'obsd-master'
Conflicts:
	client.c
2014-08-09 20:31:36 +01:00
nicm
1ac96200a7 Remove support for the continuous reporting "any" mouse mode which never
really worked properly and is rarely used.
2014-08-09 07:33:37 +00:00
Thomas Adam
fd3b7f3572 FAQ: Mention Git before filing bug reports
It's tedious having to tell people all the time to try the Git version to
see if a given problem is reproducible; put this in the FAQ and hope people
read it.
2014-08-08 01:30:23 +01:00
nicm
b8b00aad5d Revert the up/down wheel emulation for now, there will be a better way
to do this along later for those who want it.
2014-07-21 20:45:35 +00:00
nicm
8e4ae12b4d lockf is entirely useless and it was a mistake to change to it, go back
to using flock which actually works sensibly. Also always retry the lock
to fix a potential race, and add some extra logging.
2014-07-21 10:52:48 +00:00
nicm
2056a9ef9e Drop explicit support for F13-F20 and change to match the xterm terminfo
entry:

        F13-F24 are S-F1 to S-F12
        F25-F36 are C-F1 to C-F12
        F37-F48 are C-S-F1 to C-S-F12
        F49-F60 are M-F1 to M-F12
and     F61-F63 are M-S-F1 to M-S-F3

This should be no difference for applications inside tmux, but means
that any key binding for F13 will need to be replaced by S-F1 and so on.
2014-07-21 10:25:48 +00:00
nicm
c5253ad8f7 Show an error if cmd_find_session can't find the current session, like
the other functions.
2014-07-13 20:57:46 +00:00
krw
2b67907176 An EOF is a good reason to close a connection.
ok nicm@
2014-07-13 20:51:08 +00:00
nicm
f117c7d94a If a client is killed while suspended with ^Z so has gone through the
MSG_EXITED dance, don't try to resume it since a) it's pointless and b)
the tty structures have been cleaned up and tmux will crash.
2014-07-13 20:23:10 +00:00
guenther
d1f939cede Track whether a process is a zombie or not yet fully built via flags
PS_{ZOMBIE,EMBRYO} on the process instead of peeking into the process's
thread data.  This eliminates the need for the thread-level SDEAD state.

Change kvm_getprocs() (both the sysctl() and kvm backends) to report the
"most active" scheduler state for the process's threads.

tweaks kettenis@
feedback and ok matthew@
2014-07-04 05:58:31 +00:00
tobias
1aae53596d Handle escaped back slashes and missing new lines at end of line by using
fparseln instead of reimplementing it on our own.

with input by and ok nicm@
2014-06-25 19:17:27 +00:00
nicm
54782af616 Allow keys and send-keys to invisible panes, from saggy-kun at users dot
sf dot net.
2014-06-23 10:27:05 +00:00
nicm
61605c6883 Count mouse clicks correctly, from Balazs Kezes. 2014-06-23 09:52:56 +00:00
Nicholas Marriott
f8481f93c5 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-06-21 19:48:03 +01:00
Nicholas Marriott
cddf50b715 Notes for better mouse support. 2014-06-21 19:45:52 +01:00
Nicholas Marriott
0c5ed177c4 We have utmp with utempter now and that's the best we're going to get. 2014-06-20 13:17:28 +01:00
Thomas Adam
814e40522c Merge branch 'obsd-master' 2014-06-20 12:59:43 +01:00
Nicholas Marriott
1544c688e6 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-06-20 12:20:29 +01:00
Nicholas Marriott
8049baf0bd Remove some done, tweak some others. 2014-06-20 12:19:51 +01:00
nicm
8d0819bff1 Comment style nits. 2014-06-20 11:00:19 +00:00
nicm
c8efffb4db Make -S- and -E- mean the start and end to capture-pane to avoid having
to faff around with huge numbers to get everything.
2014-06-20 10:46:59 +00:00
Nicholas Marriott
19cb0a1a92 Might as well still allow autoconf 2.59. 2014-06-19 23:15:06 +01:00
nicm
00ac1af43f Copy newline when at EOL in vi(1) mode, from Balazs Kezes. 2014-06-19 07:37:59 +00:00
nicm
fd9a53b4a4 Reset the buttons when the wheel is used, from Balazs Kezes. 2014-06-19 07:32:12 +00:00
nicm
a94696defa Some terminals send spurious releases for mouse wheel in SGR mouse mode,
this causes confusion when tmux uses SGR outside but the application
inside tmux is using conventional xterm mouse reporting. So suppress
obviously bad input. From Timothy Allen, SF bug 128.
2014-06-19 07:26:43 +00:00
Nicholas Marriott
77f582ff13 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-06-18 09:31:07 +01:00
Nicholas Marriott
f5973b7776 Build DEBUG with -O2 as well. 2014-06-18 08:21:08 +01:00
nicm
21ade85f24 Properly track switching G0 and G1 modes between US-ASCII and VT100 line
drawing rather than just treating them as SO and SI.
2014-06-06 13:21:41 +00:00
nicm
74becbfd6f Reset properly when c0-change-trigger is increased from zero so panes
don't get stuck.
2014-06-05 22:14:29 +00:00
nicm
193b6bcf36 Handle the top bit of xterm(1)-style modifier keys, based on a diff from
Balazs Kezes.
2014-05-27 13:04:42 +00:00
nicm
7160b8c2d5 Add some formats for pane bounds. 2014-05-27 12:49:36 +00:00
nicm
191f695bad Change key-table to mode-table to allow for some future work. From Keith
Amling.
2014-05-14 06:45:35 +00:00
nicm
58c97695c9 Simplify copy lines, from Keith Amling. 2014-05-14 06:39:58 +00:00
nicm
53cbae544f Now that cmdlists are reference counted, there is no need for two-step
deletion via the dead_key_bindings tree. From Keith Amling.
2014-05-14 06:21:19 +00:00
nicm
b2e791b574 Don't allow multiple buffers with the same name, from Thomas Adam. 2014-05-13 22:54:18 +00:00
Thomas Adam
92af7f5901 Linux: Add <time.h> to log.c
This is needed, otherwise tzset() is undefined.
2014-05-13 22:01:03 +01:00
Thomas Adam
bae95844d7 Merge branch 'obsd-master'
Conflicts:
	format.c
	window.c
2014-05-13 21:58:48 +01:00
nicm
b3e8d440ed If multiple arguments are given to new-session, new-window,
split-window, respawn-window or respawn-pane, pass them directly to
execvp() to help avoid quoting problems. One argument still goes to "sh
-c" like before. Requested by many over the years. Patch from J Raynor.
2014-05-13 08:08:32 +00:00
nicm
b1a06ef22e Add a copy mode key binding to copy to a named buffer. From J Raynor. 2014-05-13 07:54:20 +00:00
nicm
3dbacbb62b Add support for named buffers. If you don't name a buffer, things work
much as before - buffers are automatically named "buffer0000",
"buffer0001" and so on and ordered as a stack. Buffers can be named
explicitly when creating ("loadb -b foo" etc) or renamed ("setb -b
buffer0000 -n foo"). If buffers are named explicitly, they are not
deleted when buffer-limit is reached. Diff from J Raynor.
2014-05-13 07:34:35 +00:00
nicm
f4ffaf5a7f Just use char ** for argv like normal people, not char *const *. 2014-05-09 09:11:24 +00:00
nicm
353d1825d5 Send up and down keys for mouse wheel in alternate screen mode (when it
normally does nothing), from Marcel Partap.
2014-05-08 07:59:16 +00:00
nicm
94ccc6aeaa Instead of forcing mouse scroll to 1 in choose mode, scale it down
instead. Means modifier keys still increase the line count, just not as
much. Based on a diff from Marcel Partap.
2014-05-08 07:54:47 +00:00
nicm
189017c078 Plug a memory leak, from J Raynor. 2014-05-08 06:06:07 +00:00
nicm
540f0b3e45 Both the two previous ways of navigating panes by direction have
irritating flaws:

a) The old way of always using the top or left if the choice is
ambiguous is annoying when the layout is unbalanced.

b) The new way of remembering the last used pane is annoying if the
layout is balanced and the leftmost is obvious to the user (because
clearly if we go right from the top-left in a tiled set of four we want
to end up in top-right, even if we were last using the bottom-right).

So instead, use a combination of both: if there is only one possible
pane alongside the current pane, move to it, otherwise choose the most
recently used of the choice.
2014-05-08 06:03:30 +00:00
nicm
6369ea10d7 Handle colour 8 properly in the 256 colour palette, from Timothy Allen. 2014-05-08 05:53:29 +00:00
Thomas Adam
ea5a223a2e Merge branch 'obsd-master' 2014-04-30 00:05:58 +01:00
nicm
5b2c8156d5 fcntl.h is still needed here. 2014-04-29 22:31:22 +00:00
Thomas Adam
afb4dbd465 Typo in previous: $(srcdir) 2014-04-29 23:13:51 +01:00
Thomas Adam
b096ad9f22 Makefile.am: Honour $srcdir for mdoc2man.awk
Honour out-of-tree srcdir installs when generating the man page.  Noticed by
Jon Tibble.
2014-04-29 23:10:22 +01:00
jsg
40cb4cb086 specifying ECHOCTL once is enough
ok nicm@
2014-04-25 12:45:16 +00:00
Thomas Adam
3f54c9292f Merge branch 'obsd-master' 2014-04-24 12:59:00 +01:00
nicm
bec6c807cd There is no longer a need for a paste_stack struct or for global_buffers
to be global. Move to paste.c.
2014-04-24 09:14:43 +00:00
Thomas Adam
953c3ef47a Merge branch 'obsd-master'
Conflicts:
	Makefile
	tmux.1
	window.c
2014-04-23 11:26:11 +01:00
nicm
7ab2690be8 Differentiate between linked and unlinked window closes and renames,
like we already do for adds. From Andre Masella.
2014-04-23 10:14:29 +00:00
Nicholas Marriott
12e9c974fa Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-04-17 23:50:24 +01:00
Nicholas Marriott
024846b4d8 If pgrp fails in osdep_get_cwd, try sid. Fixes eg cat foo|less. From Balazs
Kezes.
2014-04-17 23:48:19 +01:00
nicm
64613b9d41 #nnT went away a while ago, remove a leftover from the manpage. 2014-04-17 15:48:02 +00:00
nicm
806520f025 Add some UTF-8 utility functions and use them to prevent the width limit
on formats from splitting UTF-8 characters improperly.
2014-04-17 15:37:55 +00:00
nicm
a5d4b7f3d9 Some more long lines. 2014-04-17 14:45:49 +00:00
Nicholas Marriott
248ad8bdb2 Next up is 2.0 not 1.10. 2014-04-17 15:26:26 +01:00
nicm
f194f103a2 Only scroll by one line at a time in choose mode, lists are generally
pretty small.
2014-04-17 14:13:59 +00:00
nicm
3e27be353d Set PATH explicitly, either from client or session
environment. Previously it came from the session environment. From J
Raynor.
2014-04-17 13:02:59 +00:00
nicm
c3b2e5eed3 Wrap some long lines. 2014-04-17 12:57:28 +00:00
nicm
ada75af199 Don't limit the DCS buffer to 256 bytes, expand it as needed. Requested
by Suraj Kurapati.
2014-04-17 12:43:38 +00:00
nicm
bce952777a Remove some unnecessary includes and fix a typo. 2014-04-17 11:38:35 +00:00
nicm
2e98c9057d Correct the dance to fix the active pane in join-pane by pulling the
(right) code from break-pane and window_remove_pane into a helper
function.
2014-04-17 09:13:13 +00:00
nicm
2740490e27 Remove the "info" message mechanism, this was only used for about five
mostly useless and annoying messages. Change those commands to silence
on success like all the others. Still accept the -q command line flag
and "quiet" server option for now.
2014-04-17 07:55:43 +00:00
nicm
877bdb46ed Extend the -q flag to set-option to suppress errors about unknown
options - this will allow options to be removed more easily.
2014-04-17 07:51:38 +00:00
nicm
ebc5cb447f Do not show the -fg, -bg and -attr options. If asked for one explicitly,
show the equivalent -style option instead.
2014-04-17 07:43:20 +00:00
nicm
992ef70fb6 Remove the monitor-content option and associated bits and bobs. It's
never worked very well. If there is a big demand for it to return, will
consider better ways to do it.
2014-04-17 07:36:45 +00:00
nicm
5acee1c04e Memory leak in error path and unnecessary assignment, from clang. 2014-04-16 23:05:38 +00:00
nicm
871b83cbab Remove a leftover prototype and fix some spacing. 2014-04-16 21:16:19 +00:00
nicm
14a96df9ee Remove the choose-list command to prepare for some later choose-* work. 2014-04-16 21:02:41 +00:00
nicm
e5d85c6c3c Because we pass the file descriptor from client to server, tmux can't
usefully work if stdin is /dev/tty. Complain about it more clearly.
2014-04-16 08:02:31 +00:00
Nicholas Marriott
4abc8f717a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-04-15 00:33:56 +01:00
Nicholas Marriott
8e1cef4040 +. 2014-04-15 00:31:45 +01:00
nicm
a47d2397df Don't leak socketpair file descriptors if fork fails. Spotted by Balazs
Kezes.
2014-04-14 22:27:30 +00:00
nicm
b8bda67f30 Don't blindly increase offsets by the return value of snprintf, if there
wasn't enough space this will go off the end. Instead clamp to the
available space. Fixes crash reported by Julien Rebetez.
2014-04-11 19:35:54 +00:00
nicm
73c5a487c1 save-buffer needs to use O_TRUNC. 2014-04-07 10:32:16 +00:00
Thomas Adam
57c514d2f8 Remove <vis.h>; not used on Linux. 2014-04-05 12:40:19 +01:00
Thomas Adam
0c99c7dbff Merge branch 'obsd-master'
Conflicts:
	Makefile
	tty-keys.c
2014-04-05 12:36:14 +01:00
nicm
acef311fe3 Work out mouse scroll wheel effect when the mouse is first detected and
store it in struct mouse_event, reduce the scroll size the 3 but allow
shift to reduce it to 1 and meta and ctrl to multiply by 3 if the
terminal supports them, also support wheel in choose mode. From Marcel
Partap.
2014-04-03 08:20:29 +00:00
nicm
8824dae6f7 A couple of trivial mouse-related style nits. 2014-04-03 08:15:17 +00:00
nicm
252a7373d6 Support UTF-8 with choose-buffer, from Kosuke ASAMI. Also make
buffer_sample bigger to let it trim at window right edge.
2014-04-02 18:12:18 +00:00
nicm
82f3e0e9e6 Use the same logic for bell with and without visual-bell, from Filip
Moc.
2014-04-02 17:14:24 +00:00
nicm
8880bdb67c Do not replace ## with # in status_replace1 because it'll be done later
by the format code.
2014-04-02 17:08:23 +00:00
Nicholas Marriott
806d5dcb17 Remove LocalWords. 2014-04-02 18:02:25 +01:00
nicm
b52b40b2bc pane_start_path has gone away. 2014-04-02 07:55:09 +00:00
deraadt
d9960b2d4d missed commit matching log.c 2014-04-01 05:50:30 +00:00
nicm
3c06bec03f Don't crash with a zero-length argument to setb, from J Raynor. 2014-03-31 21:43:55 +00:00
nicm
ee19d304ff In four byte UTF-8 sequences, only three bits of the first byte should
be used. Fix from Koga Osamu.
2014-03-31 21:43:35 +00:00
nicm
48478ea0a9 Remove log_debug2 as well and simplify log.c. 2014-03-31 21:42:45 +00:00
nicm
7bdb675469 GRID_DEBUG is no longer needed. 2014-03-31 21:42:27 +00:00
nicm
f155316be7 Remove unused log functions. 2014-03-31 21:42:05 +00:00
nicm
dca7d1c0fd Make message-limit a server option. 2014-03-31 21:41:35 +00:00
nicm
1704d4a6b7 Don't segfaut when the parent of the layout cell is NULL, from Thomas Adam. 2014-03-31 21:41:07 +00:00
nicm
46593e7aa2 Add names for mouse button bits rather than using magic numbers, from
Marcel Partap.
2014-03-31 21:40:21 +00:00
nicm
fcdae6925a Use hex constants rather than shifts for mouse events and flags, pointed
out by Marcel Partap.
2014-03-31 21:39:59 +00:00
nicm
0e4d1d8493 Add setb -a to append and a copy mode append command, from J Raynor with
minor changes.
2014-03-31 21:39:31 +00:00
nicm
b11de5adc7 Make session_attached a count and add session_many_attached flag. 2014-03-31 21:37:55 +00:00
nicm
9368914ee7 Add start-of-list, end-of-list, top-line and bottom-line in choice mode,
from madmaverick9 at roxxmail dot eu, similar diff a few days later from
Marcel Partap.
2014-03-31 21:36:43 +00:00
nicm
175f215187 Having three *clock* files is ridiculous, remove clock.c. 2014-03-31 21:34:08 +00:00
nicm
18cb135218 Don't write into buffer if no arguments, reported by Filipe Rosset. 2014-03-31 21:32:31 +00:00
nicm
04f469a324 Change secondary device attributes response to \033[>84;0;0c which is
unique for tmux.
2014-03-31 21:32:00 +00:00
Nicholas Marriott
26c42ad1e4 Don't crash with a zero-length argument to setb, from J Raynor. 2014-03-24 12:00:15 +00:00
Nicholas Marriott
77603c4f2d Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-03-08 16:28:56 +00:00
Nicholas Marriott
7019f77c05 In four byte UTF-8 sequences, only three bits of the first byte should be
used. Fix from Koga Osamu.
2014-03-08 16:27:45 +00:00
Nicholas Marriott
9880114aff Make -a append to top buffer if -b is not specified. 2014-03-08 08:53:48 +00:00
Nicholas Marriott
3625bcba24 Add osdep-cgywin.c as a copy of osdep-linux.c, from J Raynor. 2014-03-08 08:44:24 +00:00
Nicholas Marriott
b1a87b2ee4 Remove log_debug2 as well and simplify log.c. 2014-03-07 16:05:29 +00:00
Nicholas Marriott
c5a30513ed GRID_DEBUG is no longer needed. 2014-03-07 15:51:27 +00:00
Nicholas Marriott
ebe7bd7c8b Remove unused log functions. 2014-03-07 15:49:09 +00:00
Nicholas Marriott
683ca270d4 Make message-limit a server option. 2014-03-07 15:37:01 +00:00
Nicholas Marriott
78e783e786 Don't segfaut when the parent of the layout cell is NULL, from Thomas Adam. 2014-03-06 13:01:51 +00:00
Nicholas Marriott
cbd360b7dd Spaces to tabs. 2014-03-06 12:46:03 +00:00
Nicholas Marriott
23e944c91d Add names for mouse button bits rather than using magic numbers, from Marcel
Partap.
2014-03-06 12:00:30 +00:00
Nicholas Marriott
f15fcb6a1d Use hex constants rather than shifts for mouse events and flags, pointed out by
Marcel Partap.
2014-03-06 11:53:46 +00:00
Nicholas Marriott
8c0edcbfa3 Add setb -a to append and a copy mode append command, from J Raynor with minor
changes.
2014-03-06 11:50:07 +00:00
Nicholas Marriott
b7f6356053 Make session_attached a count and add session_many_attached flag. 2014-03-06 11:25:27 +00:00
Nicholas Marriott
b65c72c45c Restore SunOS fix, noticed by Greg Onufer. 2014-03-05 23:28:32 +00:00
Nicholas Marriott
19c534e325 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-03-05 23:27:04 +00:00
Thomas Adam
5f05c41126 www: Add link to CHANGES file for download tarball
Make the CHANGES file more prominent when choosing to download the released
version.
2014-03-03 21:59:22 +00:00
Nicholas Marriott
9134e4de1e Add start-of-list, end-of-list, top-line and bottom-line in choice mode, from
madmaverick9 at roxxmail dot eu, similar diff a few days earlier from Marcel
Partap.
2014-02-26 22:22:07 +00:00
Nicholas Marriott
582c2671dd Having three *clock* files is ridiculous, remove clock.c. 2014-02-26 21:59:33 +00:00
Nicholas Marriott
0bb9d51965 Don't write into buffer if no arguments, reported by Filipe Rosset. 2014-02-26 21:42:59 +00:00
Nicholas Marriott
6d9f936ff2 Change secondary device attributes response to \033[>84;0;0c which is unique
for tmux.
2014-02-26 21:42:14 +00:00
Nicholas Marriott
594348440e Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-02-26 13:49:41 +00:00
Nicholas Marriott
091cd0109f Add. 2014-02-26 13:48:25 +00:00
Thomas Adam
225164a9d6 Fix xterm-keys.vim syntax
Fix the typo in the xterm-keys.vim file, from Mark Oteiza.
2014-02-25 20:23:08 +00:00
Nicholas Marriott
f3152079e1 I prefer . here not :. 2014-02-24 23:11:25 +00:00
Nicholas Marriott
bf82f15bba Missing period. 2014-02-24 23:09:19 +00:00
Nicholas Marriott
4273c1b80e Use utempter to update utmp if it's around for configure, from madmaverick9 at
roxxmail dot eu.
2014-02-24 23:07:22 +00:00
Nicholas Marriott
488583dc8d Add to TODO. 2014-02-23 10:19:04 +00:00
nicm
f1828921df Change terminal-overrides to a server option (now that we have them), it
doesn't make much sense as a session option.
2014-02-23 00:53:06 +00:00
Thomas Adam
7eed5ad97b Go back to working on 1.10 2014-02-22 21:09:09 +00:00
Thomas Adam
80d9964a30 Update CHANGES and configure.ac for 1.9a release 2014-02-22 20:55:59 +00:00
Thomas Adam
150ef86800 Merge branch 'obsd-master' 2014-02-22 20:48:44 +00:00
nicm
315d45a0eb Fix crash due to uninitialized lastwp member of layout_cell, reported by
Balazs Kezes.
2014-02-22 18:01:10 +00:00
Nicholas Marriott
2a412fad04 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-02-22 17:36:17 +00:00
Nicholas Marriott
fe6f520054 FAQ about xterm-keys in emacs and vim, from Mark Oteiza. 2014-02-22 17:35:41 +00:00
nicm
c7f3599ebc Fix -fg/-bg/-style with 256 colour terminals. 2014-02-22 01:38:47 +00:00
Thomas Adam
b7589750a1 Correct Linux-specific manpage sections
Some of the man page locations on Linux differ to those on *BSD.  Noticed by
Christopher Meng.
2014-02-21 09:27:28 +00:00
Nicholas Marriott
c310212d28 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-02-21 08:03:42 +00:00
Nicholas Marriott
94d99d5462 Put each command on its own line and remove duplicates, from Daniel Hahler. 2014-02-21 08:02:48 +00:00
Thomas Adam
9120df33ef dist: Call clean target before any other action
In case 'make dist' is invoked from a dirty tree which hasn't had its object
files cleaned up, clean out the tree first before tarring up the files for a
release.
2014-02-20 23:20:17 +00:00
Thomas Adam
1ab0745f8e Working on 1.10 2014-02-20 21:44:33 +00:00
Thomas Adam
c5d2de7ec0 Update CHANGES and configure.ac for 1.9 release 2014-02-20 21:32:42 +00:00
Thomas Adam
ca1d78f523 Merge branch 'obsd-master' 2014-02-19 15:05:07 +00:00
nicm
6daf06b1ad Fix memory leaks with paste_replace, based on changes from J Raynor. 2014-02-17 23:07:03 +00:00
nicm
69b7c496ac Be consistent and allow only mouse down and mouse wheel for any pane
with mouse-select-pane rather than just in copy mode, reported by Balazs
Kezes.
2014-02-17 22:42:20 +00:00
nicm
1e981f4c6d Don't crash when given a invalid colour, reported by Felix Rosencrantz,
fix from Thomas Adam.
2014-02-17 18:12:47 +00:00
Nicholas Marriott
d325104d10 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-02-17 18:09:25 +00:00
Thomas Adam
b3de4a3dec Merge branch 'obsd-master'
Conflicts:
	tmux.1
	tmux.c
2014-02-16 23:02:07 +00:00
nicm
81db6bab91 Leftovers from removing 88 colour support, from Theo Buehler. 2014-02-16 12:45:17 +00:00
nicm
f2e54e1e2f If the terminfo entry has colors#256, assume that setaf and setab work
and use them for the 256 colour set. If the terminfo entry doesn't have
colors#256 and the user gives -2 to the client, use a \033[38;5;Xm
sequence as before. Should allow fbterm to work with it's weird setaf
and setab.
2014-02-14 14:37:08 +00:00
nicm
e9d32f901a Make status-interval of zero work as indented. 2014-02-14 14:00:18 +00:00
nicm
f835be4bb2 Style nit - no space between function name and bracket. 2014-02-14 13:59:01 +00:00
Nicholas Marriott
3aadc9d665 Missing *. 2014-02-14 13:56:39 +00:00
nicm
bfb700cf41 Do not need to call winlink_find_by_window, from Filip Moc. 2014-02-14 12:44:45 +00:00
nicm
d0accdba88 Check for NULL session and whatnot in status_replace, from Thomas Adam. 2014-02-14 12:37:54 +00:00
nicm
f58721a9e8 Make C-j the same as C-m, from Simon Nicolussi. 2014-02-14 12:35:58 +00:00
nicm
325396046a Avoid use of uninitialized variable, from Thomas Adam. 2014-02-12 20:26:13 +00:00
nicm
c52548f6fd The last fix to xterm keys meant that some keys such as \033OA were
being wrongly treated as partial matches. So both check xterm keys after
standard keys and only wildcard the minimum required ('1' to
'8'). Problems reported by Ralf Horstmann and Tim van der Molen.
2014-02-10 11:20:41 +00:00
Ben Boeckel
8edbbb9865 Sort and organize option names in tmux.vim
Also update with the latest options and remove the to-be-deprecated
{-attr,-bg,-fg} options.

Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
2014-02-05 19:14:12 +00:00
Ben Boeckel
73c125f248 Sort and organize commands in tmux.vim
Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
2014-02-05 19:13:11 +00:00
Thomas Adam
1721056f35 Remove references to 88colour support
Tmux doesn't directly support terminals with 88 colours directly anymore.
2014-02-05 10:51:25 +00:00
Thomas
6eef24c37a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2014-02-05 10:47:57 +00:00
jmc
973de5a704 fix some minor formatting glitches; 2014-02-02 08:48:48 +00:00
Nicholas Marriott
57332be8da Tidy up TODO list. 2014-02-01 00:47:04 +00:00
Thomas Adam
44737b06db Fixup BSD specific things from last merge
There's entries for header files we don't use, and the cvsimport doesn't
like removing files automatically, etc., and it won't have known to have
done this from autoconf's POV, so define that in the correct place, hence
the removal of the previously committed Makefile.
2014-01-31 21:47:54 +00:00
Thomas Adam
d50e47fc4a Merge branch 'obsd-master'
Conflicts:
	Makefile
	cmd-server-info.c
	cmd-start-server.c
2014-01-31 21:39:56 +00:00
nicm
9f02feb9d0 Break up and simplify screen_redraw_screen. 2014-01-31 14:19:24 +00:00
nicm
72d1be5ddd Fix partial matches with xterm-keys on, from m0viefreak dot cm at
googlemail dot com.
2014-01-31 11:20:28 +00:00
nicm
1935eb5c1e Add \033[18t window operations from J Raynor. 2014-01-31 11:17:20 +00:00
nicm
62e0ed5d7e Fix missing argument, stupid last minute changes... 2014-01-28 23:11:44 +00:00
nicm
945339b443 Allow replacing each of the many sets of separate foo-{fg,bg,attr}
options with a single foo-style option. For example:

    set -g status-fg yellow
    set -g status-bg red
    set -g status-attr blink

Becomes:

    set -g status-style fg=yellow,bg=red,blink

The -a flag to set can be used to add to rather than replace a style. So:

    set -g status-bg red

Becomes:

    set -ag status-style bg=red

Currently this is fully backwards compatible (all *-{fg,bg,attr} options
remain) but the plan is to deprecate them over time.

From Tiago Cunha.
2014-01-28 23:07:09 +00:00
nicm
c930fd5ff6 Remember the last active pane in the top-bottom or left-right cell so
that it can be restored when moving back to that cell with selectp
-L/-R/etc. From Suraj N Kurapati.
2014-01-28 22:19:17 +00:00
nicm
dda70d4ef1 Merge start-server into kill-server. 2014-01-27 23:57:35 +00:00
nicm
7d3d996383 Support paste key in copy mode input (for search etc). Also clamp length
to screen width.
2014-01-22 22:32:15 +00:00
nicm
d23561f381 Merge server-info into show-messages and remove some not useful output. 2014-01-22 14:43:42 +00:00
Nicholas Marriott
cbf9224c5f Add AC_PROG_MKDIR_P. 2014-01-22 14:03:16 +00:00
Nicholas Marriott
c965870585 + to TODO. 2014-01-22 14:02:32 +00:00
nicm
9ee93b3ea3 Do not permit periods in session names (colons are already banned). From
J Raynor.
2014-01-22 14:00:08 +00:00
nicm
df680d7257 Only exit copy mode at the bottom if no selection in progress, from
Benoit Pierre.
2014-01-22 13:57:49 +00:00
Thomas
d02c4bda3a Merge branch 'obsd-master' 2014-01-20 10:48:12 +00:00
nicm
938768ed3d Do not attempt to read .tmux.conf if we can't figure out a home
directory, from Tiago Cunha.
2014-01-15 11:46:28 +00:00
nicm
3368b602a8 Couple of fixes from cppcheck via Tiago Cunha. 2014-01-15 11:44:18 +00:00
nicm
b185449d07 Fix a memory/fd leak reported by Tiago Cunha. 2014-01-09 21:20:45 +00:00
nicm
c2cac69a22 Similar to attach-session, make switch-client -t accept a window and
pane. From Johannes Jakobsson.
2014-01-09 14:28:14 +00:00
nicm
1a0d3cd5d3 Allow attach-session -t to accept a window and pane to select them on
attach. Based on a diff from J Raynor.
2014-01-09 14:20:55 +00:00
nicm
adc1f21eae Three small changes from Tiago Cunha:
- Check for truncation when copying path.
- Don't need to use a temporary buffer in screen_set_title.
- Include strerror in output when connecting to server fails.
2014-01-09 14:05:55 +00:00
nicm
994cb872cf Style and comment fixes from Tiago Cunha. 2014-01-09 13:58:06 +00:00
nicm
66829ee12e Simplify args_set, from Tiago Cunha. 2014-01-09 13:51:57 +00:00
nicm
1751da76d5 Remove unnecessary calls to va_start/va_end, from Tiago Cunha. 2014-01-09 13:46:12 +00:00
Nicholas Marriott
ba014c1a60 NetBSD broke strnvis when they added it, check for that. 2014-01-06 15:16:57 +00:00
Nicholas Marriott
886c282679 Use 0 if O_DIRECTORY is missing, reported by Dagobert Michelsen. 2014-01-06 15:12:05 +00:00
Nicholas Marriott
ccf39fcdc1 +. 2013-12-09 23:27:42 +00:00
Nicholas Marriott
ee65bde130 Note libevent version. 2013-12-09 22:53:17 +00:00
Nicholas Marriott
b091790622 +. 2013-11-30 17:56:49 +00:00
Nicholas Marriott
a352570e9f +. 2013-11-30 17:18:25 +00:00
nicm
d459314517 Add comments to ACS table matching terminfo(5). 2013-11-24 19:38:32 +00:00
nicm
1286c56188 Replace ## by # in format. 2013-11-24 11:29:09 +00:00
nicm
40982a01fb With -k, kill window after using it to work out -c path. Reported by
jmacristovao at gmail dot com.
2013-11-23 09:18:29 +00:00
nicm
7aeb4473ad Handle empty current directory more gracefully. 2013-11-22 20:58:36 +00:00
deraadt
72a4602b88 missing unsigned char casts areound tolower()
ok nicm
2013-11-20 17:01:23 +00:00
okan
30275bc610 Include unistd.h as it is the standard location for getopt().
OK millert@
2013-11-17 20:19:36 +00:00
Thomas Adam
3e498cdb49 Merge branch 'obsd-master' 2013-11-14 07:51:26 +00:00
benno
7624800ddc from nicm: : handle msgbuf_write() returning EAGAIN 2013-11-13 20:43:36 +00:00
nicm
f0ed61f53c Support case insensitive searching in the same manner as emacs - all
lowercase means case insensitive, any uppercase means case
sensitive. From J Raynor.
2013-11-09 00:48:57 +00:00
nicm
a6cd84869e Correctly redraw the top two lines in copy mode when they are selected -
the selection was being updated before the redraw so the markings were
lost. Based on a fix from J Raynor.
2013-11-08 12:39:20 +00:00
nicm
7fa55b0419 Key to swap to other end of selection (bound to o with vi keys), from J
Raynor.
2013-10-23 11:31:03 +00:00
nicm
bf35441608 Do not run any command line command from the client which starts the
server until after the configuration file completes. This prevents it
racing against run-shell or if-shell in .tmux.conf that run in the
background.
2013-10-20 17:28:43 +00:00
nicm
f52eac6225 Don't turn on modifyOtherKeys by default, it is annoying if tmux is
killed and it's left on and we can't turn it on and off like we do for
attributes. It's not hard to enable in .Xresources or .Xdefaults anyway.
2013-10-20 09:37:50 +00:00
Thomas Adam
2c08a3a559 Merge branch 'obsd-master' 2013-10-15 08:06:56 +01:00
nicm
2eb6d6e31b Fix detach -a by skipping clients where the session is NULL. 2013-10-15 00:15:11 +00:00
Thomas Adam
334c28afe7 Fix previous
cwd is a char*, not a u_int.
2013-10-11 19:41:43 +01:00
Thomas Adam
5944230c50 Fix up missing cwd definition
This went walkies during the merge.
2013-10-11 19:38:40 +01:00
Nicholas Marriott
8bcdd8fc21 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code
Conflicts:
	cmd-split-window.c
	cmd-unbind-key.c
	format.c
	osdep-openbsd.c
2013-10-11 16:52:39 +01:00
Thomas
d518067be6 Forward-declarations for osdep-linux 2013-10-11 14:55:57 +01:00
Thomas
f703a30dfe Fixup osdep-* specific code
get_proc_name() is osdep_get_name() outside of OpenBSD.
2013-10-11 14:39:22 +01:00
Nicholas Marriott
1a0951959f Add destroy entry to TODO. 2013-10-11 14:36:28 +01:00
Nicholas Marriott
b347a994fd + to TODO. 2013-10-11 14:36:28 +01:00
Nicholas Marriott
6126fa0995 + to TODO. 2013-10-11 14:36:28 +01:00
Nicholas Marriott
85df418728 ++ to TODO. 2013-10-11 14:36:28 +01:00
Nicholas Marriott
558e5639d0 Remove from TODO. 2013-10-11 14:36:28 +01:00
Nicholas Marriott
d8d746b4b8 Set EVENT_NOEPOLL on Linux again. 2013-10-11 14:36:28 +01:00
Nicholas Marriott
570028e9c0 Add entry about smaller clients based on text from Thomas Adam. 2013-10-11 14:36:28 +01:00
Thomas Adam
7c3e7d6535 Add subdir-objects to shut automake up
automake 1.14 onwards has started emitting lots of warnings about this
option:

automake: warning: possible forward-incompatibility.
automake: At least a source file is in a subdirectory, but the
'subdir-objects'
automake: automake option hasn't been enabled.  For now, the corresponding
output
automake: object file(s) will be placed in the top-level directory.
However,
automake: this behaviour will change in future Automake versions: they will
automake: unconditionally cause object files to be placed in the same
subdirectory
automake: of the corresponding sources.
automake: You are advised to start using 'subdir-objects' option throughout
your
automake: project, to avoid future incompatibilities.

So enable this in AM_INIT_AUTOMAKE.

This doesn't seem to break older automake versions.
2013-10-11 14:36:28 +01:00
Thomas Adam
5b065e93b3 Check setupterm() in libtinfo also
Some ncurses packages have build time configuration options to separate its
different parts into separate libraries.  Some Linux distributions in
particular separate out the terminfo routines in to libtinfo.

This change teaches configure that setupterm() can also be found there.
2013-10-11 14:36:28 +01:00
Thomas Adam
d3f37566e2 Ignore .dirstamp files
GNU automake 1.14+ uses these files for subdir-option detection.  We don't
want to accidentally commit these.  They're not useful to us.
2013-10-11 14:36:28 +01:00
Nicholas Marriott
b8b31ad53e Add openat() to compat. 2013-10-11 14:36:28 +01:00
Thomas
7f479ffdce Merge branch 'obsd-master' into mtemp 2013-10-11 14:33:29 +01:00
nicm
4901d9ddc8 Don't leak file descriptors in the rare MSG_VERSION case. From Chris
Johnsen.
2013-10-11 08:07:12 +00:00
nicm
ffba21a60c Remove stray return, from Chris Johnsen. 2013-10-11 08:06:03 +00:00
nicm
98b81e9834 And get it right this time... don't leak if it is an empty string either. 2013-10-11 08:03:43 +00:00
nicm
17ec688ced Bracket in the wrong place in description of c0-change-trigger. 2013-10-10 23:31:28 +00:00
nicm
0b77d17b35 Fix leak in format_get_command. 2013-10-10 23:31:03 +00:00
nicm
d0566a474a Remove the KERN_PROC_CWD the proc_current_path format (which is the only
thing that uses it now).
2013-10-10 12:39:24 +00:00
nicm
99e3cbc526 Use format_get_command() and some spacing tweaks. 2013-10-10 12:35:30 +00:00
nicm
b85de1ddb3 Pass -1 for cwd now not NULL. 2013-10-10 12:29:53 +00:00
nicm
c1ccefc62d We accidentally haven't been using $TMUX to work out the session for a
while and in fact it is less useful that using the client ttyname. So
don't bother and don't pass it from the client. If we need it in future
it is in c->environ.
2013-10-10 12:29:35 +00:00
nicm
6ac7abe8f0 Remove now unused cmd_get_default_path. 2013-10-10 12:28:56 +00:00
nicm
909e1c1a86 Don't boke when figuring out working directory from configuration file. 2013-10-10 12:28:38 +00:00
nicm
7936ce3874 Show session name in detached message. Requested by somebody a few
months ago who didn't bother testing it. But it works for me anyway.
2013-10-10 12:28:08 +00:00
nicm
b8b85fbb0c Don't look at string[length - 1] if length == 0. 2013-10-10 12:27:38 +00:00
nicm
282c5f9644 Alter how tmux handles the working directory to internally use file
descriptors rather than strings.

- Each session still has a current working directory.

- New sessions still get their working directory from the client that
  created them or its attached session if any.

- New windows are created by default in the session working directory.

- The -c flag to new, neww, splitw allows the working directory to be
  overridden.

- The -c flag to attach let's the session working directory be changed.

- The default-path option has been removed.

To get the equivalent to default-path '.', do:

        bind c neww -c $PWD

To get the equivalent of default-path '~', do:

        bind c neww -c ~

This also changes the client identify protocol to be a set of messages rather
than one as well as some other changes that should make it easier to make
backwards-compatible protocol changes in future.
2013-10-10 12:26:34 +00:00
nicm
165aa59760 Make tilde expansion in command strings work even if it isn't terminated by /. 2013-10-10 12:14:09 +00:00
nicm
10c38436aa Similarly for MSG_COMMAND - allow full imsg limit not arbitrary 2048. 2013-10-10 12:13:56 +00:00
nicm
a0404b6902 retcode -> retval for exit message. 2013-10-10 12:12:54 +00:00
nicm
eb26dbd072 Merge IDENTIFY_* flags with CLIENT_* flags. 2013-10-10 12:12:08 +00:00
nicm
6c093010e0 Remove CMD_SENDENVIRON. 2013-10-10 12:09:34 +00:00
nicm
d2160e3f83 mouse-resize-pane: Only resize on border select
The current behaviour of mouse-resize-pane is such that if the mouse
button is held down and a selection takes place within a pane, that if
the mouse pointer then hits a border edge, that pane-resize would
initiate.

This seems counter-intuitive; instead, check for a resize condition if
the border of a pane is selected, and in the case of mouse selection
within a pane, no longer resize the pane if edge of the border is hit.

By Thomas Adam.
2013-10-10 12:08:14 +00:00
nicm
b822d24b15 Support -c for new-session, based on code from J Raynor. 2013-10-10 12:07:36 +00:00
nicm
fc54bfe6b0 Make cmdq->client_exit a tristate (-1 means "not set") so that if
explicitly set it can be copied from child to parent cmdq by if-shell
and source-file. This fixes using attach or new. From Chris Johnsen.
2013-10-10 12:04:38 +00:00
nicm
1a49ebaa9f First period not last for host_short, from Michael Scholz. 2013-10-10 12:04:01 +00:00
nicm
e4dc1568ce Don't treat TMUX_TMPDIR as a potential file
The point of setting TMUX_TMPDIR is to then make any labels from -L go
to that directory.  In the case of makesocketpath() with no TMUX_TMPDIR
set, would set both the path and the default socket to a file.  The
checking of the permissions on the file worked fine in that case, but
when TMUX_TMPDIR is set, won't work on a directory.

This fixes the problem by ensuring the check on the permissions is
performed on directories only.

By Thomas Adam.
2013-10-10 12:03:22 +00:00
nicm
1bd0851ee8 Mark flags as optional and mutually exclusive. From Tiago Cunha. 2013-10-10 12:02:55 +00:00
nicm
1b7c2dd056 Trivial style and spacing nits. 2013-10-10 12:01:14 +00:00
nicm
d45c12b6c9 Remove the barely-used and unnecessary command check() function. 2013-10-10 12:00:18 +00:00
nicm
90ae7682ed Clear window->flags when clearing winlinks
When clearing WINLINK_ALERTFLAGS for all sessions, we must also, for
that window, clear the window->flags as well, otherwise sessions may
well still see flags for winlinks long since cleared.

This therefore introduces WINDOW_ALERTFLAGS to help with this.
2013-10-10 11:59:23 +00:00
nicm
e6af0ad23e choose-tree: Reset top when toggling items
When choose-tree is told to expand/collapse items (especially when first
rendering collapsed to just show sessions), ensure that in addition to
setting the selected item, that the item itself appears on the bottom of
the screen, rather than off screen.

This was causing rendering glitches when a very small tmux window tried
to render a list of items in choose-tree much larger than itself, and
the selected item appeared off screen, and didn't show the selection
until the selection had wrapped around to the top of the screen.
2013-10-10 11:58:52 +00:00
nicm
34674bb180 Renumber windows: Lookup lastw via window not index
When calling 'movew -r' on a session to reorder the winlinks, ensure
when adding back in the information for the lastw stack that we look up
the winlink based on the window and not its index.

Using the index doesn't make sense here because when comparing it to the
old set, it will never match since the winlink has been renumbered.

Bug reported by Ben Boeckel. Patch by Thomas Adam.
2013-10-10 11:58:24 +00:00
nicm
784b711393 Assign mouse x/y coords before checking them. When receiving mouse
inputs, we should set the x/y coordinates earlier than we currently do,
so that we aren't off-by-one in the case when the statusbar is at the
top of the screen. By Thomas Adam.
2013-10-10 11:57:52 +00:00
nicm
81a548bcc4 Accept multiple parameters to SM/RM/DECSET/DECRST, based on a diff from
Hayaki Saito.
2013-10-10 11:57:14 +00:00
nicm
fd1750af49 Add automatic-rename-format option allowing automatic rename to use
something other than pane_current_command.
2013-10-10 11:56:50 +00:00
nicm
2bf2f5d58e Allow nested format expansion. 2013-10-10 11:50:36 +00:00
nicm
40811eb8d4 Add length limit operator for formats. 2013-10-10 11:50:20 +00:00
nicm
2756d12750 Handle input mouse positions <33 (we already can generate them). 2013-10-10 11:49:42 +00:00
nicm
7839993fe7 Only include actual trailing spaces not unused cells with capturep -J,
from George Nachman.
2013-10-10 11:49:29 +00:00
nicm
47a4a9992c Allow the file descriptor received from the client to be -1. 2013-10-10 11:49:07 +00:00
nicm
d75dd2ab1c Add formats for window flags. 2013-10-10 11:47:52 +00:00
nicm
6e665708fc Missing space in refresh-client synopsis. 2013-10-10 11:46:47 +00:00
nicm
d3830e622f Grouped sessions were being leaked on destroy, correctly free them. 2013-10-10 11:46:28 +00:00
nicm
0538676aa3 Make recalculate_sizes() handle an empty window with no active
pane. This can happen when a window is in two sessions - it isn't
destroyed immediately when the pane goes away but is left until the last
session is destroyed. Fixes problems with grouped sessions reported by
Daniel Ralston.
2013-10-10 11:46:00 +00:00
nicm
4c9f41f1ad Pass flags into cmdq_guard as an argument since sometimes cmdq->cmd can
be NULL. Avoids crash when a command in a command client can't be
parsed.
2013-10-10 11:45:28 +00:00
Nicholas Marriott
e588ddb5d6 Add openat() to compat. 2013-10-10 10:27:23 +01:00
Nicholas Marriott
f3ec8693e3 Pass -1 for cwd now not NULL. 2013-10-06 22:44:24 +01:00
Nicholas Marriott
e9b09faab2 We accidentally haven't been using $TMUX to work out the session for a while
and in fact it is less useful that using the client ttyname. So don't bother
and don't pass it from the client. If we need it in future it is in c->environ.
2013-10-06 22:38:33 +01:00
Nicholas Marriott
5ea6148362 Remove now unused cmd_get_default_path. 2013-10-06 21:35:44 +01:00
Nicholas Marriott
9e0d7bddc0 Don't boke when figuring out working directory from configuration file. 2013-10-06 21:31:55 +01:00
Nicholas Marriott
aa0a57fd56 Show session name in detached message. Requested by somebody a few months ago
who didn't bother testing it. But it works for me anyway.
2013-10-06 21:21:52 +01:00
Nicholas Marriott
d86c70af96 Don't look at string[length - 1] if length == 0. 2013-10-06 21:20:11 +01:00
Nicholas Marriott
4538c269d0 Alter how tmux handles the working directory to internally use file descriptors
rather than strings.

- Each session still has a current working directory.

- New sessions still get their working directory from the client that created
  them or its attached session if any.

- New windows are created by default in the session working directory.

- The -c flag to new, neww, splitw allows the working directory to be
  overridden.

- The -c flag to attach let's the session working directory be changed.

- The default-path option has been removed.

To get the equivalent to default-path '.', do:

        bind c neww -c $PWD

To get the equivalent of default-path '', do:

        bind c neww -c '#{pane_current_path}'

The equivalent of default-path '~' is left as an exercise for the reader.

This also changes the client identify protocol to be a set of messages rather
than one as well as some other changes that should make it easier to make
backwards-compatible protocol changes in future.
2013-10-06 21:02:23 +01:00
Nicholas Marriott
446eb11cde Make tilde expansion in command strings work even if it isn't terminated by /. 2013-10-06 09:06:07 +01:00
Nicholas Marriott
fa1375c09f Similarly for MSG_COMMAND - allow full imsg limit not arbitrary 2048. 2013-10-06 00:48:24 +01:00
Nicholas Marriott
f141e9b37a Instead of fixed size buffers for some messages, send only the string length. 2013-10-06 00:28:35 +01:00
Nicholas Marriott
3fba377ddd retcode -> retval for exit message. 2013-10-06 00:18:00 +01:00
Nicholas Marriott
01a4752503 Merge IDENTIFY_* flags with CLIENT_* flags. 2013-10-06 00:10:40 +01:00
Nicholas Marriott
d66cbf20f7 Bump protocol version and add new message types. 2013-10-06 00:06:01 +01:00
Nicholas Marriott
7e4314eccb Remove CMD_SENDENVIRON. 2013-10-06 00:02:52 +01:00
nicm
7c71c3e27d Change the default for the default-path option to ~. This is a quick
change to turn off the KERN_PROC_CWD code which is unpredictable. Later
it will go away and there may be other changes to how this works.
2013-10-05 13:56:48 +00:00
Thomas Adam
5eeee39cc1 Ignore .dirstamp files
GNU automake 1.14+ uses these files for subdir-option detection.  We don't
want to accidentally commit these.  They're not useful to us.
2013-10-05 12:45:24 +01:00
Thomas Adam
796974ddf6 Check setupterm() in libtinfo also
Some ncurses packages have build time configuration options to separate its
different parts into separate libraries.  Some Linux distributions in
particular separate out the terminfo routines in to libtinfo.

This change teaches configure that setupterm() can also be found there.
2013-10-05 12:44:29 +01:00
Thomas Adam
75f5b3dab6 Add subdir-objects to shut automake up
automake 1.14 onwards has started emitting lots of warnings about this
option:

automake: warning: possible forward-incompatibility.
automake: At least a source file is in a subdirectory, but the
'subdir-objects'
automake: automake option hasn't been enabled.  For now, the corresponding
output
automake: object file(s) will be placed in the top-level directory.
However,
automake: this behaviour will change in future Automake versions: they will
automake: unconditionally cause object files to be placed in the same
subdirectory
automake: of the corresponding sources.
automake: You are advised to start using 'subdir-objects' option throughout
your
automake: project, to avoid future incompatibilities.

So enable this in AM_INIT_AUTOMAKE.

This doesn't seem to break older automake versions.
2013-10-05 12:44:09 +01:00
nicm
9f330897a8 Fix previous not to leak fd on failure, whoops. 2013-10-05 10:40:49 +00:00
Nicholas Marriott
710eeb2a33 Fix previous not to lead fd on failure. 2013-10-05 11:40:47 +01:00
Nicholas Marriott
3493b7dac7 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-10-05 09:14:35 +01:00
Nicholas Marriott
d51b4f92d7 Use open(".")/fchdir() to save and restore current directory rather than
getcwd()/chdir().
2013-10-05 09:14:11 +01:00
nicm
3d8a8ea0c6 Use open(".")/fchdir() to save and restore current directory rather than
getcwd()/chdir().
2013-10-05 08:12:39 +00:00
Thomas Adam
2057812c8f mouse-resize-pane: Only resize on border select
The current behaviour of mouse-resize-pane is such that if the mouse button
is held down and a selection takes place within a pane, that if the mouse
pointer then hits a border edge, that pane-resize would initiate.

This seems counter-intuitive; instead, check for a resize condition if the
border of a pane is selected, and in the case of mouse selection within a
pane, no longer resize the pane if edge of the border is hit.
2013-10-02 06:53:47 +01:00
Nicholas Marriott
13360ad541 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-10-01 23:50:24 +01:00
Nicholas Marriott
9389cfbec9 Support -c for new-session, based on code from J Raynor. 2013-10-01 23:48:03 +01:00
Nicholas Marriott
7be152412e Make cmdq->client_exit a tristate (-1 means "not set") so that if explicitly
set it can be copied from child to parent cmdq by if-shell and
source-file. This fixes using attach or new. From Chris Johnsen.
2013-10-01 23:31:09 +01:00
Nicholas Marriott
d0fa48db1e Restore missing key binding for %, from Chris Johnsen. 2013-10-01 23:27:36 +01:00
Nicholas Marriott
884a21d0f5 First period not last for host_short, from Michael Scholz. 2013-10-01 23:24:39 +01:00
Thomas
21bca549d3 layout-resize-pane-mouse: Consider visible panes only
When a pane is maximized, and text is selected, we end up checking if a pane
switch is needed.  This therefore means we might end up selecting panes
which aren't visible.
2013-09-30 15:26:43 +01:00
Thomas
bda970b3b1 Don't treat TMUX_TMPDIR as a potential file
The point of setting TMUX_TMPDIR is to then make any labels from -L go to
that directory.  In the case of makesocketpath() with no TMUX_TMPDIR set,
would set both the path and the default socket to a file.  The checking of
the permissions on the file worked fine in that case, but when TMUX_TMPDIR
is set, won't work on a directory.

This fixes the problem by ensuring the check on the permissions is performed
on directories only.
2013-09-30 15:26:32 +01:00
Tiago Cunha
75ec17f0b5 Mark flags as optional and mutually exclusive. 2013-08-31 11:16:47 +01:00
Nicholas Marriott
d62121e7bb Add entry about smaller clients based on text from Thomas Adam. 2013-08-31 10:42:09 +01:00
Nicholas Marriott
06d101657f No space in lsw -a targets. 2013-08-28 12:59:13 +01:00
Nicholas Marriott
2f7ffab0e8 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-08-23 15:58:46 +01:00
Nicholas Marriott
3ed5e56a39 Set EVENT_NOEPOLL on Linux again. 2013-08-23 15:25:05 +01:00
Nicholas Marriott
a0802dd486 A couple of manpage fixes from Tiago Cunha. 2013-08-22 00:32:55 +01:00
Nicholas Marriott
f2675cdf04 Trivial style and spacing nits. 2013-08-21 18:35:01 +01:00
Nicholas Marriott
e3864c383f Remove from TODO. 2013-08-21 18:33:34 +01:00
Nicholas Marriott
25c0dc5e6e ++ to TODO. 2013-08-21 18:30:27 +01:00
Nicholas Marriott
8954d01f96 + to TODO. 2013-08-21 18:28:31 +01:00
Nicholas Marriott
b2fe9bff3f Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-08-21 18:03:07 +01:00
Nicholas Marriott
a36da3a878 Remove the barely-used and unnecessary command check() function. 2013-08-21 18:01:40 +01:00
Thomas
c103f2fbcb Clear window->flags when clearing winlinks
When clearing WINLINK_ALERTFLAGS for all sessions, we must also, for that
window, clear the window->flags as well, otherwise sessions may well still
see flags for winlinks long since cleared.

This therfore introduces WINDOW_ALERTFLAGS to help with this.
2013-08-20 13:03:53 +01:00
Thomas
aa4920fea3 choose-tree: Reset top when toggling items
When choose-tree is told to expand/collapse items (especially when first
rendering collapsed to just show sessions), ensure that in addition to
setting the selected item, that the item itself appears on the bottom of the
screen, rather than off screen.

This was causing rendering glitches when a very small tmux window tried to
render a list of items in choose-tree much larger than itself, and the
selected item appeared off screen, and didn't show the selection until the
selection had wrapped around to the top of the screen.
2013-08-20 00:05:28 +01:00
Thomas Adam
5532766b19 Renumber windows: Lookup lastw via window not index
When calling 'movew -r' on a session to reorder the winlinks, ensure when
adding back in the information for the lastw stack that we look up the
winlink based on the window and not its index.

Using the index doesn't make sense here because when comparing it to the old
set, it will never match since the winlink has been renumbered.

Bug reported by Ben Boeckel.
2013-08-20 00:04:07 +01:00
Thomas
5dbf3cb036 Assign mouse x/y coords before checking them
When receiving mouse inputs, we should set the x/y coordinates earlier than
we currently do, so that we aren't off-by-one in the case when the statusbar
is at the top of the screen.
2013-08-20 00:02:38 +01:00
Nicholas Marriott
ddf929390e Accept multiple parameters to SM/RM/DECSET/DECRST, based on a diff from Hayaki
Saito.
2013-08-19 22:31:38 +01:00
Nicholas Marriott
23519fc0b4 Add automatic-rename-format option allowing automatic rename to use something
other than pane_current_command.
2013-08-19 22:16:11 +01:00
Nicholas Marriott
04288fcd4c Allow nested format expansion. 2013-08-19 22:14:55 +01:00
Nicholas Marriott
84c22d053b Add length limit operator for formats. 2013-08-03 21:06:38 +01:00
Nicholas Marriott
7581762c8e + to TODO. 2013-08-02 13:53:17 +01:00
Nicholas Marriott
7673732c0f Handle input mouse positions <33 (we already can generate them). 2013-08-02 08:51:57 +01:00
Nicholas Marriott
2dfd3fbd71 Only include actual trailing spaces not unused cells with capturep -J, from
George Nachman.
2013-08-01 23:47:45 +01:00
Nicholas Marriott
3a13e066ba Allow the file descriptor received from the client to be -1 - it can be on
Cygwin when stdin is not a terminal. Reported by A Young, SF bug 52.
2013-08-01 23:42:39 +01:00
Nicholas Marriott
bcd9bcae2a Add formats for window flags. 2013-08-01 23:41:39 +01:00
Nicholas Marriott
939f796f08 Don't leak formats if they are added multiple times. 2013-08-01 23:40:44 +01:00
Nicholas Marriott
27364345bf Don't add client formats when they are NULL. 2013-08-01 23:39:09 +01:00
Nicholas Marriott
35c19ffc28 Missing space in refresh-client synopsis. 2013-08-01 23:38:53 +01:00
Nicholas Marriott
b0b5cad496 Grouped sessions were being leaked on destroy, correctly free them. 2013-08-01 23:38:35 +01:00
Nicholas Marriott
965edf8a5c Make recalculate_sizes() handle an empty window with no active pane. This can
happen when a window is in two sessions - it isn't destroyed immediately when
the pane goes away but is left until the last session is destroyed. Fixes
problems with grouped sessions reported by Daniel Ralston.
2013-08-01 23:37:45 +01:00
Nicholas Marriott
1c271852fc Pass flags into cmdq_guard as an argument since sometimes cmdq->cmd can be
NULL. Avoids crash when a command in a command client can't be parsed.
2013-08-01 23:35:03 +01:00
Nicholas Marriott
7ea560261c Add destroy entry to TODO. 2013-07-27 19:57:21 +01:00
schwarze
304ea079d2 use .Mt for email addresses; from Jan Stary <hans at stare dot cz>; ok jmc@ 2013-07-16 00:07:52 +00:00
Thomas Adam
c190c73240 Merge branch 'obsd-master' 2013-07-13 16:57:51 +01:00
Nicholas Marriott
e8567098a4 Add support for Cgywin, apparently it is enough just to open the tty again in
the server and fd passing is not necessary. Needs some ifdefs unfortunately but
no way around that and some of them can go next time we're willing to do a
protocol bump. Patch from J Raynor jxraynor at gmail dot com.
2013-07-12 22:21:42 +01:00
Nicholas Marriott
a9ebb62d54 Make next-word-end work properly with vi(1) keys, reported by patrick
keshishian.
2013-07-12 09:52:36 +00:00
Thomas Adam
bdea2f9eda Merge branch 'obsd-master' 2013-07-06 11:18:49 +01:00
Nicholas Marriott
f5b041e394 Add pane_synchronized format, from Romain Francoise. 2013-07-05 15:27:14 +00:00
Nicholas Marriott
e496a548d7 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-07-05 16:24:13 +01:00
Nicholas Marriott
3d39b18e31 Section on clipboard, from Thomas Adam. 2013-07-05 16:23:33 +01:00
Nicholas Marriott
a96a8a1aab Clarify error messages when setting options, from Thomas Adam. 2013-07-05 15:10:38 +00:00
Nicholas Marriott
064124cc5f When the session option renumber-window is used, ensure we iterate over
all sessions in that group when the winlinks are reordered, otherwise
the winlink lists are out of sync with one another. From Thomas Adam.
2013-07-05 14:52:33 +00:00
Nicholas Marriott
7af5fec038 Whitespace nits, from Ben Boeckel. 2013-07-05 14:44:06 +00:00
Nicholas Marriott
f884fff869 Implement s, S, C mode switch commands in vi(1) mode, from Ben Boeckel. 2013-07-05 14:38:23 +00:00
Nicholas Marriott
c7a121cfc0 Focus events can cause trouble if left on and they can't be turned off
during idle periods (like the other states are) because we'd miss
events. So add a server option to control them. Defaults to off.
2013-06-28 20:55:16 +01:00
Nicholas Marriott
777be296ee Always push a focus event when the application turns it on, prompted by
discussion with Hayaki Saito a while ago.
2013-06-28 20:55:16 +01:00
Nicholas Marriott
a0172a6ae5 Mark control commands specially so the client can identify them, based
on a diff from George Nachman a while back.
2013-06-28 20:55:16 +01:00
Nicholas Marriott
1099442c0a +strings.h in compat/. 2013-06-25 09:57:49 +01:00
Nicholas Marriott
18989cd430 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-06-25 09:49:14 +01:00
Nicholas Marriott
828145456c Don't set TMUX_CONF in tmux.h. 2013-06-25 09:48:09 +01:00
Nicholas Marriott
097a046e4a Use _XPG6 on Solaris with GCC because the headers are insane and don't like GCC
with -std=gnu99 and _XPG4_2. We should not really be using _XPG* at all but
there doesn't seem to be a magic define that says "give me the latest
standard", and things are further confused by the CMSG_DATA check in
configure.ac which sets _XOPEN_SOURCE _XOPEN_SOURCE_EXTENDED.

While here add COPYING to EXTRA_DIST.
2013-06-25 09:35:42 +01:00
Nicholas Marriott
3977dba761 Focus events can cause trouble if left on and they can't be turned off
during idle periods (like the other states are) because we'd miss
events. So add a server option to control them. Defaults to off.
2013-06-23 13:10:46 +00:00
Nicholas Marriott
a41cd8d75b Always push a focus event when the application turns it on, prompted by
discussion with Hayaki Saito a while ago.
2013-06-23 12:51:28 +00:00
Nicholas Marriott
662d471215 Mark control commands specially so the client can identify them, based
on a diff from George Nachman a while back.
2013-06-23 12:41:54 +00:00
Thomas Adam
06b5805479 Merge branch 'obsd-master' 2013-06-13 18:12:49 +01:00
Stuart Henderson
d6debc21c7 revert r1.156 "Add support for focus notifications when tmux pane changes"
beck@ found annoying beeps if a machine was shutdown while tmux is running
and you then focus in/out of an xterm; kettenis tracked it down to 1.156.
2013-06-11 19:18:02 +00:00
Jason McIntyre
ddb52a2b15 escape "Ss", becuase groff thinks it has found a macro; 2013-06-02 14:40:17 +00:00
Nicholas Marriott
13441e8cb8 The actual terminfo entries we ended up with for cursor changes are Cs,
Ce, Ss and Se (not Cc, Ce, Cs, Csr). So use and document these instead
of the ones we were using earlier.
2013-06-02 07:52:15 +00:00
Thomas Adam
a97d5b8e60 Amend tmux.1 handling in .gitignore
Now that tmux.1 is used as the canonical source for man page documentation,
ensure that we ignore tmux.1.{mdoc,man} instead.
2013-06-01 10:58:39 +01:00
Thomas Adam
399d7380a5 Merge branch 'obsd-master' 2013-05-31 21:44:42 +01:00
Nicholas Marriott
c231381aa3 Demote the old single-character replacement variables (#S and friends)
to aliases of formats. From Tiago Cunha.
2013-05-31 19:56:05 +00:00
Nicholas Marriott
c30d60f7ae Add host_short format, from Tiago Cunha. 2013-05-31 19:46:42 +00:00
Nicholas Marriott
9fb9f78e43 Use u_char for the send-keys string to avoid mangling top-bit-set
characters when they are promoted to int and passed to
window_pane_key. Reported by Jacob Bang.
2013-05-31 12:50:05 +00:00
Nicholas Marriott
a0cf65db77 Instead of eating 1024 bytes or so for the arguments of each command,
save memory by using an RB tree. From Tiago Cunha.
2013-05-31 12:19:34 +00:00
Nicholas Marriott
2ee9c4df12 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-05-31 13:00:11 +01:00
Nicholas Marriott
e6c77e7afb Add a COPYING file, suggested by Dagobert Michelsen. 2013-05-31 12:59:17 +01:00
Thomas Adam
76cb088d16 Merge branch 'obsd-master'
Conflicts:
	tmux.h
2013-05-25 11:48:12 +01:00
Nicholas Marriott
907ad00300 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code
Conflicts:
	Makefile.am
2013-05-15 16:50:15 +01:00
Nicholas Marriott
88a4da9747 Don't let cursor position overflow when reflowing, from Christopher
Collins.
2013-05-15 15:39:51 +00:00
Nicholas Marriott
25c430b1cd Reserve space for \0 in cmd_print, from George Nachman. 2013-05-15 15:34:09 +00:00
Nicholas Marriott
772d61f3ed RIS should reset focus reporting, from Hayaki Saito. 2013-05-15 15:32:14 +00:00
Nicholas Marriott
5b1cf02f2e Rename tmux.1.in back to tmux.1 and generate tmux.1.{mdoc,man} instead. 2013-05-15 16:27:30 +01:00
Nicholas Marriott
66f4c60a84 Don't limit width and height to 222 in standard mouse mode. 2013-05-07 11:00:16 +00:00
Nicholas Marriott
fce095665c Use $(srcdir) for generating tmux.1, reported by fasta_ on IRC. 2013-04-28 15:37:02 +01:00
Nicholas Marriott
2555ac58cc .Op Fl b not .Fl b for run-shell synopsis, from Ben Boeckel. 2013-04-24 10:15:47 +00:00
Nicholas Marriott
e323101ede Rename global configuration define. 2013-04-24 10:01:32 +00:00
Nicholas Marriott
ce52e45d44 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-04-24 11:00:32 +01:00
Nicholas Marriott
4f3c31a6b6 Use sysconfdir for the location of global tmux.conf (but default it to /etc),
based on changes from Dagobert Michelsen.
2013-04-24 10:57:03 +01:00
Thomas Adam
70bc8ef845 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-04-23 08:26:51 +01:00
Thomas Adam
cd60e57b6a Merge branch 'obsd-master'
Sync from OpenBSD.
2013-04-23 08:26:04 +01:00
Nicholas Marriott
3d2b7d5bce When using choose-tree -u, start with the current window
highlighted. From Thomas Adam.
2013-04-22 22:17:29 +00:00
Nicholas Marriott
04f54ab38f Get session of -t window rather than client's window. 2013-04-22 16:34:53 +00:00
Nicholas Marriott
46c7dbef0f Call recalculate_sizes() after killing window in case it is in a grouped
session, from Daniel Ralston.
2013-04-22 13:35:18 +00:00
Nicholas Marriott
11b90bc959 Pass tmux.1.in to awk on stdin rather than as an argument. 2013-04-22 14:04:40 +01:00
Nicholas Marriott
792e2856c9 Add compat for cfmakeraw, from Dagobert Michelsen. 2013-04-22 09:44:15 +01:00
Nicholas Marriott
d89b35e682 Use lockf which is more portable than flock, from Dagobert Michelsen. 2013-04-22 08:42:19 +00:00
Nicholas Marriott
a46ccbd883 -paths.h. Fixes Solaris, from Dagobert Michelsen. 2013-04-22 09:39:21 +01:00
Nicholas Marriott
5dda1abc32 Don't let server_client_check_focus use a dead bufferevent, from Romain
Francoise.
2013-04-21 21:32:00 +00:00
Theo Deraadt
55640a31b3 (long long) and %lld for time_t output
ok nicm
2013-04-17 14:52:31 +00:00
Nicholas Marriott
88428cff3a %zu format for size_t. 2013-04-17 08:41:41 +00:00
Nicholas Marriott
c24b58e2ee Generate tmux.1 using mdoc2man.awk on Solaris, issue brought up and changes
tested by Dagobert Michelsen.
2013-04-16 11:33:53 +01:00
Nicholas Marriott
9e537c808b Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-04-16 10:39:48 +01:00
Thomas Adam
2c4543b9e9 Add back missing -V flag
This went walkies from a previous git commit.
2013-04-14 18:07:08 +01:00
Thomas Adam
b58bca9a72 Merge branch 'obsd-master'
Conflicts:
	tmux.c
2013-04-13 17:05:49 +01:00
Nicholas Marriott
27dcf470dc Remove some Korean characters from the zero-width list that apparently
shouldn't be there, from Jeong Mok Cho.
2013-04-12 12:50:36 +00:00
Nicholas Marriott
caa8290510 Copy the client into the new cmdq in source-file so commands that work
on it (such as new-session) can work. Fixes issue reported by oss-adv at
users dot sf dot net.
2013-04-12 12:44:31 +00:00
Nicholas Marriott
7f9b225cc2 Call setlocale(LC_TIME) at startup. 2013-04-11 21:52:18 +00:00
Nicholas Marriott
4ccb2e2c21 TODO tweaks. 2013-04-11 22:45:05 +01:00
Nicholas Marriott
cbee283c26 Send an SGR0 after turning on modifyOtherKeys to fix Terminal.app which
treats \033[>4;1m and \033[4;1m (bold+underline). Reported & tested by
otto@.
2013-04-11 07:27:27 +00:00
Nicholas Marriott
9fcda95a6f Set EV_WRITE for jobs or run/if-shell jobs can hang. From Chris Johnsen. 2013-04-10 12:20:35 +00:00
Nicholas Marriott
7ada64d5f8 Fix bug where end guard in control mode was not printed after session
destroyed, from George Nachman.
2013-04-10 12:15:36 +00:00
Nicholas Marriott
20f0d917be Missed -o from set-window-option, from Ben Boeckel. 2013-04-10 12:07:18 +00:00
Nicholas Marriott
e312db1408 Add wait-for to tmux.vim from Ben Boeckel. 2013-04-10 13:04:19 +01:00
Nicholas Marriott
743bd1275f Need errno.h, reported by Swaroop M S. 2013-04-10 12:52:40 +01:00
Nicholas Marriott
69c86379e3 Remove some code not needed on OpenBSD. 2013-04-10 11:51:16 +00:00
Nicholas Marriott
46b3c1a025 Use proc_bsdinfo which works on older OS X versions, from OZAKI Kiichi. 2013-04-10 12:46:29 +01:00
Nicholas Marriott
3ea893464f TODO changes. 2013-04-10 12:43:08 +01:00
Nicholas Marriott
738e789dbd If -s to swap-pane is not given, use the current pane. 2013-03-28 15:08:12 +00:00
Nicholas Marriott
66afcf5be0 Make copy-mode -u still scroll up if already in copy mode, handy for
people who bind it with -n.
2013-03-28 15:07:42 +00:00
Nicholas Marriott
4b0ed56e32 Tidy up and trim down TODO file. 2013-03-28 12:42:00 +00:00
Nicholas Marriott
dc2af8347b New code doesn't build on old versions of OS X so only support 10.7 and
later. Reported by Jared Scheel and tested by Chris Johnsen.
2013-03-28 08:36:34 +00:00
Nicholas Marriott
64ea8829af Add define for timersub to compat.h. 2013-03-28 00:00:13 +00:00
Nicholas Marriott
629cfec8a3 Trivial typo fixes in changes. 2013-03-27 23:37:05 +00:00
Nicholas Marriott
7f63658709 Add TMUX_TMPDIR variable to put the socket directory outside
TMPDIR. From Ben Boeckel.
2013-03-27 11:24:18 +00:00
Nicholas Marriott
5e4d9a3197 Move the cursor back into the last column on CUU/CUD to match xterm
behaviour. From George Nachman.
2013-03-27 11:19:19 +00:00
Nicholas Marriott
982354765b Remove tmux's (already minimal) 88 colour support. Such terminals are
few and unnecessary.
2013-03-27 11:17:12 +00:00
Thomas Adam
5fe0576dcb Working on 1.9 2013-03-26 20:33:10 +00:00
Thomas Adam
1b083aa0fd Update CHANGES and configure.ac for 1.8 release. 2013-03-26 20:19:04 +00:00
Thomas
399a15b9fc Merge branch 'obsd-master' 2013-03-26 16:59:37 +00:00
Nicholas Marriott
dfac36b6c3 Only accept partial keys if the timer has not expired, fixes infinite
loop when Escape is pressed the wrong number of times.
2013-03-26 14:14:08 +00:00
Nicholas Marriott
771d7db3a6 Fix compiler warnings, missing #include. From Thomas Adam. 2013-03-26 10:54:48 +00:00
Thomas
00af2df102 Merge branch 'obsd-master' 2013-03-25 16:30:37 +00:00
Nicholas Marriott
be390c1991 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-25 16:13:22 +00:00
Nicholas Marriott
2fd0cb7600 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code
Conflicts:
	TODO
	cmd-queue.c
	cmd-server-info.c
	cmd-wait-for.c
	tmux.1
2013-03-25 16:11:22 +00:00
Thomas Adam
5f5d413408 Remove compat/vis.h from cmd-save-buffer.
The include for compat.h in tmux.h takes care of this.

BUG-ID:  N/A
2013-03-25 16:09:34 +00:00
Nicholas Marriott
972da2d498 Try to establish client for run-shell and if-shell if no -t. 2013-03-25 16:04:07 +00:00
Nicholas Marriott
e44bd9f750 Revert the command-prefix change which breaks sequences of commands. 2013-03-25 15:59:57 +00:00
Nicholas Marriott
777edd0269 Add to TODO. 2013-03-25 15:47:16 +00:00
Nicholas Marriott
855d6fe1fe Add to TODO. 2013-03-25 15:47:10 +00:00
Nicholas Marriott
b625ad6d8b Use -std=gnu99 not c99 with GCC. 2013-03-25 15:33:23 +00:00
Thomas Adam
97b5df35b1 Portability fix-ups
* Ammend the Makefile to include newer commands.
* "compat/vis.h" versus <vis.h>
* Removal of cmd-send-prefix.c and cmd-show-buffer.c
* osdep-* for processes.

BUG-ID:  N/A
2013-03-25 15:32:02 +00:00
Thomas Adam
7a87c7eff6 Fixup Makefile 2013-03-25 15:00:56 +00:00
Thomas Adam
f90eb43fcb Merge branch 'obsd-master' 2013-03-25 14:59:29 +00:00
Nicholas Marriott
a09d8e88fc Use -std=gnu99 not c99 with GCC. 2013-03-25 12:16:03 +00:00
Nicholas Marriott
b5fda7ad2a Spacing, warning nits. 2013-03-25 12:00:30 +00:00
Nicholas Marriott
58bb6f8c56 Set pane resize flag when needed. 2013-03-25 11:55:01 +00:00
Nicholas Marriott
673eb160d4 Sort includes and fix spaces. 2013-03-25 11:53:54 +00:00
Nicholas Marriott
e97e0d7e54 Man page fixes. 2013-03-25 11:49:54 +00:00
Nicholas Marriott
4119c476aa b comes before t. 2013-03-25 11:46:28 +00:00
Nicholas Marriott
e2295014d9 Process ^[ as meta when a partial key is found. 2013-03-25 11:44:16 +00:00
Nicholas Marriott
43fb9835fa Add -P and -F to new-session. 2013-03-25 11:44:00 +00:00
Nicholas Marriott
599dd2a560 Create a new context when copying instead of using the input
context. The input context may not exist yet. Fixes crash when copying
from config file errors.
2013-03-25 11:43:33 +00:00
Nicholas Marriott
d28a39d01d Extend jobs to support writing and use that for copy-pipe instead of
popen, from Chris Johnsen.
2013-03-25 11:43:01 +00:00
Nicholas Marriott
270d90ce1e Handle empty pending output (not a failure) and add \n. From George
Nachman.
2013-03-25 11:42:19 +00:00
Nicholas Marriott
0c969a7dfd Handle no client better in display-message. 2013-03-25 11:42:01 +00:00
Nicholas Marriott
111d993e75 When only two panes in a window, only draw half the separating line as
active.
2013-03-25 11:41:49 +00:00
Nicholas Marriott
0ef24f9912 Only send end guard if begin was sent, from George Nachman. 2013-03-25 11:41:16 +00:00
Nicholas Marriott
87fe1c0b0e Include prefix on ids, from George Nachman. 2013-03-25 11:40:54 +00:00
Nicholas Marriott
114d822d27 Don't zoom windows with one pane, from Romain Francoise. 2013-03-25 11:39:11 +00:00
Nicholas Marriott
88b92df849 We ignore SIGWINCH until ready, so send a MSG_RESIZE immediately when
becoming ready.
2013-03-25 11:38:57 +00:00
Nicholas Marriott
e4c0730bf1 Use single stdout and stderr for control clients. 2013-03-25 11:36:59 +00:00
Nicholas Marriott
8a40e10d55 Add time and a command count to control mode guards, based on code from
George Nachman.
2013-03-25 11:35:55 +00:00
Nicholas Marriott
e0961dfdf4 Fix handling of short (< 4 character) checksums and a bug with parsing
old-style custom layouts. Based on fix from Chris Johnsen.
2013-03-25 11:35:30 +00:00
Nicholas Marriott
446fb0cb9c Do not redraw panes if invisible. 2013-03-25 10:12:01 +00:00
Nicholas Marriott
6fee3e9e4b Rename session idx to session id throughout and add $ prefix to targets
to use it, extended from a diff from George Nachman.
2013-03-25 10:11:45 +00:00
Nicholas Marriott
748acdc77c Add wait-for -L and -U for lock and unlock, from Thiago Padilha. 2013-03-25 10:09:35 +00:00
Nicholas Marriott
410a3abbef Add a wait-for command which blocks a client on a named channel until it
is woken up again (with wait-for -S). From Thiago Padilha.
2013-03-25 10:09:05 +00:00
Nicholas Marriott
304336a591 Allow lastgc to be NULL in grid_string_cells so find-window doesn't
crash, problem reported by eugene everson.
2013-03-25 10:07:40 +00:00
Nicholas Marriott
35452b3e55 Do not leak command in formats, from Romain Francoise. 2013-03-25 10:07:21 +00:00
Nicholas Marriott
ebd9c615c8 Add some additional debug logging. 2013-03-25 10:06:13 +00:00
Nicholas Marriott
e9cef8bf30 Continue the parent cmdq after sourcing a file. 2013-03-25 10:05:58 +00:00
Nicholas Marriott
e85f764f23 Preserve trailing spaces with capture-pane -J, from George Nachman. 2013-03-25 10:05:35 +00:00
Nicholas Marriott
e2e85650ac tty.path can be NULL, don't dereference it. From George Nachman. 2013-03-25 10:04:44 +00:00
Nicholas Marriott
2c14a771a8 Remove some unused/unnecessary control notifications, from George Nachman. 2013-03-25 10:04:23 +00:00
Nicholas Marriott
d39b1a87a5 Add -q flags to shut up errors to capture-pane and show-options, from
George Nachman.
2013-03-25 10:04:04 +00:00
Nicholas Marriott
62db3c8efe Send DSC 1000p at the beginning of a -CC client's lifetime and ST and
the end, from George Nachman.
2013-03-25 10:03:24 +00:00
Nicholas Marriott
efa06643b0 Remove previous. 2013-03-25 10:03:00 +00:00
Nicholas Marriott
14fad6a5cc Add -A flag to new-session to make it behave like attach-session if the
session exists. If -A is used, -D behaves like -d to attach-session.
2013-03-24 09:58:40 +00:00
Nicholas Marriott
c71844de63 Add resize-pane -Z to temporary zoom the active pane to occupy the full
window or unzoom (restored to the normal layout) if it already zoomed,
bound to C-b z by default. The pane is unzoomed on pretty much any
excuse whatsoever.

We considered making this a new layout but the requirements are quite
different from layouts so decided it is better as a special case. Each
current layout cell is saved, a temporary one-cell layout generated and
all except the active pane set to NULL.

Prompted by suggestions and scripts from several. Thanks to Aaron Jensen
and Thiago Padilha for testing an earlier version.
2013-03-24 09:57:59 +00:00
Nicholas Marriott
a05b8c4143 Add a -o option to set-option to prevent setting an option already set,
from Thiago Padilha.
2013-03-24 09:55:02 +00:00
Nicholas Marriott
20636d956d Add a command queue to standardize and simplify commands that call other
commands and allow a command to block execution of subsequent
commands. This allows run-shell and if-shell to be synchronous which has
been much requested.

Each client has a default command queue and commands are consumed one at
a time from it. A command may suspend execution from the queue by
returning CMD_RETURN_WAIT and then resume it by calling cmd_continue() -
for example run-shell does this from the callback that is fired after
the job is freed.

When the command queue becomes empty, command clients are automatically
exited (unless attaching). A callback is also fired - this is used for
nested commands in, for example, if-shell which can block execution of
the client's cmdq until a new cmdq becomes empty.

Also merge all the old error/info/print functions together and lose the
old curclient/cmdclient distinction - a cmdq is bound to one client (or
none if in the configuration file), this is a command client if
c->session is NULL otherwise an attached client.
2013-03-24 09:54:10 +00:00
Nicholas Marriott
66edb3392b Expand format variables in the run-shell and if-shell shell commands,
from Thiago Padilha.
2013-03-24 09:33:35 +00:00
Nicholas Marriott
86adcd4b26 Add pane_tabs format to format_window_pane based on code from George
Nachman.
2013-03-24 09:29:40 +00:00
Nicholas Marriott
a60687f9ba Handle focus events from the terminal, from Aaron Jensen. 2013-03-24 09:28:59 +00:00
Nicholas Marriott
bb8457b166 Fix error reporting for client commands by adding a flag to
cmd_find_client to tell it whether or not to show errors, sometimes it's
needed and sometimes not.
2013-03-24 09:27:19 +00:00
Nicholas Marriott
3eae71b5b2 Do pane resize ioctls once at the end of the server loop rather than
immediately.
2013-03-24 09:25:04 +00:00
Nicholas Marriott
8094e82287 Add option command-prefix which is automatically prepended to any
command (apart from a naked default-shell). The default is "exec ".
2013-03-24 09:21:27 +00:00
Nicholas Marriott
1ec4354998 Add support for focus notifications when tmux pane changes, based on
work by Aaron Jensen.
2013-03-24 09:18:16 +00:00
Nicholas Marriott
ac1fe83596 Couple of fixes pointed out by jmc. 2013-03-22 18:45:36 +00:00
Nicholas Marriott
c7d1849e1c Process ^[ as meta when a partial key is found. 2013-03-22 17:02:12 +00:00
Nicholas Marriott
7f191c7951 Add -P and -F to new-session. 2013-03-22 17:01:15 +00:00
Nicholas Marriott
702ab8bab0 Add a load of miscellaneous pane formats, from George Nachman. 2013-03-22 16:03:35 +00:00
Nicholas Marriott
eaaeb28cda Add session_set_current helper function, extracted from a diff from
Aaron Jensen.
2013-03-22 16:00:26 +00:00
Nicholas Marriott
295d86911e Add -C and -J to capture pane to escape control sequences and to join
wrapped line, based on a diff from George Nachman.
2013-03-22 15:56:11 +00:00
Nicholas Marriott
c519f9a84c evbuffer_readline returns allocated storage, don't leak it. 2013-03-22 15:55:22 +00:00
Nicholas Marriott
2243cfbe75 Need to set clients in context before changing their reference count. 2013-03-22 15:54:29 +00:00
Nicholas Marriott
d644e5143f Fix so capture-pane/save-buffer can work in control clients, from George
Nachman.
2013-03-22 15:53:24 +00:00
Nicholas Marriott
58932295fc Add copy-pipe mode command to copy selection and also pipe to a command. 2013-03-22 15:52:40 +00:00
Nicholas Marriott
8478895eeb Add -e flag to capture-pane to include embedded ANSI SGR escape
sequences, from George Nachman.
2013-03-22 15:51:54 +00:00
Nicholas Marriott
8a6fbfa148 Don't use a target-client for stdout, just always cmdclient. 2013-03-22 15:51:15 +00:00
Nicholas Marriott
a1722d5c2e Remove unnecessary initializers of cmd_ctx. 2013-03-22 15:50:42 +00:00
Nicholas Marriott
0ff9275ad7 load_cfg can actually use the same context now they are reference counted. 2013-03-22 15:50:13 +00:00
Nicholas Marriott
d1e6ce2672 Add functions to allocate and free command contexts rather than doing it
all on the stack.
2013-03-22 15:49:55 +00:00
Nicholas Marriott
0ccd84d2ef Instead of skipping del_curterm on FreeBSD < 7, skip it on ncurses < 5.7. It
looks like 5.6 on Linux has the problem too. Reported by Myles Dear.
2013-03-22 15:36:45 +00:00
Nicholas Marriott
29613f2f31 Prevent lock on control clients, not on others. 2013-03-22 10:42:55 +00:00
Nicholas Marriott
8c545bbfa8 Don't try to print unterminated strings when loading configuration file. 2013-03-22 10:41:57 +00:00
Nicholas Marriott
f19836550b Unbreak line wrapping. 2013-03-22 10:41:01 +00:00
Nicholas Marriott
79f5fe6f5b Use tty_raw on stop, not tty_puts. 2013-03-22 10:40:22 +00:00
Nicholas Marriott
2f5fa4ee9d Don't hang when clearing line in choose mode now that the cursor stays
at the end with wrap.
2013-03-22 10:38:33 +00:00
Nicholas Marriott
db66d85176 Fix double space in sessions template. 2013-03-22 10:38:13 +00:00
Nicholas Marriott
f0efa576e0 Add resize-pane -x and -y for absolute pane size (much requested). 2013-03-22 10:37:39 +00:00
Nicholas Marriott
ad5df9bc2f Implement DECAWM (SM/RM 7) using existing MODE_WRAP flag. 2013-03-22 10:36:53 +00:00
Nicholas Marriott
22a2949bd2 Correctly handle UTF8 mouse option being toggled, from Egmont Koblinger. 2013-03-22 10:34:46 +00:00
Nicholas Marriott
67b4d5b609 Support the latest theory for mouse input, this is enabled/disabled with
SM/RM 1006 and is similar in style to SGR input: \033[<b;x;yM or
\033[b;x;ym. From Egmont Koblinger.
2013-03-22 10:33:50 +00:00
Nicholas Marriott
ad760b3bf7 Add client_session and client_last_session formats. 2013-03-22 10:32:36 +00:00
Nicholas Marriott
8d59b189cc No more lint means no more ARGSUSED. 2013-03-22 10:31:22 +00:00
Nicholas Marriott
306a3b8d80 In terminals with XT, turn on modifyOtherKeys=1 with the escape sequence
and handle the most common set. Pass them through if xterm-keys is on.
2013-03-22 10:30:04 +00:00
Nicholas Marriott
041a911c43 Create a new context when copying instead of using the input context. The input
context may not exist yet.
2013-03-21 23:57:21 +00:00
Nicholas Marriott
10682b9e7e Instead of loads of little screen_write_*_on and off functions which
just change mode flags, just have screen_write_mode_set and
screen_write_mode_clear.
2013-03-21 18:47:56 +00:00
Nicholas Marriott
c5504af4a6 Add various checks to turn off bits that can't work in control mode
(such as lock).
2013-03-21 18:47:01 +00:00
Nicholas Marriott
49ac5b5fe0 Do not include status line in size calculations in control mode. 2013-03-21 18:46:12 +00:00
Nicholas Marriott
d4785fe798 Don't set key KEYC_NONE on xterm_keys_find match()
When calling xterm_keys_find(); if we get a complete match, don't set
the key to unknown before calling the action to complete the binding;
otherwise non-prefixed bindings will not work.

From Thomas Adam
2013-03-21 18:45:38 +00:00
Nicholas Marriott
3d24c75d0f Include the \033 in the key tree and adjust key matching for this change. 2013-03-21 18:44:47 +00:00
Nicholas Marriott
78543cce30 Support capture-pane -p to send to stdout. 2013-03-21 18:43:34 +00:00
Jason McIntyre
55bf2ecc68 tweak previous; ok nicm 2013-03-21 17:42:36 +00:00
Nicholas Marriott
51ac2a3202 Fix a couple of memory leaks, from Romain Francoise. 2013-03-21 16:54:37 +00:00
Nicholas Marriott
48291f0eeb Make choose-tree actually work again. 2013-03-21 16:53:12 +00:00
Nicholas Marriott
d5139d1401 Fix a comment for new key table names. 2013-03-21 16:52:02 +00:00
Nicholas Marriott
3665be7c44 Tidy by splitting default key tables into two. 2013-03-21 16:50:22 +00:00
Nicholas Marriott
801d64a16e Add -c to refresh-client to set client size in control mode, based on
code from George Nachman.
2013-03-21 16:49:37 +00:00
Nicholas Marriott
dd46c95e23 Aargh. Spaces -> tabs. 2013-03-21 16:25:08 +00:00
Nicholas Marriott
4920306486 Clarify choose-tree entry in man page. 2013-03-21 16:23:46 +00:00
Nicholas Marriott
66414029a1 Run session command before window in choose-tree. 2013-03-21 16:23:07 +00:00
Nicholas Marriott
51d989f5df Do not crash when calling choose-tree with a command that changes the mode. 2013-03-21 16:22:48 +00:00
Nicholas Marriott
c982279950 Fix constness of cmd_template_replace, window_choose_add_item and
window_choose_add_window.
2013-03-21 16:19:25 +00:00
Nicholas Marriott
0c0953f3bd Add user options, prefixed with @. May be set to any arbitrary string. 2013-03-21 16:17:01 +00:00
Nicholas Marriott
69fe5ca567 Add -v to set and setw to show only option value. 2013-03-21 16:15:52 +00:00
Nicholas Marriott
63b4fd5cac Add a format client_prefix which is 1 if prefix key has been
pressed, used for example #{?client_prefix,X,Y}. Also a few extra
server_client_status needed.
2013-03-21 16:14:09 +00:00
Nicholas Marriott
dd76497ab0 Show alias in lscm output. 2013-03-21 16:12:50 +00:00
Nicholas Marriott
9b7e18f166 Rework reflow code so it does not do so much allocation which should be
faster with large histories.
2013-03-21 16:12:10 +00:00
Nicholas Marriott
180faf73af Allow choose commands to be used outside tmux, so long as at least one
client is attached.
2013-03-21 16:09:59 +00:00
Nicholas Marriott
6ddb06d372 Extend jobs to support writing and use that for copy-pipe instead of popen,
from Chris Johnsen.
2013-03-21 14:24:33 +00:00
Nicholas Marriott
69d97f6d4b Handle empty pending output (not a failure) and add \n. From George Nachman. 2013-03-19 09:34:00 +00:00
Nicholas Marriott
f5de847a0c Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-17 23:45:19 +00:00
Nicholas Marriott
6bdc947f6b Handle no client better in display-message. 2013-03-14 16:02:33 +00:00
Nicholas Marriott
919bde7cb1 When only two panes in a window, only draw half the separating line as active. 2013-03-14 12:08:26 +00:00
Nicholas Marriott
3d974b7267 Don't let display-message crash if no client, from George Nachman. 2013-03-14 07:31:20 +00:00
Nicholas Marriott
c5ad47ee7c Only send end guard if begin was sent, from George Nachman. 2013-03-13 07:31:36 +00:00
Nicholas Marriott
4d38b6d1fa Include prefix on ids, from George Nachman. 2013-03-13 07:28:12 +00:00
Nicholas Marriott
9e879b4aab Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-12 22:49:56 +00:00
Nicholas Marriott
99934bf998 Write escaped output in control mode rather than hex, from George Nachman. 2013-03-12 22:48:58 +00:00
Nicholas Marriott
8840f2d629 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-12 14:59:27 +00:00
Nicholas Marriott
d32a546d6e Clarify zoom/unzoom, from Romain Francoise. 2013-03-12 14:58:48 +00:00
Nicholas Marriott
8aa40ec1c7 Don't zoom windows with one pane, from Romain Francoise. 2013-03-12 12:18:52 +00:00
Nicholas Marriott
543420ccd2 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-11 21:31:46 +00:00
Nicholas Marriott
064022548b We ignore SIGWINCH until ready, so send a MSG_RESIZE immediately when becoming
ready.
2013-03-11 21:30:48 +00:00
Nicholas Marriott
7c00950967 Don't add prefix to %output pane id. 2013-03-11 15:28:34 +00:00
Nicholas Marriott
b5516771d3 Clean up capture-pane and add -P option to dump pending output, based on code
from George Nachman.
2013-03-11 13:47:29 +00:00
Nicholas Marriott
7b4084a15a Document control mode in the manpage, from George Nachman. 2013-03-11 13:06:30 +00:00
Nicholas Marriott
412ac6bc3a Use single stdout and stderr for control clients. 2013-03-11 09:46:18 +00:00
Nicholas Marriott
a6ad44f111 Fix if-shell and run-shell if there are no sessions. Batted around through
several people, finished off by Chris Johnsen.
2013-03-11 09:43:56 +00:00
Nicholas Marriott
97620bb5be Add a home and end as modified by xterm in keypad mode, from Chris Johnsen. 2013-03-11 09:37:52 +00:00
Nicholas Marriott
49ed75d883 Fix a warning. 2013-03-11 09:37:16 +00:00
Nicholas Marriott
c41d92d27a Add time and a command count to control mode guards, based on code from George
Nachman.
2013-03-11 09:35:44 +00:00
Nicholas Marriott
a060aa2bf0 Fix handling of short (< 4 character) checksums and a bug with parsing
old-style custom layouts. Based on fix from Chris Johnsen.
2013-03-10 23:41:59 +00:00
Nicholas Marriott
2ac6501698 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-09 21:33:28 +00:00
Nicholas Marriott
06ac399ce6 Zoom script is no longer needed. 2013-03-09 21:32:47 +00:00
Nicholas Marriott
dde5d49a5e Do not redraw panes if invisible. 2013-03-09 17:29:22 +00:00
Nicholas Marriott
89d3f13945 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-07 10:09:13 +00:00
Nicholas Marriott
f47a063841 Rename session idx to session id throughout and add $ prefix to targets to use
it, extended from a diff from George Nachman.
2013-03-07 10:07:22 +00:00
Nicholas Marriott
e964ff70e6 Fix --disable-static, reported by Shea Levy. 2013-03-06 14:58:48 +00:00
Nicholas Marriott
bc3580fa06 Add wait-for -L and -U for lock and unlock, from Thiago Padilha. 2013-03-06 11:00:55 +00:00
Nicholas Marriott
7fd4d49d56 Add a wait-for command which blocks a client on a named channel until it is
wokrn up again (with wait-for -S). From Thiago Padilha.
2013-03-06 09:57:26 +00:00
Nicholas Marriott
ec75f9d1a3 Allow lastgc to be NULL in grid_string_cells so find-window doesn't crash,
problem reported by eugene everson.
2013-03-06 09:56:31 +00:00
Nicholas Marriott
6405fceee2 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-03-05 20:02:47 +00:00
Nicholas Marriott
f9e46a373f Do not leak command in formats, from Romain Francoise. 2013-03-05 20:01:16 +00:00
Nicholas Marriott
d05debbe19 Unzoom on last-pane and fix a typo, from Romain Francoise. 2013-03-05 18:00:14 +00:00
Nicholas Marriott
f8c86a9515 Add some additional debug logging. 2013-03-05 17:17:59 +00:00
Nicholas Marriott
2c9cddd876 Continue the parent cmdq after sourcing a file. 2013-03-05 17:14:19 +00:00
Nicholas Marriott
aaeee34c32 Preserve trailing spaces with capture-pane -J, from George Nachman. 2013-03-04 11:03:03 +00:00
Nicholas Marriott
70397e4a95 Print %%error not %%end guard on error, from George Nachman. 2013-03-04 09:09:07 +00:00
Nicholas Marriott
43d904dbf3 tty.path can be NULL, don't dereference it. From George Nachman. 2013-03-04 09:02:32 +00:00
Nicholas Marriott
1da64bf786 Remove some unused/unnecessary control notifications, from George Nachman. 2013-03-04 09:01:30 +00:00
Nicholas Marriott
1cb1fb5bd4 Add -q flags to shut up errors to capture-pane and show-options, from George
Nachman.
2013-03-04 09:00:24 +00:00
Nicholas Marriott
208881a735 Send DSC 1000p at the beginning of a -CC client's lifetime and ST and the end,
from George Nachman..
2013-03-04 08:52:41 +00:00
Thomas Adam
a2f52d4224 Remove previous 2013-02-25 18:25:37 +00:00
Thomas Adam
2ccb67cae4 Plug small memory leak in run-shell
Don't potentially leak the command to run were it to fail.
2013-02-25 07:33:21 +00:00
Nicholas Marriott
b2a61348dd Add -a to capture-pane to capture alternate screen, from George Nachman. 2013-02-24 07:52:03 +00:00
Nicholas Marriott
234f6d27c1 Use \\ not \ for escaping \. 2013-02-24 07:49:54 +00:00
Nicholas Marriott
f339cfd315 Add -A flag to new-session to make it behave like attach-session if the session
exists. If -A is used, -D behaves like -d to attach-session.
2013-02-24 00:43:28 +00:00
Nicholas Marriott
c5239c5984 Add resize-pane -Z to temporary zoom the active pane to occupy the full window
or unzoom (restored to the normal layout) if it already zoomed, bound to C-b z
by default. The pane is unzoomed on pretty much any excuse whatsoever.

We considered making this a new layout but the requirements are quite different
from layouts so decided it is better as a special case. Each current layout
cell is saved, a temporary one-cell layout generated and all except the active
pane set to NULL.

Prompted by suggestions and scripts from several. Thanks to Aaron Jensen and
Thiago Padilha for testing an earlier version.
2013-02-24 00:25:03 +00:00
Nicholas Marriott
be13479f09 Add a -o option to set-option to prevent setting an option already set, from
Thiago Padilha.
2013-02-23 23:22:03 +00:00
Nicholas Marriott
69a8d64716 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code
Conflicts:
	cmd-if-shell.c
	cmd-run-shell.c
	tmux.1
2013-02-23 22:42:49 +00:00
Nicholas Marriott
3964309c67 Add a command queue to standardize and simplify commands that call other
commands and allow a command to block execution of subsequent commands. This
allows run-shell and if-shell to be synchronous which has been much requested.

Each client has a default command queue and commands are consumed one at a time
from it. A command may suspend execution from the queue by returning
CMD_RETURN_WAIT and then resume it by calling cmd_continue() - for example
run-shell does this from the callback that is fired after the job is freed.

When the command queue becomes empty, command clients are automatically exited
(unless attaching). A callback is also fired - this is used for nested commands
in, for example, if-shell which can block execution of the client's cmdq until
a new cmdq becomes empty.

Also merge all the old error/info/print functions together and lose the old
curclient/cmdclient distinction - a cmdq is bound to one client (or none if in
the configuration file), this is a command client if c->session is NULL
otherwise an attached client.
2013-02-23 22:25:58 +00:00
Nicholas Marriott
243244d285 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-23 19:26:12 +00:00
Nicholas Marriott
497b27dafb Expand format variables in the run-shell and if-shell shell commands, from
Thiago Padilha.
2013-02-23 19:24:42 +00:00
Nicholas Marriott
ca6d9f799e Tidy TODO and nuke stuff that is done in some form or not going to happen. 2013-02-23 15:52:56 +00:00
Nicholas Marriott
f1aa5f6a1d Add to TODO. 2013-02-23 15:43:13 +00:00
Nicholas Marriott
dc50de782a The visit -> Visit 2013-02-23 15:15:20 +00:00
Nicholas Marriott
2e85eeea37 www Project Page -> SourceForge Page 2013-02-23 14:51:56 +00:00
Nicholas Marriott
357da035b9 Merge send-prefix into send-keys. 2013-02-23 14:41:07 +00:00
Nicholas Marriott
5aa54c863d Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-23 14:23:59 +00:00
Nicholas Marriott
42735d446e Merge show-buffer into save-buffer. 2013-02-23 14:23:35 +00:00
Nicholas Marriott
57eb334d5b Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-23 13:03:47 +00:00
Nicholas Marriott
5f904aa350 Add pane_tags format to format_window_pane based on code from George Nachman. 2013-02-23 13:02:52 +00:00
Nicholas Marriott
ee0f8adfac Handle focus events from the terminal, from Aaron Jensen. 2013-02-23 10:01:34 +00:00
Nicholas Marriott
1ed37385c6 Use -O2 without debugging. 2013-02-22 23:37:55 +00:00
Nicholas Marriott
3a2e9d805a Fix error reporting for client commands by adding a flag to cmd_find_client to
tell it whether or not to show errors, sometimes it's needed and sometimes not.
2013-02-22 23:04:53 +00:00
Nicholas Marriott
911ef4e69a Allow display-message with no curclient. 2013-02-22 22:57:26 +00:00
Nicholas Marriott
1994ae4640 Missing PANE_RESIZE define. 2013-02-22 21:47:34 +00:00
Nicholas Marriott
dbd8e47846 Do pane resize ioctls once at the end of the server loop rather than
immediately.
2013-02-22 21:35:29 +00:00
Nicholas Marriott
ce7bf1083e Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-22 16:25:50 +00:00
Nicholas Marriott
1db4ec6e63 Add pane_current_command format. 2013-02-22 16:25:21 +00:00
Nicholas Marriott
1c82cf7660 Remove a couple of FAQ bits that are out of date and not frequent. 2013-02-22 14:53:00 +00:00
Nicholas Marriott
e43fc6f08a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-22 14:32:33 +00:00
Nicholas Marriott
31407b70e0 Add option command-prefix which is automatically prepended to any command
(apart from a naked default-shell). The default is "exec ".
2013-02-22 14:31:38 +00:00
Nicholas Marriott
7d3c1016ce Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-22 07:25:38 +00:00
Nicholas Marriott
4c9f9438ff Add support for focus notifications when tmux pane changes, based on work by
Aaron Jensen.
2013-02-22 07:23:11 +00:00
Nicholas Marriott
374dae6635 Add a load of miscellaneous pane formats, from George Nachman. 2013-02-21 19:44:27 +00:00
Nicholas Marriott
8c50f625b0 Add session_set_current helper function, extracted from a diff from Aaron
Jensen.
2013-02-21 16:54:13 +00:00
Nicholas Marriott
6fc96978c2 Add to TODO. 2013-02-21 16:43:04 +00:00
Nicholas Marriott
8e3767e344 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-21 09:37:06 +00:00
Nicholas Marriott
b8b5631d9d Add -C and -J to capture pane to escape control sequences and to join wrapped
line, based on a diff from George Nachman.
2013-02-21 09:35:01 +00:00
Nicholas Marriott
c577b47cd5 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-20 23:16:53 +00:00
Nicholas Marriott
cb6f36655e evbuffer_readline returns allocated storage, don't leak it. 2013-02-20 23:15:21 +00:00
Nicholas Marriott
7905f4600d Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-20 14:58:23 +00:00
Nicholas Marriott
41c39e9bd9 Remove stray blank line. 2013-02-20 13:01:59 +00:00
Nicholas Marriott
f81d723264 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-20 10:59:02 +00:00
Nicholas Marriott
afd5e978cf Need to set clients in context before changing their reference count. 2013-02-20 10:25:15 +00:00
Nicholas Marriott
e68b9abd04 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-20 10:20:44 +00:00
Nicholas Marriott
e487b87f6f Clear last attributes after reset in string_cells, from George Nachman. 2013-02-20 09:34:21 +00:00
Nicholas Marriott
1e20153b6e Fix so capture-pane/save-buffer can work in control clients, from George
Nachman.
2013-02-20 09:32:52 +00:00
Nicholas Marriott
4621a52183 Include ML and IRC in the text. 2013-02-20 00:16:00 +00:00
Nicholas Marriott
e90a742db8 Tweak bold link. 2013-02-20 00:06:01 +00:00
Nicholas Marriott
b219d54503 Simplify main www page. 2013-02-20 00:03:59 +00:00
Nicholas Marriott
3108d80b7e Move NOTES->README, move Vim syntax file documentation to the file itself and
otherwise tweak some bits.
2013-02-19 23:31:04 +00:00
Nicholas Marriott
8a7d463b87 Prevent lock on control clients, not on others. 2013-02-19 21:11:32 +00:00
Nicholas Marriott
c3859d1df1 Add copy-pipe mode command to copy selection and also pipe to a command. 2013-02-19 17:49:53 +00:00
Nicholas Marriott
5a5e285be8 Don't try to print unterminated strings when loading configuration file. 2013-02-19 17:28:21 +00:00
Nicholas Marriott
4d1d4d6e8e Add -e flag to capture-pane to include embedded ANSI SGR escape sequences, from
George Nachman.
2013-02-19 09:55:02 +00:00
Nicholas Marriott
a96dd1932a Don't use a target-client for stdout, just always cmdclient. 2013-02-19 09:51:04 +00:00
Nicholas Marriott
693244795c Remove unnecessary initializers of cmd_ctx. 2013-02-18 23:38:57 +00:00
Nicholas Marriott
255a4f8ce3 load_cfg can actually use the same context now they are reference counted. 2013-02-18 23:35:54 +00:00
Nicholas Marriott
e2b26d910c Unbreak line wrapping. 2013-02-18 23:31:23 +00:00
Nicholas Marriott
293e331d69 Add functions to allocate and free command contexts rather than doing it all on
the stack.
2013-02-18 23:20:21 +00:00
Nicholas Marriott
2a91025581 Use tty_raw on stop, not tty_puts. 2013-02-18 17:35:53 +00:00
Nicholas Marriott
37d34b6b83 Don't hang when clearing line in choose mode now that the cursor stays at the
end with wrap.
2013-02-18 17:23:08 +00:00
Nicholas Marriott
44452823b7 Fix double space in sessions template. 2013-02-18 17:12:58 +00:00
Nicholas Marriott
e4bb87032e Add resize-pane -x and -y for absolute pane size. 2013-02-18 17:00:35 +00:00
Nicholas Marriott
a6c4c2cca0 Implement DECAWM (SM/RM 7) using existing MODE_WRAP flag. 2013-02-18 15:57:46 +00:00
Nicholas Marriott
ba3b8ccc1d Correctly turn handle UTF8 mouse option being toggled, from Egmont Koblinger. 2013-02-18 15:03:50 +00:00
Nicholas Marriott
e5eee7de0c Support the latest theory for mouse input, this is enabled/disabled with SM/RM
1006 and is similar in style to SGR input: \033[<b;x;yM or \033[b;x;ym. From
Egmont Koblinger.
2013-02-18 14:52:27 +00:00
Nicholas Marriott
d8261019f1 Add client_session and client_last_session formats. 2013-02-18 14:23:40 +00:00
Nicholas Marriott
9d165df18a No more lint means no more ARGSUSED. 2013-02-17 23:15:38 +00:00
Nicholas Marriott
7d1a8f7e9e Remove stray test code which would convert abc to x. 2013-02-17 23:05:57 +00:00
Nicholas Marriott
8df3ec612a In terminals with XT, turn on modifyOtherKeys=1 with the escape sequence and
handle the most common set. Pass them through if xterm-keys is on.
2013-02-17 22:56:12 +00:00
Nicholas Marriott
4c91c153cb I strongly suspect it is possible for tmux to block on detach in tty_raw, so
make the fd blocking again much later and have tty_raw just retry the write a
few times.
2013-02-17 22:28:11 +00:00
Nicholas Marriott
cf2c0237f4 Instead of loads of little screen_write_*_on and off functions which just
change mode flags, just have screen_write_mode_set and screen_write_mode_clear.
2013-02-17 10:43:35 +00:00
Nicholas Marriott
3d9fd1c7f2 Add various checks to turn off bits that can't work in control mode (such as
lock).
2013-02-17 10:12:55 +00:00
Nicholas Marriott
d1e8fb33da Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-17 10:04:59 +00:00
Nicholas Marriott
1e3a4f2331 Do not include status line in size calculations in control mode. 2013-02-17 10:04:26 +00:00
Thomas Adam
2ac1d46f46 Don't set key KEYC_NONE on xterm_keys_find match()
When calling xterm_keys_find(); if we get a complete match, don't set the
key to unknown before calling the action to complete the binding; otherwise
non-prefixed bindings will not work.
2013-02-16 21:04:48 +00:00
Nicholas Marriott
77a2174685 Fix a couple of memory leaks, from Romain Francoise. 2013-02-16 19:35:49 +00:00
Nicholas Marriott
3e270af17a Don't omit half the default table (!= not ==). 2013-02-16 13:29:40 +00:00
Nicholas Marriott
10db7ec51b Include the \033 in the key tree and adjust key matching for this change. 2013-02-16 13:21:14 +00:00
Nicholas Marriott
4f01bfc4bc Make choose-tree actually work again. 2013-02-15 12:57:13 +00:00
Nicholas Marriott
1d591ada76 Support capture-pane -p to send to stdout. 2013-02-15 09:31:45 +00:00
Nicholas Marriott
2bdc59fac8 Fix a comment for new key table names. 2013-02-15 02:38:15 +00:00
Nicholas Marriott
784a74df0b Fix function parameter to tty_keys_free. 2013-02-15 02:18:38 +00:00
Nicholas Marriott
82355d2f2d Tidy by splitting default key tables into two. 2013-02-15 02:16:41 +00:00
Nicholas Marriott
97a99d8718 Add -c to refresh-client to set client size in control mode, based on code from
George Nachman.
2013-02-15 01:54:48 +00:00
Nicholas Marriott
755d4863c8 Spaces -> tabs. 2013-02-14 12:22:14 +00:00
Nicholas Marriott
28544391f5 Do not leak formats in status_replace. 2013-02-14 12:20:17 +00:00
Nicholas Marriott
931b0103cd Clarify choose-tree entry in man page. 2013-02-13 11:07:21 +00:00
Nicholas Marriott
6e03b50771 Run session command before window in choose-tree. 2013-02-13 11:05:10 +00:00
Nicholas Marriott
362c460767 Do not crash when calling choose-tree with a command that changes the mode. 2013-02-13 11:01:26 +00:00
Nicholas Marriott
f4c815a1d9 Fix constness again, sigh. 2013-02-13 10:41:12 +00:00
Nicholas Marriott
fc6f08d5b7 No more need for freefn. 2013-02-13 10:27:49 +00:00
Nicholas Marriott
68e370574a Fix constness of window_choose_add_item and _window. 2013-02-13 10:25:37 +00:00
Nicholas Marriott
544c80d715 Fix constness of cmd_template_replace. 2013-02-13 10:19:43 +00:00
Nicholas Marriott
36fe146a74 Fix choose-tree usage. 2013-02-13 09:55:37 +00:00
Nicholas Marriott
caa29af2a9 Add user options, prefixed with @. May be set to any arbitrary string. 2013-02-13 09:54:24 +00:00
Nicholas Marriott
0f31d231db Return error for --foo when using compat/getopt.c. 2013-02-12 20:36:22 +00:00
Nicholas Marriott
102cb77435 Add -v to set and setw to show only option value. 2013-02-12 20:12:10 +00:00
Nicholas Marriott
7360ff4496 Use proc_pidinfo on Darwin for process name too, from OZAKI Kiichi. 2013-02-12 09:40:22 +00:00
Nicholas Marriott
a6fd92bd8d Remove stray change accidentally committed. 2013-02-10 19:15:49 +00:00
Nicholas Marriott
06ac4b628d Add a format client_prefix which is 1 if prefix key has been pressed, used for
example #{?client_prefix,X,Y}. Also a few extra server_client_status needed.
2013-02-10 18:58:05 +00:00
Nicholas Marriott
6c53a1ed68 Allow formats in status options. 2013-02-10 18:53:25 +00:00
Nicholas Marriott
6ad2c5c40f Show alias in lscm output. 2013-02-10 18:26:22 +00:00
Nicholas Marriott
99cc0015f8 Rework reflow code so it does not do so much allocation which should be faster
with large histories.
2013-02-10 18:15:30 +00:00
Nicholas Marriott
f1ce95915c Allow choose commands to be used outside tmux, so long as at least one client
is attached.
2013-02-10 17:52:51 +00:00
Nicholas Marriott
aadc87f5a7 Remove free callback for window_choose_data objects. 2013-02-10 17:36:58 +00:00
Nicholas Marriott
4d382ae8e6 Miscellaneous tidying of choose API, including:
- rename client and session to start_client and start_session in
  window_choose_data struct. also add TREE_OTHER define and reorder the
  struct
- rename window_choose_ctx to window_choose_data_run
- don't pass a cmd_ctx into window_choose_create (will let it use a
  different client later). instead take type, session, client
- add window_choose_data_free and use it to dispose of wcd rather than
  each cmd-*.c doing it individually
- change so ref counting is done by wcd_add and wcd_free rather than
  callers. this means 1 ref for each item but what of it :-)
- also add a ref to tree_session - not sure if this is needed?
- all the callbacks except choose-client and find-window are the same so
  remove them and add window_choose_default_callback
- reorder/rename some other bits and pieces for tidyness
2013-02-10 17:32:58 +00:00
Nicholas Marriott
418ba99078 Add to TODO. 2013-02-09 16:21:20 +00:00
Nicholas Marriott
648ce2f56a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-09 14:53:51 +00:00
Nicholas Marriott
0648c58716 Add to TODO list. 2013-02-09 14:52:11 +00:00
Thomas Adam
01da28efb1 Minor update to .gitignore
Now ignores:  corefiles, stray patches and tags file.
2013-02-09 10:26:57 +00:00
Thomas Adam
6d6e1581b5 Use osdep_get_cwd() for format change 2013-02-07 13:06:31 +00:00
Thomas Adam
64da762c15 Merge branch 'obsd-master' 2013-02-07 12:08:55 +00:00
Nicholas Marriott
8903c1f167 Automatically reflow wrapped lines when a pane is resized, requested by
many over the years and finally implemented by Richard Woodbury.
2013-02-05 11:08:59 +00:00
Nicholas Marriott
a5521597b0 Don't set some string formats if the string is NULL. 2013-02-05 11:01:45 +00:00
Thomas Adam
fe00607816 Only set AUTO{MAKE,CONF}_VERSION on OpenBSD
OpenBSD requires the presence of AUTOMAKE_VERSION and AUTOCONF_VERSION for
bootstrapping purposes.  Setting these on any other system requires that
explicit version to be used, rather than what might already be installed.

Therefore, only do this when the platform is OpenBSD and ignore everything
else.
2013-01-31 00:14:59 +00:00
Thomas Adam
6e6d756109 Corrections to SYNCING
* Reflow some paragraphs due to repo-naming pushing the line length over 80
  chaacters.

* Correct path to git clone commands for each repo.
2013-01-30 23:28:38 +00:00
Nicholas Marriott
85531fd404 Unused variable/type nit from Thomas Adam. 2013-01-30 17:00:17 +00:00
Nicholas Marriott
c4c98df4f2 Add -Wdeclaration-after-statement. 2013-01-30 16:35:00 +00:00
Thomas Adam
a3f4eb7b24 Merge branch 'obsd-master'
Conflicts:
	Makefile
	grid-utf8.c
2013-01-30 15:27:19 +00:00
Nicholas Marriott
fdbfc7e349 Rather than having two grids for each pane, one for ASCII and one for
UTF-8, collapse the two together. Simplifies the code at the expense of
more memory (which can probably be reduced again later).
2013-01-18 02:16:21 +00:00
Nicholas Marriott
c2e2107063 Style nits - return (x) not return x. 2013-01-18 02:10:29 +00:00
Thomas Adam
2ca8b7f359 Merge branch 'obsd-master' 2013-01-17 22:14:18 +00:00
Nicholas Marriott
3a09e01a8e Do not allow cursor colours to be set beginning with ? as that will
report the colour, from Hayaki Saito.
2013-01-17 20:30:43 +00:00
Nicholas Marriott
d31315884c Fix some blank line nits. 2013-01-17 03:51:21 +00:00
Nicholas Marriott
57ca428975 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-01-17 02:09:18 +00:00
Nicholas Marriott
b0e2ef1a7d Update www for new SF URLs. 2013-01-17 02:08:58 +00:00
Thomas Adam
b237d9dd95 Updated SYNCING 2013-01-17 02:02:04 +00:00
Thomas Adam
de194016ec Merge branch 'obsd-master' 2013-01-17 01:38:21 +00:00
Nicholas Marriott
e33ba57c13 Remove the layout undo/redo code which never really worked. 2013-01-17 00:11:22 +00:00
Nicholas Marriott
44f8e1caff Implement ECH (erase character, CSI X). Reported by Christian Neukirchen. 2013-01-15 23:18:55 +00:00
Nicholas Marriott
bc2e4a36df If timing between keys is less than (by default) 1 millisecond, assume
the text is being pasted. assume-paste-time option changes the value (0
disables). Based on a diff from Marcin Kulik.
2013-01-15 22:55:29 +00:00
Thomas Adam
675c6b3773 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-12-31 18:50:37 +00:00
Tiago Cunha
f4472c16b2 Fix keyword matching.
Per the documentation in *:syn-keyword* (in particular *E789*), the
optional characters inside the square brackets can only be used in the
end. Therefore, unfold some keywords which were being wrongly
recognised.

Noticed by Bruce Wolk.
2012-12-24 17:18:35 +00:00
Nicholas Marriott
854e8ae04d Add ^ and $ special command targets to select lowest and highest
numbered windows, from Raghavendra D Prabhu.
2012-12-24 12:38:57 +00:00
Nicholas Marriott
3e6d45acf6 Add -T option to select-window to toggle to last window if already
current, from Raghavendra D Prabhu.
2012-12-24 12:34:32 +00:00
Nicholas Marriott
a2c8af97e9 Add missing function prototype. 2012-12-24 12:33:05 +00:00
Nicholas Marriott
b18ff67646 Add a -u flag to choose-tree to start uncollapsed, from Raghavendra D
Prabhu.
2012-12-24 12:25:52 +00:00
millert
6a5adfc0ba We no longer use struct eproc for kinfo_proc in sysctl.h so there
is no direct need for sys/proc.h or sys/resource.h.  Some consumers
of kinfo_proc need these for the proc flags and rlimit defines like
RLIM_INF so add the appropriate includes to them.
OK deraadt@ sthen@
2012-12-18 21:28:45 +00:00
Nicholas Marriott
9714880283 Change load_cfg to fix a crash reported by jasper. 2012-12-13 15:36:16 +00:00
Nicholas Marriott
3a0016a78a Use the CMD_*_USAGE defines consistently, from Thomas Adam. 2012-12-09 23:17:35 +00:00
Thomas Adam
fb83914bd7 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-12-08 20:29:37 +00:00
Thomas Adam
d5de489dc4 .+ 2012-12-08 19:16:45 +00:00
Nicholas Marriott
3fa4f691e3 Handle resetting 256-colours properly when parsing #[default],
#[fg=default] and #[bg=default] styles.
2012-12-08 17:05:57 +00:00
Nicholas Marriott
8600fe054b Use strlcat not strncat in load_cfg and some other trivial tidying from
Tiago Cunha.
2012-12-06 13:06:05 +00:00
Nicholas Marriott
8378be03d1 Fix argument order in a log statement. 2012-12-06 12:49:13 +00:00
Nicholas Marriott
51a1dbfe09 Simplify command string parsing with a helper function from Tiago Cunha. 2012-12-06 12:47:48 +00:00
Nicholas Marriott
8264e92b37 Fix return value of load_cfg, from Thomas Adam. 2012-11-27 22:59:34 +00:00
Thomas Adam
739a76634c Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-27 22:24:00 +00:00
Nicholas Marriott
47c097cb51 Support middle-click paste, based on a diff from Ailin Nemui. 2012-11-27 20:22:12 +00:00
Nicholas Marriott
24d7d073ff Support the 47 and 1047 SM and RM sequences (alternate screen without
cursor), requested by I forget who ages ago.
2012-11-27 20:08:42 +00:00
Thomas Adam
39631edb98 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-27 18:12:04 +00:00
Nicholas Marriott
9b8998aeec Correctly aggregate together errors from nested config files (with
source-file). Fix by Thomas Adam, reported by Sam Livingstone-Gray
2012-11-27 16:12:29 +00:00
Nicholas Marriott
4aa4e9fb26 Allow cmd-run-shell to accept -t to specify the pane to display the
output, requested by Alexander Tsepkov.
2012-11-27 15:09:35 +00:00
Nicholas Marriott
1fcc7f50ac When scrolling in copy mode with the mouse, scroll screen rather than
moving cursor. This change from Ailin Nemui, alternative to a change
from Stephen Hicks.
2012-11-27 14:42:56 +00:00
Nicholas Marriott
6ef4f8e16c Revert last, after discussion it isn't necessary. 2012-11-27 14:26:48 +00:00
Nicholas Marriott
93224260ae Add window-status-last-* options, from Boris Faure. 2012-11-27 13:52:23 +00:00
Nicholas Marriott
991bfcf443 Fix session choice so that preferring unattached sessions actually
works, reported by Drew Frank.
2012-11-27 09:20:03 +00:00
Nicholas Marriott
d762ced298 Call realpath earlier on the socket directory path rather than on the
socket file path because the latter may not exist yet and in that case
realpath is allowed to fail. From Romain Francoise.
2012-11-26 11:35:28 +00:00
Thomas Adam
1bc910a963 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-22 22:19:04 +00:00
Nicholas Marriott
63f451965c Merge branch 'master' of ssh://tmux.git.sourceforge.net/gitroot/tmux/tmux 2012-11-22 16:48:50 +00:00
Nicholas Marriott
260419f48e Put helper function back, will be needed in a bit. 2012-11-22 14:41:11 +00:00
Thomas Adam
c04aa90207 Merge branch 'obsd-master'
Sync from OpenBSD.

* obsd-master:
  Add halfpage commands to mode command string table (missed by accident), from Thomas Adam.
  Clarify some points about config files, notably that they are only read at server start. From Thomas Adam.
  Use a utility function for common code to show errors in config file, from Thomas Adam.
2012-11-22 13:24:14 +00:00
Nicholas Marriott
0679eb6a6d Add halfpage commands to mode command string table (missed by accident),
from Thomas Adam.
2012-11-19 10:51:25 +00:00
Nicholas Marriott
9a7e5bd1d3 Clarify some points about config files, notably that they are only read
at server start. From Thomas Adam.
2012-11-19 10:50:24 +00:00
Nicholas Marriott
827b311c81 Use a utility function for common code to show errors in config file,
from Thomas Adam.
2012-11-19 10:38:06 +00:00
Thomas Adam
e4679172e3 Sanitise additional .mailmap entries
This sanitises multiple author addresses some more, mapping them back to one
common entity.
2012-11-08 21:39:35 +00:00
Thomas Adam
be10e8eee6 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-08 21:27:40 +00:00
Thomas Adam
cb4553bd06 Add .mailmap for commit author translations
Because it's not possible to enumerate up-front all of the committers to
tmux coming from OpenBSD, at the time a commit is imported in to git from
the OpenBSD CVS repository, the author information is not known to Git,
necessarily.

But it's possible to alter for output the respective author after the fact,
via Git's .mailmap file.  It is this file which will therefore provide a new
mapping of OpenBSD commiter to an actual real name and real email address.
2012-11-08 21:14:32 +00:00
Nicholas Marriott
c68efec6c0 Show last client activity time in default choose-client list. 2012-11-05 13:13:04 +00:00
Thomas Adam
a75801320d Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-04 01:27:57 +00:00
okan
241a746f32 fix an off-by-one
ok nicm@
2012-10-31 19:11:18 +00:00
Thomas Adam
47fbf87185 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-10-26 20:28:58 +01:00
Nicholas Marriott
d210d99cce Make mouse event structure clearer by defining events (up, click, drag)
and simplifying how buttons and wheels are represented, from Ailin
Nemui. Should be no functional changes.
2012-10-26 14:35:42 +00:00
Thomas Adam
31f93d8445 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-10-25 23:32:14 +01:00
Nicholas Marriott
2a609b332f Add ability to active pane in list-windows and find-window formats, from
Carl Henrik Lunde.
2012-10-25 11:26:47 +00:00
Nicholas Marriott
18236c1c1b Fix BELL_NONE which had been broken in some code reorganisation or other
also don't redraw unnecessarily. From Seiji Ohashi.
2012-10-25 11:16:53 +00:00
Nicholas Marriott
596e9d8068 Fix bad size in memcpy from Romain Francoise. 2012-10-25 11:14:46 +00:00
Nicholas Marriott
589b4b8c6a Fix typo bell->bells from Thomas Adam. 2012-10-25 11:11:58 +00:00
Nicholas Marriott
60808bbded +. 2012-10-23 18:47:52 +01:00
Thomas Adam
d4dc52ec84 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-10-16 18:30:36 +01:00
Nicholas Marriott
c695c0c085 Fix some function prototypes from Helmut Tessarek. 2012-10-15 21:53:30 +00:00
Nicholas Marriott
a91c598971 Link to git instructions from index.html. 2012-10-15 18:25:44 +01:00
Thomas Adam
bf45619441 Don't push all tags when releasing tmux
Pushing all tags with "git push --tags" will also transfer tags from the
tmux-openbsd repository which isn't what we want to do!

Therefore, just specify the newly created tag to push instead for the next
release.
2012-10-13 13:35:35 +01:00
Thomas Adam
9b2aabb752 Merge branch 'master' of ssh://tmux.git.sourceforge.net/gitroot/tmux/tmux 2012-10-13 12:25:08 +01:00
Thomas Adam
c0fb5edff9 Update website. 2012-10-13 12:22:11 +01:00
Thomas Adam
5cdc9591d3 Working on 1.8 2012-10-13 12:12:43 +01:00
235 changed files with 32810 additions and 19905 deletions

8
.gitignore vendored
View File

@@ -1,6 +1,12 @@
*.o *.o
*~ *~
*.diff
*.patch
*.core
core
tags
.deps/ .deps/
compat/.dirstamp
aclocal.m4 aclocal.m4
autom4te.cache/ autom4te.cache/
config.log config.log
@@ -10,3 +16,5 @@ tmux
Makefile Makefile
Makefile.in Makefile.in
configure configure
tmux.1.*
*.dSYM

37
.mailmap Normal file
View File

@@ -0,0 +1,37 @@
Bob Beck <beck@openbsd.org> beck <beck>
Claudio Jeker <claudio@openbsd.org> claudio <claudio>
Igor Sobrado <sobrado@openbsd.org> sobrado <sobrado>
Ingo Schwarze <schwarze@openbsd.org> schwarze <schwarze>
Jacek Masiulaniec <jacekm@openbsd.org> jacekm <jacekm>
Jason McIntyre <jmc@openbsd.org> jmc <jmc>
Joel Sing <jsing@openbsd.org> jsing <jsing>
Jonathan Gray <jsg@openbsd.org> jsg <jsg>
Kenneth R Westerback <krw@openbsd.org> krw <krw>
Marc Espie <espie@openbsd.org> espie <espie>
Matthew Dempsky <matthew@openbsd.org> matthew <matthew>
Matthias Kilian <kili@openbsd.org> kili <kili>
Matthieu Herrb <matthieu@openbsd.org> matthieu <matthieu>
Michael McConville <mmcc@openbsd.org> mmcc <mmcc>
Miod Vallat <miod@openbsd.org> miod <miod>
Nicholas Marriott <nicholas.marriott@gmail.com> Nicholas Marriott <nicm@openbsd.org>
Nicholas Marriott <nicholas.marriott@gmail.com> nicm <nicm>
Nicholas Marriott <nicholas.marriott@gmail.com> no_author <no_author@example.org>
Okan Demirmen <okan@openbsd.org> okan <okan>
Philip Guenther <guenther@openbsd.org> guenther <guenther>
Pierre-Yves Ritschard <pyr@openbsd.org> pyr <pyr>
Ray Lai <ray@openbsd.org> ray <ray>
Ryan McBride <mcbride@openbsd.org> mcbride <mcbride>
Sebastian Benoit <benno@openbsd.org> benno <benno>
Sebastien Marie <semarie@openbsd.org> semarie <semarie>
Stefan Sperling <stsp@openbsd.org> stsp <stsp>
Stuart Henderson <sthen@openbsd.org> sthen <sthen>
Ted Unangst <tedu@openbsd.org> tedu <tedu>
Theo de Raadt <deraadt@openbsd.org> Theo Deraadt <deraadt@openbsd.org>
Theo de Raadt <deraadt@openbsd.org> deraadt <deraadt>
Thomas Adam <thomas@xteddy.org> Thomas <thomas@xteddy.org>
Thomas Adam <thomas@xteddy.org> Thomas Adam <thomas.adam@smoothwall.net>
Thomas Adam <thomas@xteddy.org> n6tadam <n6tadam@xteddy.org>
Tim van der Molen <tim@openbsd.org> tim <tim>
Tobias Stoeckmann <tobias@openbsd.org> tobias <tobias>
Todd C Miller <millert@openbsd.org> millert <millert>
William Yodlowsky <william@openbsd.org> william <william>

10
.travis.yml Normal file
View File

@@ -0,0 +1,10 @@
language: c
matrix:
include:
- compiler: gcc
- compiler: clang
env: CFLAGS="-g -O2"
before_install:
- sudo apt-get update -qq
- sudo apt-get -y install debhelper autotools-dev dh-autoreconf file libncurses5-dev libevent-dev pkg-config libutempter-dev build-essential
script: (CFLAGS= ./autogen.sh) && ./configure --enable-debug && make

403
CHANGES
View File

@@ -1,3 +1,397 @@
CHANGES FROM 2.3 to 2.4 20 April 2017
Incompatible Changes
====================
* Key tables have undergone major changes. Mode key tables are no longer
separate from the main key tables. All mode key tables have been removed,
together with the -t flag to bind-key and unbind-key.
The emacs-edit, vi-edit, emacs-choose and vi-choose tables have been replaced
by fixed key bindings in the command prompt and choose modes. The mode-keys
and status-keys options remain.
The emacs-copy and vi-copy tables have been replaced by the copy-mode and
copy-mode-vi tables. Commands are sent using the -X and -N flags to
send-keys. So the following:
bind -temacs-copy C-Up scroll-up
bind -temacs-copy -R5 WheelUpPane scroll-up
Becomes:
bind -Tcopy-mode C-Up send -X scroll-up
bind -Tcopy-mode WheelUpPane send -N5 -X scroll-up
This changes allows the full command parser (including command sequences) and
command set to be used - for example, the normal command prompt with editing
and history is now used for searching, jumping, and so on instead of a custom
one. The default C-r binding is now:
bind -Tcopy-mode C-r command-prompt -p'search up' "send -X search-backward '%%'"
There are also some new commmands available with send -X, such as
copy-pipe-and-cancel.
* set-remain-on-exit has gone -- can be achieved with hooks instead.
* Hooks: before hooks have been removed and only a selection of commands now
have after hooks (they are no longer automatic). Additional hooks have been
added.
* The xterm-keys option now defaults to on.
Normal Changes
==============
* Support for mouse double and triple clicks.
* BCE (Background Colour Erase) is now supported.
* All occurrences of a search string in copy mode are now highlighted;
additionally, the number of search results is displayed. The highlighting
updates interactively with the default emacs key bindings (incremental
search).
* source-file now understands glob patterns.
* Formats now have simple comparisons:
#{==:a,b}
#{!=:a,b}
* There are the following new formats:
- #{version} -- the tmux server version;
- #{client_termtype} -- the terminal type of the client;
- #{client_name} -- the name of a client;
- #{client_written} -- the number of bytes written to the client.
* The configuration file now accepts %if/%endif conditional blocks which are
processed when it is parsed; the argument is a format string (useful with the
new format comparison options).
* detach-client now has -E to execute a command replacing the client instead of
exiting.
* Add support for custom command aliases, this is an array option which
contains items of the form "alias=command". This is consulted when an
unknown command is parsed.
* break-pane now has -n to specify the new window name.
* OSC 52 support has been added for programs inside tmux to set a tmux buffer.
* The mouse "all event" mode (1003) is now supported.
* Palette setting is now possible (OSC 4 and 104).
* Strikethrough support (a recent terminfo is required).
* Grouped sessions can now be named (new -t).
* terminal-overrides and update-environment are now array options (the previous
set -ag syntax should work without change).
* There have been substantial performance improvements.
CHANGES FROM 2.2 to 2.3 29 September 2016
Incompatible Changes
====================
None.
Normal Changes
==============
* New option 'pane-border-status' to add text in the pane borders.
* Support for hooks on commands: 'after' and 'before' hooks.
* 'source-file' understands '-q' to suppress errors for nonexistent files.
* Lots of UTF8 improvements, especially on MacOS.
* 'window-status-separator' understands #[] expansions.
* 'split-window' understands '-f' for performing a full-width split.
* Allow report count to be specified when using 'bind-key -R'.
* 'set -a' for appending to user options (@foo) is now supported.
* 'display-panes' can now accept a command to run, rather than always
selecting the pane.
CHANGES FROM 2.1 to 2.2 10 April 2016
Incompatible Changes
====================
* The format strings which referenced time have been removed. Instead:
#{t:window_activity}
can be used.
* Support for TMPDIR has been removed. Use TMUX_TMPDIR instead.
* UTF8 detection now happens automatically if the client supports it, hence
the:
mouse-utf8
utf8
options has been removed.
* The:
mouse_utf8_flag
format string has been removed.
* The -I option to show-messages has been removed. See:
#{t:start_time}
format option instead.
Normal Changes
==============
* Panes are unzoomed with selectp -LRUD
* New formats added:
#{scroll_position}
#{socket_path}
#{=10:...} -- limit to N characters (from the start)
#{=-10:...} -- limit to N characters (from the end)
#{t:...} -- used to format time-based formats
#{b:...} -- used to ascertain basename from string
#{d:...} -- used to ascertain dirname from string
#{s:...} -- used to perform substitutions on a string
* Job output is run via the format system, so formats work again
* If display-time is set to 0, then the indicators wait for a key to be
pressed.
* list-keys and list-commands can be run without starting the tmux server.
* kill-session learns -C to clear all alerts in all windows of the session.
* Support for hooks (internal for now), but hooks for the following have been
implemented:
alert-bell
alert-silence
alert-activity
client-attached
client-detached
client-resized
pane-died
pane-exited
* RGB (24bit) colour support. The 'Tc' flag must be set in the external TERM
entry (using terminal-overrides or a custom terminfo entry).
CHANGES FROM 2.0 to 2.1 18 October 2015
Incompatible Changes
====================
* Mouse-mode has been rewritten. There's now no longer options for:
- mouse-resize-pane
- mouse-select-pane
- mouse-select-window
- mode-mouse
Instead there is just one option: 'mouse' which turns on mouse support
entirely.
* 'default-terminal' is now a session option. Furthermore, if this is set
to 'screen-*' then emulate what screen does. If italics are wanted, this
can be set to 'tmux' but this is still new and not necessarily supported
on all platforms with older ncurses installs.
* The c0-* options for rate-limiting have been removed. Instead, a backoff
approach is used.
Normal Changes
==============
* New formats:
- session_activity
- window_linked
- window_activity_format
- session_alerts
- session_last_attached
- client_pid
- pid
* 'copy-selection', 'append-selection', 'start-named-buffer' now understand
an '-x' flag to prevent it exiting copying mode.
* 'select-pane' now understands '-P' to set window/pane background colours.
* 'renumber-windows' now understands windows which are unlinked.
* 'bind' now understands multiple key tables. Allows for key-chaining.
* 'select-layout' understands '-o' to undo the last layout change.
* The environment is updated when switching sessions as well as attaching.
* 'select-pane' now understands '-M' for marking a pane. This marked pane
can then be used with commands which understand src-pane specifiers
automatically.
* If a session/window target is prefixed with '=' then only an exact match
is considered.
* 'move-window' understands '-a'.
* 'update-environment' understands '-E' when attach-session is used on an
already attached client.
* 'show-environment' understands '-s' to output Bourne-compatible commands.
* New option: 'history-file' to save/restore command prompt history.
* Copy mode is exited if the history is cleared whilst in copy-mode.
* 'copy-mode' learned '-e' to exit copy-mode when scrolling to end.
CHANGES FROM 1.9a to 2.0 6 March 2015
Incompatible Changes
====================
* The choose-list command has been removed.
* 'terminal-overrides' is now a server option, not a session option.
* 'message-limit' is now a server option, not a session option.
* 'monitor-content' option has been removed.
* 'pane_start_path' option has been removed.
* The "info" mechanism which used to (for some commands) provide feedback
has been removed, and like other commands, they now produce nothing on
success.
Normal Changes
==============
* tmux can now write an entry to utmp if the library 'utempter' is present
at compile time.
* set-buffer learned append mode (-a), and a corresponding
'append-selection' command has been added to copy-mode.
* choose-mode now has the following commands which can be bound:
- start-of-list
- end-of-list
- top-line
- bottom-line
* choose-buffer now understands UTF-8.
* Pane navigation has changed:
- The old way of always using the top or left if the choice is ambiguous.
- The new way of remembering the last used pane is annoying if the
layout is balanced and the leftmost is obvious to the user (because
clearly if we go right from the top-left in a tiled set of four we want
to end up in top-right, even if we were last using the bottom-right).
So instead, use a combination of both: if there is only one possible
pane alongside the current pane, move to it, otherwise choose the most
recently used of the choice.
* 'set-buffer' can now be told to give names to buffers.
* The 'new-session', 'new-window', 'split-window', and 'respawn-pane' commands
now understand multiple arguments and handle quoting problems correctly.
* 'capture-pane' understands '-S-' to mean the start of the pane, and '-E-' to
mean the end of the pane.
* Support for function keys beyond F12 has changed. The following explains:
- F13-F24 are S-F1 to S-F12
- F25-F36 are C-F1 to C-F12
- F37-F48 are C-S-F1 to C-S-F12
- F49-F60 are M-F1 to M-F12
- F61-F63 are M-S-F1 to M-S-F3
Therefore, F13 becomes a binding of S-F1, etc.
* Support using pane id as part of session or window specifier (so % means
session-of-%1 or window-of-%1) and window id as part of session
(so @1 means session-of-@1).
* 'copy-pipe' command now understands formats via -F
* 'if-shell' command now understands formats via -F
* 'split-window' and 'join-window' understand -b to create the pane to the left
or above the target pane.
CHANGES FROM 1.9 to 1.9a 22 February 2014
NOTE: This is a bug-fix release to address some important bugs which just
missed the 1.9 deadline, but were found afterwards.
Normal Changes
==============
* Fix crash due to uninitialized lastwp member of layout_cell
* Fix -fg/-bg/-style with 256 colour terminals.
CHANGES FROM 1.8 to 1.9, 20 February 2014
NOTE: This release has bumped the tmux protocol version. It is therefore
advised that the prior tmux server is restarted when this version of tmux is
installed, to avoid protocol mismatch errors for newer clients trying to
talk to an older running tmux server.
Incompatible Changes
====================
* 88 colour support has been removed.
* 'default-path' has been removed. The new-window command accepts '-c' to
cater for this. The previous value of "." can be replaced with: 'neww -c
$PWD', the previous value of '' which meant current path of the pane can
be specified as: 'neww -c "#{pane_current_path}"'
Deprecated Changes
==================
* The single format specifiers: #A -> #Z (where defined) have been
deprecated and replaced with longer-named equivalents, as listed in the
FORMATS section of the tmux manpage.
* The various foo-{fg,bg,attr} commands have been deprecated and replaced
with equivalent foo-style option instead. Currently this is still
backwards-compatible, but will be removed over time.
Normal Changes
==============
* A new environment variable TMUX_TMPDIR is now honoured, allowing the
socket directory to be set outside of TMPDIR (/tmp/ if not set).
* If -s not given to swap-pane the current pane is assumed.
* A #{pane_synchronized} format specifier has been added to be a conditional
format if a pane is in a synchronised mode (c.f. synchronize-panes)
* Tmux now runs under Cygwin natively.
* Formats can now be nested within each other and expanded accordingly.
* Added 'automatic-rename-format' option to allow the automatic rename
mechanism to use something other than the default of
#{pane_current_command}.
* new-session learnt '-c' to specify the starting directory for that session
and all subsequent windows therein.
* The session name is now shown in the message printed to the terminal when
a session is detached.
* Lots more format specifiers have been added.
* Server race conditions have been fixed; in particular commands are not run
until after the configuration file is read completely.
* Case insensitive searching in tmux's copy-mode is now possible.
* attach-session and switch-client learnt the '-t' option to accept a window
and/or a pane to use.
* Copy-mode is only exited if no selection is in progress.
* Paste key in copy-mode is now possible to enter text from the clipboard.
* status-interval set to '0' now works as intended.
* tmux now supports 256 colours running under fbterm.
* Many bug fixes!
CHANGES FROM 1.7 to 1.8, 26 March 2013
Incompatible Changes
====================
* layout redo/undo has been removed.
Normal Changes
==============
* Add halfpage up/down bindings to copy mode.
* Session choosing fixed to work with unattached sessions.
* New window options window-status-last-{attr,bg,fg} to denote the last
window which was active.
* Scrolling in copy-mode now scrolls the region without moving the mouse
cursor.
* run-shell learnt '-t' to specify the pane to use when displaying output.
* Support for middle-click pasting.
* choose-tree learns '-u' to start uncollapsed.
* select-window learnt '-T' to toggle to the last window if it's already
current.
* New session option 'assume-paste-time' for pasting text versus key-binding
actions.
* choose-* commands now work outside of an attached client.
* Aliases are now shown for list-commands command.
* Status learns about formats.
* Free-form options can be set with set-option if prepended with an '@'
sign.
* capture-pane learnt '-p' to send to stdout, and '-e' for capturing escape
sequences, and '-a' to capture the alternate screen, and '-P' to dump
pending output.
* Many new formats added (client_session, client_last_session, etc.)
* Control mode, which is a way for a client to send tmux commands.
Currently more useful to users of iterm2.
* resize-pane learnt '-x' and '-y' for absolute pane sizing.
* Config file loading now reports errors from all files which are loaded via
the 'source-file' command.
* 'copy-pipe' mode command to copy selection and pipe the selection to a
command.
* Panes can now emit focus notifications for certain applications
which use those.
* run-shell and if-shell now accept formats.
* resize-pane learnt '-Z' for zooming a pane temporarily.
* new-session learnt '-A' to make it behave like attach-session.
* set-option learnt '-o' to prevent setting an option which is already set.
* capture-pane and show-options learns '-q' to silence errors.
* New command 'wait-for' which blocks a client until woken up again.
* Resizing panes will now reflow the text inside them.
* Lots and lots of bug fixes, fixing memory-leaks, etc.
* Various manpage improvements.
CHANGES FROM 1.6 to 1.7, 13 October 2012 CHANGES FROM 1.6 to 1.7, 13 October 2012
* tmux configuration files now support line-continuation with a "\" at the * tmux configuration files now support line-continuation with a "\" at the
@@ -725,7 +1119,7 @@ The list of older changes is below.
* -u flag to scroll-mode and copy-mode to start scrolled one page * -u flag to scroll-mode and copy-mode to start scrolled one page
up. scroll-mode -u is bound to prefix,page-up (ppage) by default. up. scroll-mode -u is bound to prefix,page-up (ppage) by default.
* Allow status, mode and message attributes to be changed by three new options: * Allow status, mode and message attributes to be changed by three new options:
status-attr, mode-attr, message-attr. A comma-separataed list is accepted status-attr, mode-attr, message-attr. A comma-separated list is accepted
containing: bright, dim, underscore, blink, reverse, hidden, italics, for containing: bright, dim, underscore, blink, reverse, hidden, italics, for
example: example:
@@ -1748,10 +2142,3 @@ The list of older changes is below.
emacs) that don't require scrolling regions (ESC[r) mostly work fine emacs) that don't require scrolling regions (ESC[r) mostly work fine
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id$
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms
LocalWords: dstidx srcname srcidx winlink lsw nabc sabc Exp Tiago Cunha dch
LocalWords: setw Chisnall renamew merdely eg Maier newname selectw neww Gass

33
CONTRIBUTING Normal file
View File

@@ -0,0 +1,33 @@
When reporting issues:
YOU MUST INCLUDE THE TMUX VERSION
DO NOT OPEN AN ISSUE THAT DOES NOT MENTION THE TMUX VERSION
Please also include:
- your platform (Linux, OS X, or whatever);
- a brief description of the problem with steps to reproduce;
- a minimal tmux config, if you can't reproduce without a config;
- your terminal, and $TERM inside and outside of tmux;
- logs from tmux (see below);
- at most one or two screenshots, if helpful.
This should include at least the output of:
$ uname -sp && tmux -V && echo $TERM
Please do not report bugs (crashes, incorrect behaviour) without reproducing on
a tmux built from Git master.
Note that TERM inside tmux must be a variant of screen or tmux (for example:
screen or screen-256color, tmux or tmux-256color). Please ensure this is the
case before opening an issue.
To run tmux without a config and get logs, run:
tmux -Ltest kill-server
tmux -vvvv -Ltest -f/dev/null new
Then reproduce the problem, exit tmux, and attach the tmux-server-*.log file
from the current directory to the issue.

21
COPYING Normal file
View File

@@ -0,0 +1,21 @@
THIS IS FOR INFORMATION ONLY, CODE IS UNDER THE LICENCE AT THE TOP OF ITS FILE.
The README, CHANGES, FAQ and TODO files are licensed under the ISC
license. Files under examples/ remain copyright their authors unless otherwise
stated in the file but permission has been received to distribute them with
tmux. All other files have a license and copyright notice at their start,
typically:
Copyright (c) <author>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

179
FAQ
View File

@@ -95,9 +95,6 @@ aware of are (bearing in mind I haven't used screen for a few years now):
- screen has builtin serial and telnet support; this is bloat and is unlikely - screen has builtin serial and telnet support; this is bloat and is unlikely
to be added to tmux. to be added to tmux.
- screen has support for updating utmp. Nobody has really come up with a clean,
portable way to do this without making tmux setuid or setgid yet.
- Environment handling is different. - Environment handling is different.
- tmux tends to be more demanding on the terminal so tends to show up terminal - tmux tends to be more demanding on the terminal so tends to show up terminal
@@ -107,8 +104,12 @@ aware of are (bearing in mind I haven't used screen for a few years now):
* I found a bug! What do I do? * I found a bug! What do I do?
Please send bug reports by email to nicm@users.sourceforge.net or Check the latest version of tmux from Git to see if the problem is still
tmux-users@lists.sourceforge.net. Please include as much of the following reproducible. Sometimes the length of time between releases means a lot of
fixes can be sitting in Git and the problem might already be fixed.
Please send bug reports by email to nicholas.marriott@gmail.com or
tmux-users@googlegroups.com. Please include as much of the following
information as possible: information as possible:
- the version of tmux you are running; - the version of tmux you are running;
@@ -122,7 +123,7 @@ information as possible:
* Why doesn't tmux do $x? * Why doesn't tmux do $x?
Please send feature requests by email to nicm@users.sourceforge.net. Please send feature requests by email to tmux-users@googlegroups.com.
* Why do you use the screen terminal description inside tmux? It sucks. * Why do you use the screen terminal description inside tmux? It sucks.
@@ -238,6 +239,31 @@ would be welcome.
vim users may also want to set the "ttyfast" option inside tmux. vim users may also want to set the "ttyfast" option inside tmux.
* How do I make ctrl and shift arrow keys work in emacs?
The terminal-init-screen function in term/screen.el is called for new frames,
but it doesn't configure any function keys.
If the tmux xterm-keys option is on, it is enough to define the same keys as
xterm. Add the following to init.el or .emacs to do this:
(defadvice terminal-init-screen
;; The advice is named `tmux', and is run before `terminal-init-screen' runs.
(before tmux activate)
;; Docstring. This describes the advice and is made available inside emacs;
;; for example when doing C-h f terminal-init-screen RET
"Apply xterm keymap, allowing use of keys passed through tmux."
;; This is the elisp code that is run before `terminal-init-screen'.
(if (getenv "TMUX")
(let ((map (copy-keymap xterm-function-map)))
(set-keymap-parent map (keymap-parent input-decode-map))
(set-keymap-parent input-decode-map map))))
And ensure .tmux.conf contains "set -g xterm-keys on".
Alternatively, the screen.el file can be copied to the load path and
customized.
* Why doesn't elinks set the window title inside tmux? * Why doesn't elinks set the window title inside tmux?
There isn't a way to detect if a terminal supports setting the window title, so There isn't a way to detect if a terminal supports setting the window title, so
@@ -326,87 +352,33 @@ lock(1) or vlock(1)) by using the following:
bind x set lock-command '/usr/bin/vlock' \; lock-client \; set lock-command 'tput civis && read -s -n1' bind x set lock-command '/usr/bin/vlock' \; lock-client \; set lock-command 'tput civis && read -s -n1'
* How can I open a new window in the same directory as the current window? * I don't see italics! Or less and vim show italics and reverse the wrong way round!
One option is to just run "TMUX= tmux" in the window. However, this only works if no GNU screen does not support italics and the "screen" terminfo description uses
command is running, so that you can input the command. the italics escape sequence incorrectly.
A workaround is to let tmux know about the current path through an environment As of tmux 2.1, if default-terminal is set to "screen" or matches "screen-*",
variable. To do so, use the following command: tmux will behave like screen and italics will be disabled.
[ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#I") $PWD To enable italics, create a new terminfo entry called "tmux" (some platforms
may already have this, you can check with "infocmp tmux"):
Which sets TMUXPWD_i (where i is the number of the current window) to the path $ cat <<EOF|tic -x -
of the current directory. This command can be added to PS1, for example: tmux|tmux terminal multiplexer,
ritm=\E[23m, rmso=\E[27m, sitm=\E[3m, smso=\E[7m, Ms@,
use=xterm+tmux, use=screen,
PS1='$([ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#I") $PWD)\h$ ' tmux-256color|tmux with 256 colors,
use=xterm+256setaf, use=tmux,
When a new window is created, the shell should be asked to change EOF
directory. You can define a new binding (for example, if using GNU bash): $
bind-key C-c run-shell 'tmux neww "cd $(tmux display -p "\$TMUXPWD_#I"); exec bash"'
This solution will work even if a command is currently running in the terminal,
but it will not work from a window that has just been swapped with another
because TMUXPWD_i will not be updated after a swap. However, once a new prompt
is displayed, TMUXPWD_i is updated properly.
* tmux doesn't start with "daemon failed"
tmux shows something similar to this when started:
fatal: server_start: daemon failed: No such file or directory
fatal: main_dispatch: imsg_read failed
A possible reason is that /dev/null is not a character device or is otherwise
inaccessible.
Check with:
file /dev/null
ls -l /dev/null
If it is not a character device or has incorrect permissions, it can typically
be recreated with:
cd /dev && rm null && ./MAKEDEV null
* vim displays reverse video instead of italics, while less displays italics
(or just regular text) instead of reverse. What's wrong?
Screen's terminfo description lacks italics mode and has standout mode in its
place, but using the same escape sequence that urxvt uses for italics. This
means applications (like vim) looking for italics will not find it and might
turn to reverse in its place, while applications (like less) asking for
standout will end up with italics instead of reverse. To make applications
aware that tmux supports italics and to use a proper escape sequence for
standout, you'll need to create a new terminfo file with modified sgr, smso,
rmso, sitm and ritm entries:
$ mkdir $HOME/.terminfo/
$ screen_terminfo="screen"
$ infocmp "$screen_terminfo" | sed \
-e 's/^screen[^|]*|[^,]*,/screen-it|screen with italics support,/' \
-e 's/%?%p1%t;3%/%?%p1%t;7%/' \
-e 's/smso=[^,]*,/smso=\\E[7m,/' \
-e 's/rmso=[^,]*,/rmso=\\E[27m,/' \
-e '$s/$/ sitm=\\E[3m, ritm=\\E[23m,/' > /tmp/screen.terminfo
$ tic /tmp/screen.terminfo
And tell tmux to use it in ~/.tmux.conf: And tell tmux to use it in ~/.tmux.conf:
set -g default-terminal "screen-it" set -g default-terminal "tmux"
If your terminal supports 256 colors, use: If using urxvt, make sure you have an italics capable font enabled. for
example, add to ~/.Xdefaults:
$ screen_terminfo="screen-256color"
instead of "screen". See the FAQ entry about 256 colors support for more info.
Also note that tmux will still display reverse video on terminals that do not
support italics.
If your urxvt cannot display italics at all, make sure you have an italics
capable font enabled, for example, add to ~/.Xdefaults:
urxvt.italicFont: xft:Bitstream Vera Sans Mono:italic:autohint=true urxvt.italicFont: xft:Bitstream Vera Sans Mono:italic:autohint=true
@@ -422,7 +394,7 @@ always (or ever) be added to the scrollback.
You can make tmux use the normal screen by telling it that your terminal does You can make tmux use the normal screen by telling it that your terminal does
not have an alternate screen. Put the following in ~/.tmux.conf: not have an alternate screen. Put the following in ~/.tmux.conf:
set -g terminal-overrides 'xterm*:smcup@:rmcup@' set -ga terminal-overrides ',xterm*:smcup@:rmcup@'
Adjust if your $TERM does not start with xterm. Adjust if your $TERM does not start with xterm.
@@ -441,5 +413,50 @@ configuration file:
Or the default window options: Or the default window options:
$ tmux -Lfoo -f/dev/null start\; show -gw $ tmux -Lfoo -f/dev/null start\; show -gw
$Id$ * How do I copy a selection from tmux to the system's clipboard?
When running in xterm(1), tmux can automatically send copied text to the
clipboard. This is controlled by the set-clipboard option and also needs this
X resource to be set:
XTerm*disallowedWindowOps: 20,21,SetXprop
For rxvt-unicode (urxvt), there is an unofficial Perl extension here:
http://anti.teamidiot.de/static/nei/*/Code/urxvt/
Otherwise a key binding for copy mode using xclip (or xsel) works:
bind -temacs-copy C-y copy-pipe "xclip -i >/dev/null"
Or for inside and outside copy mode with the prefix key:
bind C-y run -b "tmux save-buffer - | xclip -i"
On OS X, look at the pbcopy(1) and pbpaste(1) commands.
* Why don't some commands work inside tmux on OS X?
Apple requires some undocumented, unsupported fiddling to allow commands that
interact with the GUI to work. Neither tmux itself nor most shells do this, so
an external program is required. This can be found here:
https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard
Affected commands may include say(1), pbcopy(1), pbpaste(1) and ssh(1).
* Why do I see dots around a session when I attach to it?
tmux limits the size of the window to the smallest attached session. If
it didn't do this then it would be impossible to see the entire window.
The dots mark the size of the window tmux can display.
To avoid this, detach all other clients when attaching:
$ tmux attach -d
Or from inside tmux by detaching individual clients with C-b D or all
using:
C-b : attach -d

1
ISSUE_TEMPLATE Normal file
View File

@@ -0,0 +1 @@
Please read https://raw.githubusercontent.com/tmux/tmux/master/CONTRIBUTING

View File

@@ -1,94 +1,92 @@
# $Id$ # Makefile.am
# Obvious program stuff. # Obvious program stuff.
bin_PROGRAMS = tmux bin_PROGRAMS = tmux
dist_man1_MANS = tmux.1 CLEANFILES = tmux.1.mdoc tmux.1.man
# Distribution tarball options. # Distribution tarball options.
EXTRA_DIST = \ EXTRA_DIST = \
CHANGES FAQ NOTES TODO examples compat \ CHANGES FAQ README TODO COPYING example_tmux.conf compat/*.[ch] \
array.h compat.h tmux.h osdep-*.c osdep-*.c mdoc2man.awk tmux.1
dist-hook: dist-hook:
grep "^#found_debug=" configure grep "^#enable_debug=" configure
find $(distdir) -name .svn -type d|xargs rm -Rf
# Preprocessor flags. # Preprocessor flags.
CPPFLAGS += @XOPEN_DEFINES@ AM_CPPFLAGS += @XOPEN_DEFINES@ -DTMUX_CONF="\"$(sysconfdir)/tmux.conf\""
# glibc as usual does things ass-backwards and hides useful things by default, # Additional object files.
# so everyone has to add this. LDADD = $(LIBOBJS)
if IS_GLIBC
CFLAGS += -D_GNU_SOURCE
endif
# Set flags for gcc. gcc4 whines abouts silly stuff so it needs slightly # Set flags for gcc.
# different flags.
if IS_GCC if IS_GCC
CFLAGS += -std=c99 AM_CFLAGS += -std=gnu99 -O2
if IS_DEBUG if IS_DEBUG
CFLAGS += -g -ggdb -O0 AM_CFLAGS += -g
CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 AM_CFLAGS += -Wno-long-long -Wall -W -Wformat=2
CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations AM_CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare AM_CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align AM_CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align
CPPFLAGS += -DDEBUG AM_CFLAGS += -Wdeclaration-after-statement -Wno-pointer-sign -Wno-attributes
endif AM_CFLAGS += -Wno-unused-result
if IS_GCC4 AM_CPPFLAGS += -DDEBUG
CPPFLAGS += -iquote. -I/usr/local/include
if IS_DEBUG
CFLAGS += -Wno-pointer-sign
endif
else
CPPFLAGS += -I. -I- -I/usr/local/include
endif endif
AM_CPPFLAGS += -iquote.
endif endif
# Set flags for Solaris. # Set flags for Solaris.
if IS_SUNOS if IS_SUNOS
CPPFLAGS += -D_XPG4_2 -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS if IS_GCC
AM_CPPFLAGS += -D_XPG6
else
AM_CPPFLAGS += -D_XPG4_2
endif
endif endif
# Set flags for Sun CC. # Set flags for Sun CC.
if IS_SUNCC if IS_SUNCC
CFLAGS += -erroff=E_EMPTY_DECLARATION AM_CFLAGS += -erroff=E_EMPTY_DECLARATION
endif
# Set _LINUX_SOURCE_COMPAT for AIX for malloc(0).
if IS_AIX
AM_CPPFLAGS += -D_LINUX_SOURCE_COMPAT=1
endif
# Set flags for NetBSD.
if IS_NETBSD
AM_CPPFLAGS += -D_OPENBSD_SOURCE
endif endif
# List of sources. # List of sources.
dist_tmux_SOURCES = \ dist_tmux_SOURCES = \
alerts.c \
arguments.c \ arguments.c \
attributes.c \ attributes.c \
cfg.c \ cfg.c \
client.c \ client.c \
clock.c \
cmd-attach-session.c \ cmd-attach-session.c \
cmd-bind-key.c \ cmd-bind-key.c \
cmd-break-pane.c \ cmd-break-pane.c \
cmd-capture-pane.c \ cmd-capture-pane.c \
cmd-choose-buffer.c \ cmd-choose-buffer.c \
cmd-choose-client.c \ cmd-choose-client.c \
cmd-choose-list.c \
cmd-choose-tree.c \ cmd-choose-tree.c \
cmd-clear-history.c \
cmd-clock-mode.c \
cmd-command-prompt.c \ cmd-command-prompt.c \
cmd-confirm-before.c \ cmd-confirm-before.c \
cmd-copy-mode.c \ cmd-copy-mode.c \
cmd-delete-buffer.c \
cmd-detach-client.c \ cmd-detach-client.c \
cmd-display-message.c \ cmd-display-message.c \
cmd-display-panes.c \ cmd-display-panes.c \
cmd-find-window.c \ cmd-find-window.c \
cmd-has-session.c \ cmd-find.c \
cmd-if-shell.c \ cmd-if-shell.c \
cmd-join-pane.c \ cmd-join-pane.c \
cmd-kill-pane.c \ cmd-kill-pane.c \
cmd-kill-server.c \ cmd-kill-server.c \
cmd-kill-session.c \ cmd-kill-session.c \
cmd-kill-window.c \ cmd-kill-window.c \
cmd-link-window.c \
cmd-list-buffers.c \ cmd-list-buffers.c \
cmd-list-clients.c \ cmd-list-clients.c \
cmd-list-commands.c \
cmd-list-keys.c \ cmd-list-keys.c \
cmd-list-panes.c \ cmd-list-panes.c \
cmd-list-sessions.c \ cmd-list-sessions.c \
@@ -101,6 +99,7 @@ dist_tmux_SOURCES = \
cmd-new-window.c \ cmd-new-window.c \
cmd-paste-buffer.c \ cmd-paste-buffer.c \
cmd-pipe-pane.c \ cmd-pipe-pane.c \
cmd-queue.c \
cmd-refresh-client.c \ cmd-refresh-client.c \
cmd-rename-session.c \ cmd-rename-session.c \
cmd-rename-window.c \ cmd-rename-window.c \
@@ -114,34 +113,31 @@ dist_tmux_SOURCES = \
cmd-select-pane.c \ cmd-select-pane.c \
cmd-select-window.c \ cmd-select-window.c \
cmd-send-keys.c \ cmd-send-keys.c \
cmd-send-prefix.c \
cmd-server-info.c \
cmd-set-buffer.c \ cmd-set-buffer.c \
cmd-set-environment.c \ cmd-set-environment.c \
cmd-set-hook.c \
cmd-set-option.c \ cmd-set-option.c \
cmd-show-buffer.c \
cmd-show-environment.c \ cmd-show-environment.c \
cmd-show-messages.c \ cmd-show-messages.c \
cmd-show-options.c \ cmd-show-options.c \
cmd-source-file.c \ cmd-source-file.c \
cmd-split-window.c \ cmd-split-window.c \
cmd-start-server.c \
cmd-string.c \ cmd-string.c \
cmd-suspend-client.c \
cmd-swap-pane.c \ cmd-swap-pane.c \
cmd-swap-window.c \ cmd-swap-window.c \
cmd-switch-client.c \ cmd-switch-client.c \
cmd-unbind-key.c \ cmd-unbind-key.c \
cmd-unlink-window.c \ cmd-wait-for.c \
cmd.c \ cmd.c \
colour.c \ colour.c \
control.c \ compat.h \
control-notify.c \ control-notify.c \
control.c \
environ.c \ environ.c \
format.c \ format.c \
grid-utf8.c \
grid-view.c \ grid-view.c \
grid.c \ grid.c \
hooks.c \
input-keys.c \ input-keys.c \
input.c \ input.c \
job.c \ job.c \
@@ -151,24 +147,26 @@ dist_tmux_SOURCES = \
layout-set.c \ layout-set.c \
layout.c \ layout.c \
log.c \ log.c \
mode-key.c \
names.c \ names.c \
notify.c \ notify.c \
options-table.c \ options-table.c \
options.c \ options.c \
paste.c \ paste.c \
proc.c \
pty.c \
resize.c \ resize.c \
screen-redraw.c \ screen-redraw.c \
screen-write.c \ screen-write.c \
screen.c \ screen.c \
server-client.c \ server-client.c \
server-fn.c \ server-fn.c \
server-window.c \
server.c \ server.c \
session.c \ session.c \
signal.c \ signal.c \
status.c \ status.c \
style.c \
tmux.c \ tmux.c \
tmux.h \
tty-acs.c \ tty-acs.c \
tty-keys.c \ tty-keys.c \
tty-term.c \ tty-term.c \
@@ -179,67 +177,29 @@ dist_tmux_SOURCES = \
window-copy.c \ window-copy.c \
window.c \ window.c \
xmalloc.c \ xmalloc.c \
xmalloc.h \
xterm-keys.c xterm-keys.c
nodist_tmux_SOURCES = osdep-@PLATFORM@.c nodist_tmux_SOURCES = osdep-@PLATFORM@.c
# Pile in all the compat/ stuff that is needed. # Add compat file for forkpty.
if NO_FORKPTY if NEED_FORKPTY
nodist_tmux_SOURCES += compat/forkpty-@PLATFORM@.c nodist_tmux_SOURCES += compat/forkpty-@PLATFORM@.c
endif endif
if NO_IMSG
nodist_tmux_SOURCES += compat/imsg.c compat/imsg-buffer.c # Add compat file for utf8proc.
endif if HAVE_UTF8PROC
if NO_CLOSEFROM nodist_tmux_SOURCES += compat/utf8proc.c
nodist_tmux_SOURCES += compat/closefrom.c
endif
if NO_DAEMON
nodist_tmux_SOURCES += compat/daemon.c
endif
if NO_SETENV
nodist_tmux_SOURCES += compat/setenv.c
endif
if NO_STRLCAT
nodist_tmux_SOURCES += compat/strlcat.c
endif
if NO_STRLCPY
nodist_tmux_SOURCES += compat/strlcpy.c
endif
if NO_ASPRINTF
nodist_tmux_SOURCES += compat/asprintf.c
endif
if NO_FGETLN
nodist_tmux_SOURCES += compat/fgetln.c
endif
if NO_GETOPT
nodist_tmux_SOURCES += compat/getopt.c
endif
if NO_STRCASESTR
nodist_tmux_SOURCES += compat/strcasestr.c
endif
if NO_STRSEP
nodist_tmux_SOURCES += compat/strsep.c
endif
if NO_VIS
nodist_tmux_SOURCES += compat/vis.c compat/unvis.c
endif
if NO_STRTONUM
nodist_tmux_SOURCES += compat/strtonum.c
endif
if NO_B64_NTOP
nodist_tmux_SOURCES += compat/b64_ntop.c
endif endif
# Update SF web site. # Install tmux.1 in the right format.
upload-index.html: update-index.html install-exec-hook:
scp www/index.html www/main.css www/images/*.png \ if test x@MANFORMAT@ = xmdoc; then \
${USER},tmux@web.sf.net:/home/groups/t/tm/tmux/htdocs sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1 \
rm -f www/index.html www/images/small-* >$(srcdir)/tmux.1.mdoc; \
else \
update-index.html: sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1| \
(cd www/images && \ $(AWK) -f$(srcdir)/mdoc2man.awk >$(srcdir)/tmux.1.man; \
rm -f small-* && \ fi
for i in *.png; do \ $(mkdir_p) $(DESTDIR)$(mandir)/man1
convert "$$i" -resize 200x150 "small-$$i"; \ $(INSTALL_DATA) $(srcdir)/tmux.1.@MANFORMAT@ \
done \ $(DESTDIR)$(mandir)/man1/tmux.1
)
sed "s/%%VERSION%%/${VERSION}/g" www/index.html.in >www/index.html

72
NOTES
View File

@@ -1,72 +0,0 @@
Welcome to tmux!
tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen.
This release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they haven't been tested in a while).
Since the 1.2 release tmux depends on libevent. Download it from:
http://www.monkey.org/~provos/libevent/
To build tmux from a release tarball, do:
$ ./configure && make
$ sudo make install
To get and build the latest version control checkout:
$ git clone git://tmux.git.sourceforge.net/gitroot/tmux/tmux
$ cd tmux
$ sh autogen.sh
$ ./configure && make
For more information see https://sourceforge.net/scm/?type=git&group_id=200378
and http://git-scm.com.
For documentation on using tmux, see the tmux.1 manpage. It can be viewed from
the source tree with:
$ nroff -mdoc tmux.1|less
Some common questions are answered in the FAQ file and a more extensive (but
slightly out of date) guide is available in the OpenBSD FAQ at
http://www.openbsd.org/faq/faq7.html#tmux. A rough todo list is in the TODO
file.
A Vim syntax file is available in the examples directory. To install it:
- Drop the file in the syntax directory into runtimepath (such as
~/.vim/syntax/tmux.vim).
- Make the filetype recognisable by adding the following to filetype.vim
(~/.vim/filetype.vim):
augroup filetypedetect
au BufNewFile,BufRead .tmux.conf*,tmux.conf* setf tmux
augroup END
- Switch on syntax highlighting by adding "syntax enable" to .vimrc.
For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory.
tmux mailing lists are available. The visit:
https://sourceforge.net/mail/?group_id=200378
Bug reports, feature suggestions and especially code contributions are most
welcome. Please send by email to:
tmux-users@lists.sourceforge.net
This file and the CHANGES, FAQ and TODO files are licensed under the ISC
license. Files under examples/ remain copyright their authors unless otherwise
stated in the file but permission has been received to distribute them with
tmux. All other files have a license and copyright notice at their
start.
-- Nicholas Marriott <nicm@users.sf.net>
$Id$

73
README Normal file
View File

@@ -0,0 +1,73 @@
Welcome to tmux!
tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen.
This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris.
tmux depends on libevent 2.x. Download it from:
http://libevent.org
It also depends on ncurses, available from:
http://invisible-island.net/ncurses/
To build and install tmux from a release tarball, use:
$ ./configure && make
$ sudo make install
tmux can use the utempter library to update utmp(5), if it is installed - run
configure with --enable-utempter to enable this.
To get and build the latest from version control:
$ git clone https://github.com/tmux/tmux.git
$ cd tmux
$ sh autogen.sh
$ ./configure && make
For more information see http://git-scm.com. Patches should be sent by email to
the mailing list at tmux-users@googlegroups.com.
For documentation on using tmux, see the tmux.1 manpage. It can be viewed from
the source tree with:
$ nroff -mdoc tmux.1|less
Some common questions are answered in the FAQ file, a rough todo list is in the
TODO file and an example configuration in example_tmux.conf.
A vim(1) syntax file is available at:
https://github.com/ericpruitt/tmux.vim
https://raw.githubusercontent.com/ericpruitt/tmux.vim/master/vim/syntax/tmux.vim
And a bash(1) completion file at:
https://github.com/imomaliev/tmux-bash-completion
For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory.
tmux mailing lists are available. For general discussion and bug reports:
https://groups.google.com/forum/#!forum/tmux-users
And for Git commit emails:
https://groups.google.com/forum/#!forum/tmux-git
Subscribe by sending an email to <tmux-users+subscribe@googlegroups.com>.
Bug reports, feature suggestions and especially code contributions are most
welcome. Please send by email to:
tmux-users@googlegroups.com
This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under the
ISC license. All other files have a license and copyright notice at their start.
-- Nicholas Marriott <nicholas.marriott@gmail.com>

89
SYNCING
View File

@@ -1,7 +1,7 @@
Preamble Preamble
======== ========
Tmux on SourceForge has two git repositories [1] "tmux" and "tmux-openbsd". Tmux portable relies on repositories "tmux" and "tmux-openbsd".
Here's a description of them: Here's a description of them:
* "tmux" is the portable version, the one which contains code for other * "tmux" is the portable version, the one which contains code for other
@@ -13,10 +13,9 @@ Here's a description of them:
Note: The "tmux-openbsd" repository is actually handled by "git cvsimport" Note: The "tmux-openbsd" repository is actually handled by "git cvsimport"
running at 15 minute intervals, so a commit made to OpenBSD's tmux CVS running at 15 minute intervals, so a commit made to OpenBSD's tmux CVS
repository will take that long to appear in this git repository. repository will take at least that long to appear in this git repository.
(It might take longer, depending on the CVS mirror used to import the
It is assumed that the person doing the sync has read/write access to the OpenBSD code).
tmux repository on SourceForge already.
If you've never used git before, git tracks meta-data about the committer If you've never used git before, git tracks meta-data about the committer
and the author, as part of a commit, hence: and the author, as part of a commit, hence:
@@ -38,23 +37,23 @@ Cloning repositories
This involves having both tmux and tmux-openbsd cloned, as in: This involves having both tmux and tmux-openbsd cloned, as in:
% cd /some/where/useful % cd /some/where/useful
% git clone ssh://${USER}@tmux.git.sf.net/gitroot/tmux/tmux % git clone https://github.com/tmux/tmux.git
% git clone ssh://${USER}@tmux.git.sf.net/gitroot/tmux/tmux-openbsd % git clone https://github.com/ThomasAdam/tmux-openbsd.git
Note that you do not need additoinal checkouts to manage the sync -- an Note that you do not need additional checkouts to manage the sync -- an
existing clone of either repositories will suffice. So if you already have existing clone of either repositories will suffice. So if you already have
these checkouts existing, skip that. these checkouts existing, skip that.
Adding in git-remotes Adding in git-remotes
===================== =====================
Because the portable "tmux" git repository and the "tmux-openbsd" repository do Because the portable "tmux" git repository and the "tmux-openbsd"
not inherently share any history between each other, the history has been repository do not inherently share any history between each other, the
faked between them. This "faking of history" is something which has to be history has been faked between them. This "faking of history" is something
told to git for the purposes of comparing the "tmux" and "tmux-openbsd" which has to be told to git for the purposes of comparing the "tmux" and
repositories for syncing. To do this, we must reference the clone of the "tmux-openbsd" repositories for syncing. To do this, we must reference the
"tmux-openbsd" repository from the "tmux" repository, as shown by the clone of the "tmux-openbsd" repository from the "tmux" repository, as
following command: shown by the following command:
% cd /path/to/tmux % cd /path/to/tmux
% git remote add obsd-tmux file:///path/to/tmux-openbsd % git remote add obsd-tmux file:///path/to/tmux-openbsd
@@ -83,8 +82,8 @@ Then back in "tmux":
Creating the necessary branches Creating the necessary branches
=============================== ===============================
Now that "tmux" can see commits and branches from "tmux-openbsd" by way of Now that "tmux" can see commits and branches from "tmux-openbsd" by way
the remote name "obsd-tmux", we can now create the master branch from of the remote name "obsd-tmux", we can now create the master branch from
"tmux-openbsd" in the "tmux" repository: "tmux-openbsd" in the "tmux" repository:
% git checkout -b obsd-master obsd-tmux/master % git checkout -b obsd-master obsd-tmux/master
@@ -92,10 +91,10 @@ the remote name "obsd-tmux", we can now create the master branch from
Adding in the fake history points Adding in the fake history points
================================= =================================
To tie both the "master" branch from "tmux" and the "obsd-master" branch To tie both the "master" branch from "tmux" and the "obsd-master"
from "tmux-openbsd" together, the fake history points added to the "tmux" branch from "tmux-openbsd" together, the fake history points added to the
repository need to be added. To do this, we must add an additional refspec "tmux" repository need to be added. To do this, we must add an
line, as in: additional refspec line, as in:
% cd /path/to/tmux % cd /path/to/tmux
% git config --add remote.origin.fetch '+refs/replace/*:refs/replace/*' % git config --add remote.origin.fetch '+refs/replace/*:refs/replace/*'
@@ -108,8 +107,7 @@ Make sure the "master" branch is checked out:
% git checkout master % git checkout master
The following will show commits on OpenBSD not yet synched with tmux The following will show commits on OpenBSD not yet synched with "tmux":
portable:
% git log master..obsd-master % git log master..obsd-master
@@ -117,7 +115,7 @@ From there, merge the result in, fixing up any conflicts which might arise.
% git merge obsd-master % git merge obsd-master
Then ensure things look correct by BULDING the result of that sync: Then ensure things look correct by BUILDING the result of that sync:
% make clean && ./autogen.sh && ./configure && make % make clean && ./autogen.sh && ./configure && make
@@ -130,44 +128,49 @@ And if happy:
% git push origin master % git push origin master
Keeping an eye on libutil in OpenBSD
====================================
A lot of the compat/ code in tmux comes from libutil, especially imsg.
Sometimes the API can change, etc., which might cause interesting problems
trying to run the portable version of tmux. It's worth checking
periodically for any changes to libutil in OpenBSD and syncing those files
to compat/ as and when appropriate.
Release tmux for next version Release tmux for next version
============================= =============================
1. Comment the "found_debug=yes" line in configure.ac, since releases 1. Comment the "enable_debug=yes" line in configure.ac, since releases
don't have debugging enabled, otherwise make(1) aborts when don't have debugging enabled, otherwise make(1) aborts when
preparing the distribution. preparing the distribution.
2. Update and commit NOTES and CHANGES. The former should be checked for 2. Update and commit README and CHANGES. The former should be checked for
anything outdated and updated with a list of things that might break anything outdated and updated with a list of things that might break
upgrades and the latter should mention all the major changes since upgrades and the latter should mention all the major changes since
the last version. the last version.
3. Tag with: 3. Tag with:
% git tag -a 1.X % git tag -a 2.X
Where "1.X" is the next version. Where "2.X" is the next version.
Push the tag out with: Push the tag out with:
% git push --tags % git push 2.X
4. Build the tarball with make dist. Now that it's using autoconf there 4. Build the tarball with 'make dist'.
shouldn't be any weird files (such as the original and rejection files
from patch(1)) but it doesn't hurt taking a quick look at it.
5. Split the release changes into a new file. This should be named 5. Check the tarball. If it's good, go here to select the tag just pushed:
tmux-$VERSION-readme to make sourceforge show it automagically in specific
parts of the project page.
6. Upload the tarball and the above file. Make the tarball the default https://github.com/tmux/tmux/tags
download by selecting all operating systems under the file details.
7. Run make update-index.html upload-index.html to replace %%VERSION%%. Click the "Add release notes", upload the tarball and add a link in the
description field to the CHANGES file.
8. Bump version in configure.ac and uncomment "found_debug=yes" to create 7. Clone the tmux.github.io repository, and change the RELEASE version in
a debug build by default. the Makefile. Commit it, and run 'make' to replace %%VERSION%%. Push
the result out.
9. Update freshmeat. 8. Bump version in tmux/tmux.git configure.ac and uncomment "enable_debug=yes" to
create a debug build by default.
[1] http://tmux.git.sourceforge.net/git/gitweb-index.cgi

276
TODO
View File

@@ -1,170 +1,122 @@
NOTES - command bits and pieces:
===== * allow multiple targets: fnmatch for -t/-c, for example detach all
clients with -t*
* add -c for new-session like new-window
* ' and " should be parsed the same (eg "\e" vs '\e') in config
and command prompt
* last-pane across sessions
* resize-pane -p to match split-window -p
* flag to wait-for to have a timeout and/or to stop waiting when the
client gets a signal
This file describes rough notes regarding ideas for potential future tmux - make command sequences more usable
development. It's not necessarily guaranteed that items in this TODO file * don't require space after ;
will ever get implemented. * options for error handling: && and ||?
It is asked therefore, that anyone thinking of undertaking a task in this - options bits and pieces:
TODO file, email tmux-users@lists.sf.net to discuss the feature. * way to set socket path from config file
Thie file is split up between tmux user interface (UI) issues, and terminal - format improvements:
compatibility issues. * option to quote format (#{q:session_name})
* some way to pad # stuff with spaces
* formats to show if a window is linked into multiple sessions, into
multiple attached sessions, and is the active window in multiple
attached sessions?
TMUX UI ISSUES - choose mode improvements:
============== * choose-pane command (augment choose-tree to do this?)
* flag to choose-* for sort order
* two choices (first one then second, for swap-pane and join-pane)
* choose modes should ditch the key bindings and just have fixed keys, and
be more customized to their purpose (d to delete a buffer for choose-buffer,
a preview of buffer contents, etc)
- improve monitor-*:
* straighten out rules for multiple clients
* think about what happens across sessions
* monitor changes within a region
* perhaps monitor /all/ panes in the window not just one
- improve mouse support:
* bind commands to mouse in different areas?
* commands executed when clicking on a pattern (URL)
- implicitly add exec to the commands for new windows (switch to disable it)?
- bring back detach-session to detach all clients on a session?
- allow fnmatch for -c, so that you can, eg, detach all clients
- garbage collect window history (100 lines at a time?) if it hasn't been used
in $x time
- flags to centre screen in window
- activity/bell should be per-window not per-link? what if it is cur win in
session not being watched?
- should be able to move to a hidden pane and it would be moved into view. pane
number in status line/top-right would be cool for this
- support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically?
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- make command sequences more usable: don't require space after ;, handle
errors better
- attach should have a flag to create session if it doesn't exist
- choice and more mode would be better per client than per window?
- hooks to which commands may be attached, for example: tmux add-hook
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
$HOME/.tmux-session.conf
- way to set socket path from config file
- what about utmp etc? can tmux update it like screen? setgid?
- warts on current naming: - warts on current naming:
- display-time but message-fg/bg/attr * display-time but message-fg/bg/attr
- list-* vs show-* * list-* vs show-*
- server-info
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-*
- split-window -> split-pane??
- a way for force-width/height to apply to only one pane (how?)
- command to list what is actually running in each window with command line,
pid (need some adaption of the osdep code)
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
-- idea of a "view" onto a window, need base x/y offsets for redraw
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- commands should be able to succeed or fail and have || or && for command
lists
- some way to KEEP a command running continually and just use its LAST line of
output
- UTF-8 to a non-UTF-8 terminal should not be able to balls up
the terminal - www/ruby-addressable; make regress
- support esc-esc to quit in modes
- fix ctrl+F1-F4 output. to what?
- better utf8 support: window names, prompt input, message display
- session history for client and last-session command
- option to change status line colour when current window is in a mode?
- option to move copy mode indicator into status line
- list-buffer/show-buffer should display UTF-8
- selection behaviour closer to vi in vi mode
- live update: server started with -U connects to server, requests sessions and
windows, receives fds
- sort out inheriting config from shell on new sessions/windows:
should pick up default-path/termios/etc from client if possible,
else leave empty/default
- link panes into multiple windows
- bells should be passed between sessions with visual-bell etc
sequence until its shell exits, to allow them to be used from the config file
- better session sharing: create-socket command to create socket somewhere (-r
flag for readonly)
- multiline status line (no?)
- flag for absolute pane size to resize-pane
- sanity check input to socket
- support title stack, both internally and externally
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
- command to show status line information briefly when it is off
- some way to pad # stuff with spaces, #!2T maybe
- a binding to "scroll down and exit at bottom" copy mode
- some way to pass keystrokes in copy mode through to underlying window
- last window update time and # replacement for it for display-message
- find-window across sessions - other ways to make session handling easier?
- ' and " should be parsed the same (eg "\e" vs '\e') in config and command
prompt?
- command to toggle selection not to move it in copy-mode
- audit of escape sequence support vs xterm
- support binding keys to mouse (mouse-select-pane -> mouse-keys or something,
mouse click == select-pane -t %%, mouse scroll up == copy-mode)
- something for -t "last window in session" so a session can be used as a stack
- synchronous commands - client sends cmd and blocks, neww/splitw saves client
ptr then when program inside died, sends MSG_SOMETHING with wait status to
client
- bind commands to key sequences? -- make it so ALL keys go through a table,
first an implicit table in which C-b is the only default binding to a
command that says "next key from $othertable" and so on. means -n can
go away as well
- monitor, bell etc should monitor /all/ panes in the window not just one
- a history of commands that can be reversed (reverse member of each command,
and a buffer) info() when changing to same window
- way to add dest for break-pane; maybe some easier way to unbreak-pane
- case insensitive searching
- configurable borders and empty space filler for when panes < window?
- mouse-select-pane will screw up with !MODE_MOUSE_STANDARD (it sets the
flag on w/o checking the others before calling tty_update_mode)
- multiple keys could be done with tables, ie have prefixes go and instead
bind -n ^A prefix-table "default"
where prefix-table sets command lookup table and sets prefix flag, then next
key is looked up in that table
- pass shell commands as argv rather than strings, allow them to be specified
in commands without quotes
- numeric prefix in copy mode should be paste buffer for C-w
- named buffers and allow gaps in the stack
- get rid of separate UTF-8 cell stuff: add 1 byte to cell and store BMP as
uint16_t+3 bits of flags. anything <=0xffff is Unicode, higher are used to
build tree of combined characters/non-BMP (LRU dropped when full)
- entry in FAQ about what to do when someone does mkdir /tmp/tmux-1000
- monitor-activity is broken in several ways with multiple clients
- monitor-activity should be more powerful (eg set a region)
- maybe a way to put pane names instead of window names in status line
- support for borderless panes
- run-shell/if-shell should support status_replace stuff
- wait-pane command or another way to make it synchronous/wait for command to
finish
- last-pane across sessions
- attach should take a pane and select it as well as attaching
- panes should have names like windows
- command-prompt doesn't work if made read-only. why?
- option to quote format eg #{session_name:quoted}
- formats need conditions for >0 (for #P)
- fetch full command line on !Linux, and add option to strip prefixes
such as "sh " "/bin/sh " etc etc
- synchronize-windows option
- append to buffer in copy mode
- way to paste w/o trailing whitespace
- flag to switch-client to switch all clients
- history of layouts and undo/redo flags to selectl
- way to tag a layout as a number/name
- optimize pane redraws, 20120318184853.GK10965@yelena.nicm.ath.cx
- support multibyte key strings
- allow commands to be executed when certaing patterns in a screen
are clicked on with the mouse
- flag to make next/previous commands skip a window
- way to do tmux command/run-shell from mode keys
- send command to all windows
- choose-pane command
- Augment choose-tree to do this? TA to investigate.
- choose-mode and copy-mode are very similar. Perhaps make choose-mode a
subset of copy-mode in that it inherits key-bindings and other traits but
not all.
TERMINAL ISSUES - copy/paste improvements:
================ * paste w/o trailing whitespace
* command to toggle selection not to move it in copy-mode
* regex searching
* searching in copy mode should unwrap lines, so if you search for "foobar"
then it should be found even if it is now "foo\nbar" (if the WRAP flag
is set on the line)
* capture-pane option to preserve spaces but not join lines
* improve word and line selection in copy mode (for example when dragging
it should select by word. compare how xterm works. GitHub issue 682)
- use a better termcap internally instead of screen, perhaps xterm - layout stuff
- clear window title on exit (see using xterm title stack) * way to tag a layout as a number/name
- get it passing all the vttest tests that don't require resizing the terminal * maybe keep last layout + size around and if size reverts just put it
- support for bce back
- use screen-256color when started on 256 colour terminal?? * revamp layouts: they are too complicated, should be more closely
- if-shell/run-shell should block further command execution in the same command integrated, should support hints, layout sets should just be a
- possibly support rxvt-unicode extended mouse input (1015) special case of custom layouts, and we should support panes that are
- wrap/no wrap esc seq DEC CSI ? 7 h/l not attached to a cell at all. this could be the time to introduce
* We need a tmux terminfo entry to document the extensions we are using in panelink to replace layout_cell
upstream terminfo. Must NOT change (only add or remove) anything from * way to set hints/limits about pane size for resizing
TERM=screen so we can fallback! * panning over window (window larger than visible)
* a mode where one application can cross two panes (ie x|y, width =
COLUMNS/2 but height = ROWS * 2)
* separate active panes for different clients
- code cleanup
* instead of separate window and session options, just one master
options list with each option having a type (window or session), then
options on window, on session, and global. for window options we look
window->session->global, and for session we look session->global.
problem: what about windows in multiple sessions? there are contexts
where we do not know which session, or where multiple choices makes
no sense... could at least have one global list for all types of
global options and keep separate window,session lists
* the way pane, window, session destroy is handled is too complicated
and the distinction between session.c, window.c and server-fn.c
functions is not clear. could we just have kill_pane(),
kill_window(), unlink_window(), kill_session() that fix up all data
structures (flagging sessions as dead) and return a value to say
whether clients need to be checked for dead sessions? sort of like
session_detach now but more so. or some other scheme to make it
simpler and clearer? also would be nice to remove/rename server-fn.c
* more readable way to work out the various things commands need to
know about the client, notably:
- is this the config file? (cmdq->c == NULL)
- is this a command client? (cmdq->c != NULL &&
cmdq->c->session == NULL)
- is this a control client?
- can i do stdin or stdout to this client?
or even guarantee that cmdq->c != NULL and provide a better way to
tell when in the config file - then we use cmdq->c if we need a
client w/o a session else cmd_current_client
- miscellaneous
* way to keep a job running just read its last line of output for #()
* link panes into multiple windows
* live update: server started with -U connects to server, requests
sessions and windows, receives file descriptors
* there are inconsistencies in what we get from old shell and what
comes from config for new sessions and windows. likewise, panes and
jobs and run-shell and lock command all start with slightly different
environments
* multiline status line? separate command prompt and status line?
* automatic pane logging
* marks in history, automatically add (move?) one when pane is changed
* this doesn't work, need pane reference count probably:
bind -n DoubleClick3Status confirm-before -p "kill-window #I? (y/n)" kill-window
- hooks
* more hooks for various things
* finish after hooks for special commands
* multiple hooks with the same name?
* finish hooks for notifys
* for session_closed, if no sessions at all, perhaps fake up a temporary one

322
alerts.c Normal file
View File

@@ -0,0 +1,322 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <event.h>
#include <stdlib.h>
#include "tmux.h"
static int alerts_fired;
static void alerts_timer(int, short, void *);
static int alerts_enabled(struct window *, int);
static void alerts_callback(int, short, void *);
static void alerts_reset(struct window *);
static int alerts_check_all(struct window *);
static int alerts_check_bell(struct window *);
static int alerts_check_activity(struct window *);
static int alerts_check_silence(struct window *);
static void printflike(2, 3) alerts_set_message(struct session *, const char *,
...);
static void alerts_ring_bell(struct session *);
static TAILQ_HEAD(, window) alerts_list = TAILQ_HEAD_INITIALIZER(alerts_list);
static void
alerts_timer(__unused int fd, __unused short events, void *arg)
{
struct window *w = arg;
log_debug("@%u alerts timer expired", w->id);
alerts_reset(w);
alerts_queue(w, WINDOW_SILENCE);
}
static void
alerts_callback(__unused int fd, __unused short events, __unused void *arg)
{
struct window *w, *w1;
int alerts;
TAILQ_FOREACH_SAFE(w, &alerts_list, alerts_entry, w1) {
alerts = alerts_check_all(w);
log_debug("@%u alerts check, alerts %#x", w->id, alerts);
w->alerts_queued = 0;
TAILQ_REMOVE(&alerts_list, w, alerts_entry);
w->flags &= ~WINDOW_ALERTFLAGS;
window_remove_ref(w);
}
alerts_fired = 0;
}
static int
alerts_check_all(struct window *w)
{
int alerts;
alerts = alerts_check_bell(w);
alerts |= alerts_check_activity(w);
alerts |= alerts_check_silence(w);
return (alerts);
}
void
alerts_check_session(struct session *s)
{
struct winlink *wl;
RB_FOREACH(wl, winlinks, &s->windows)
alerts_check_all(wl->window);
}
static int
alerts_enabled(struct window *w, int flags)
{
if (flags & WINDOW_BELL)
return (1);
if (flags & WINDOW_ACTIVITY) {
if (options_get_number(w->options, "monitor-activity"))
return (1);
}
if (flags & WINDOW_SILENCE) {
if (options_get_number(w->options, "monitor-silence") != 0)
return (1);
}
return (0);
}
void
alerts_reset_all(void)
{
struct window *w;
RB_FOREACH(w, windows, &windows)
alerts_reset(w);
}
static void
alerts_reset(struct window *w)
{
struct timeval tv;
w->flags &= ~WINDOW_SILENCE;
event_del(&w->alerts_timer);
timerclear(&tv);
tv.tv_sec = options_get_number(w->options, "monitor-silence");
log_debug("@%u alerts timer reset %u", w->id, (u_int)tv.tv_sec);
if (tv.tv_sec != 0)
event_add(&w->alerts_timer, &tv);
}
void
alerts_queue(struct window *w, int flags)
{
if (w->flags & WINDOW_ACTIVITY)
alerts_reset(w);
if (!event_initialized(&w->alerts_timer))
evtimer_set(&w->alerts_timer, alerts_timer, w);
if ((w->flags & flags) != flags) {
w->flags |= flags;
log_debug("@%u alerts flags added %#x", w->id, flags);
}
if (!w->alerts_queued) {
w->alerts_queued = 1;
TAILQ_INSERT_TAIL(&alerts_list, w, alerts_entry);
w->references++;
}
if (!alerts_fired && alerts_enabled(w, flags)) {
log_debug("alerts check queued (by @%u)", w->id);
event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL);
alerts_fired = 1;
}
}
static int
alerts_check_bell(struct window *w)
{
struct window *ws;
struct winlink *wl;
struct session *s;
struct client *c;
int action, visual;
if (~w->flags & WINDOW_BELL)
return (0);
TAILQ_FOREACH(wl, &w->winlinks, wentry)
wl->session->flags &= ~SESSION_ALERTED;
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
if (wl->flags & WINLINK_BELL)
continue;
s = wl->session;
if (s->curw != wl) {
wl->flags |= WINLINK_BELL;
notify_winlink("alert-bell", s, wl);
}
if (s->flags & SESSION_ALERTED)
continue;
s->flags |= SESSION_ALERTED;
action = options_get_number(s->options, "bell-action");
if (action == BELL_NONE)
return (0);
visual = options_get_number(s->options, "visual-bell");
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s || c->flags & CLIENT_CONTROL)
continue;
ws = c->session->curw->window;
if (action == BELL_CURRENT && ws != w)
action = BELL_NONE;
if (action == BELL_OTHER && ws != w)
action = BELL_NONE;
if (!visual) {
if (action != BELL_NONE)
tty_putcode(&c->tty, TTYC_BEL);
continue;
}
if (action == BELL_CURRENT)
status_message_set(c, "Bell in current window");
else if (action != BELL_NONE) {
status_message_set(c, "Bell in window %d",
wl->idx);
}
}
}
return (WINDOW_BELL);
}
static int
alerts_check_activity(struct window *w)
{
struct winlink *wl;
struct session *s;
if (~w->flags & WINDOW_ACTIVITY)
return (0);
if (!options_get_number(w->options, "monitor-activity"))
return (0);
TAILQ_FOREACH(wl, &w->winlinks, wentry)
wl->session->flags &= ~SESSION_ALERTED;
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
if (wl->flags & WINLINK_ACTIVITY)
continue;
s = wl->session;
if (s->curw == wl)
continue;
wl->flags |= WINLINK_ACTIVITY;
notify_winlink("alert-activity", s, wl);
if (s->flags & SESSION_ALERTED)
continue;
s->flags |= SESSION_ALERTED;
if (options_get_number(s->options, "bell-on-alert"))
alerts_ring_bell(s);
if (options_get_number(s->options, "visual-activity"))
alerts_set_message(s, "Activity in window %d", wl->idx);
}
return (WINDOW_ACTIVITY);
}
static int
alerts_check_silence(struct window *w)
{
struct winlink *wl;
struct session *s;
if (~w->flags & WINDOW_SILENCE)
return (0);
if (!options_get_number(w->options, "monitor-silence"))
return (0);
TAILQ_FOREACH(wl, &w->winlinks, wentry)
wl->session->flags &= ~SESSION_ALERTED;
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
if (wl->flags & WINLINK_SILENCE)
continue;
s = wl->session;
if (s->curw == wl)
continue;
wl->flags |= WINLINK_SILENCE;
notify_winlink("alert-silence", s, wl);
if (s->flags & SESSION_ALERTED)
continue;
s->flags |= SESSION_ALERTED;
if (options_get_number(s->options, "bell-on-alert"))
alerts_ring_bell(s);
if (!options_get_number(s->options, "visual-silence"))
alerts_set_message(s, "Silence in window %d", wl->idx);
}
return (WINDOW_SILENCE);
}
static void
alerts_set_message(struct session *s, const char *fmt, ...)
{
struct client *c;
va_list ap;
char *message;
va_start(ap, fmt);
xvasprintf(&message, fmt, ap);
va_end(ap);
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == s)
status_message_set(c, "%s", message);
}
free(message);
}
static void
alerts_ring_bell(struct session *s)
{
struct client *c;
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == s && !(c->flags & CLIENT_CONTROL))
tty_putcode(&c->tty, TTYC_BEL);
}
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -20,33 +20,41 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
/* Create an arguments set with no flags. */ /*
struct args * * Manipulate command arguments.
args_create(int argc, ...) */
struct args_entry {
u_char flag;
char *value;
RB_ENTRY(args_entry) entry;
};
static void args_set(struct args *, u_char, const char *);
static struct args_entry *args_find(struct args *, u_char);
static int args_cmp(struct args_entry *, struct args_entry *);
RB_GENERATE_STATIC(args_tree, args_entry, entry, args_cmp);
/* Arguments tree comparison function. */
static int
args_cmp(struct args_entry *a1, struct args_entry *a2)
{ {
struct args *args; return (a1->flag - a2->flag);
va_list ap; }
int i;
args = xcalloc(1, sizeof *args); /* Find a flag in the arguments tree. */
if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL) static struct args_entry *
fatal("bit_alloc failed"); args_find(struct args *args, u_char ch)
{
struct args_entry entry;
args->argc = argc; entry.flag = ch;
if (argc == 0) return (RB_FIND(args_tree, &args->tree, &entry));
args->argv = NULL;
else
args->argv = xcalloc(argc, sizeof *args->argv);
va_start(ap, argc);
for (i = 0; i < argc; i++)
args->argv[i] = xstrdup(va_arg(ap, char *));
va_end(ap);
return (args);
} }
/* Parse an argv and argc into a new argument set. */ /* Parse an argv and argc into a new argument set. */
@@ -54,30 +62,21 @@ struct args *
args_parse(const char *template, int argc, char **argv) args_parse(const char *template, int argc, char **argv)
{ {
struct args *args; struct args *args;
char *ptr;
int opt; int opt;
args = xcalloc(1, sizeof *args); args = xcalloc(1, sizeof *args);
if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
fatal("bit_alloc failed");
optreset = 1; optreset = 1;
optind = 1; optind = 1;
while ((opt = getopt(argc, argv, template)) != -1) { while ((opt = getopt(argc, argv, template)) != -1) {
if (opt < 0 || opt >= SCHAR_MAX) if (opt < 0)
continue; continue;
if (opt == '?' || (ptr = strchr(template, opt)) == NULL) { if (opt == '?' || strchr(template, opt) == NULL) {
free(args->flags); args_free(args);
free(args);
return (NULL); return (NULL);
} }
args_set(args, opt, optarg);
bit_set(args->flags, opt);
if (ptr[1] == ':') {
free(args->values[opt]);
args->values[opt] = xstrdup(optarg);
}
} }
argc -= optind; argc -= optind;
argv += optind; argv += optind;
@@ -92,122 +91,155 @@ args_parse(const char *template, int argc, char **argv)
void void
args_free(struct args *args) args_free(struct args *args)
{ {
u_int i; struct args_entry *entry;
struct args_entry *entry1;
cmd_free_argv(args->argc, args->argv); cmd_free_argv(args->argc, args->argv);
for (i = 0; i < SCHAR_MAX; i++) RB_FOREACH_SAFE(entry, args_tree, &args->tree, entry1) {
free(args->values[i]); RB_REMOVE(args_tree, &args->tree, entry);
free(entry->value);
free(entry);
}
free(args->flags);
free(args); free(args);
} }
/* Print a set of arguments. */ /* Add to string. */
size_t static void printflike(3, 4)
args_print(struct args *args, char *buf, size_t len) args_print_add(char **buf, size_t *len, const char *fmt, ...)
{ {
size_t off; va_list ap;
int i; char *s;
const char *quotes; size_t slen;
/* There must be at least one byte at the start. */ va_start(ap, fmt);
if (len == 0) slen = xvasprintf(&s, fmt, ap);
return (0); va_end(ap);
off = 0;
*len += slen;
*buf = xrealloc(*buf, *len);
strlcat(*buf, s, *len);
free(s);
}
/* Print a set of arguments. */
char *
args_print(struct args *args)
{
size_t len;
char *buf, *escaped;
int i, flags;
struct args_entry *entry;
static const char quoted[] = " #\"';$";
len = 1;
buf = xcalloc(1, len);
/* Process the flags first. */ /* Process the flags first. */
buf[off++] = '-'; RB_FOREACH(entry, args_tree, &args->tree) {
for (i = 0; i < SCHAR_MAX; i++) { if (entry->value != NULL)
if (!bit_test(args->flags, i) || args->values[i] != NULL)
continue; continue;
if (off == len - 1) { if (*buf == '\0')
buf[off] = '\0'; args_print_add(&buf, &len, "-");
return (len); args_print_add(&buf, &len, "%c", entry->flag);
}
buf[off++] = i;
buf[off] = '\0';
} }
if (off == 1)
buf[--off] = '\0';
/* Then the flags with arguments. */ /* Then the flags with arguments. */
for (i = 0; i < SCHAR_MAX; i++) { RB_FOREACH(entry, args_tree, &args->tree) {
if (!bit_test(args->flags, i) || args->values[i] == NULL) if (entry->value == NULL)
continue; continue;
if (off >= len) { if (*buf != '\0')
/* snprintf will have zero terminated. */ args_print_add(&buf, &len, " -%c ", entry->flag);
return (len);
}
if (strchr(args->values[i], ' ') != NULL)
quotes = "\"";
else else
quotes = ""; args_print_add(&buf, &len, "-%c ", entry->flag);
off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
off != 0 ? " " : "", i, quotes, args->values[i], quotes); flags = VIS_OCTAL|VIS_TAB|VIS_NL;
if (entry->value[strcspn(entry->value, quoted)] != '\0')
flags |= VIS_DQ;
utf8_stravis(&escaped, entry->value, flags);
if (flags & VIS_DQ)
args_print_add(&buf, &len, "\"%s\"", escaped);
else
args_print_add(&buf, &len, "%s", escaped);
free(escaped);
} }
/* And finally the argument vector. */ /* And finally the argument vector. */
for (i = 0; i < args->argc; i++) { for (i = 0; i < args->argc; i++) {
if (off >= len) { if (*buf != '\0')
/* snprintf will have zero terminated. */ args_print_add(&buf, &len, " ");
return (len);
}
if (strchr(args->argv[i], ' ') != NULL) flags = VIS_OCTAL|VIS_TAB|VIS_NL;
quotes = "\""; if (args->argv[i][strcspn(args->argv[i], quoted)] != '\0')
flags |= VIS_DQ;
utf8_stravis(&escaped, args->argv[i], flags);
if (flags & VIS_DQ)
args_print_add(&buf, &len, "\"%s\"", escaped);
else else
quotes = ""; args_print_add(&buf, &len, "%s", escaped);
off += xsnprintf(buf + off, len - off, "%s%s%s%s", free(escaped);
off != 0 ? " " : "", quotes, args->argv[i], quotes);
} }
return (off); return (buf);
} }
/* Return if an argument is present. */ /* Return if an argument is present. */
int int
args_has(struct args *args, u_char ch) args_has(struct args *args, u_char ch)
{ {
return (bit_test(args->flags, ch)); return (args_find(args, ch) == NULL ? 0 : 1);
} }
/* Set argument value. */ /* Set argument value in the arguments tree. */
void static void
args_set(struct args *args, u_char ch, const char *value) args_set(struct args *args, u_char ch, const char *value)
{ {
free(args->values[ch]); struct args_entry *entry;
/* Replace existing argument. */
if ((entry = args_find(args, ch)) != NULL) {
free(entry->value);
entry->value = NULL;
} else {
entry = xcalloc(1, sizeof *entry);
entry->flag = ch;
RB_INSERT(args_tree, &args->tree, entry);
}
if (value != NULL) if (value != NULL)
args->values[ch] = xstrdup(value); entry->value = xstrdup(value);
else
args->values[ch] = NULL;
bit_set(args->flags, ch);
} }
/* Get argument value. Will be NULL if it isn't present. */ /* Get argument value. Will be NULL if it isn't present. */
const char * const char *
args_get(struct args *args, u_char ch) args_get(struct args *args, u_char ch)
{ {
return (args->values[ch]); struct args_entry *entry;
if ((entry = args_find(args, ch)) == NULL)
return (NULL);
return (entry->value);
} }
/* Convert an argument value to a number. */ /* Convert an argument value to a number. */
long long long long
args_strtonum(struct args *args, args_strtonum(struct args *args, u_char ch, long long minval, long long maxval,
u_char ch, long long minval, long long maxval, char **cause) char **cause)
{ {
const char *errstr; const char *errstr;
long long ll; long long ll;
struct args_entry *entry;
if (!args_has(args, ch)) { if ((entry = args_find(args, ch)) == NULL) {
*cause = xstrdup("missing"); *cause = xstrdup("missing");
return (0); return (0);
} }
ll = strtonum(args->values[ch], minval, maxval, &errstr); ll = strtonum(entry->value, minval, maxval, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
*cause = xstrdup(errstr); *cause = xstrdup(errstr);
return (0); return (0);

120
array.h
View File

@@ -1,120 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef ARRAY_H
#define ARRAY_H
#define ARRAY_INITIALIZER { NULL, 0, 0 }
#define ARRAY_DECL(n, c) \
struct n { \
c *list; \
u_int num; \
size_t space; \
}
#define ARRAY_ITEM(a, i) ((a)->list[i])
#define ARRAY_ITEMSIZE(a) (sizeof *(a)->list)
#define ARRAY_INITIALSPACE(a) (10 * ARRAY_ITEMSIZE(a))
#define ARRAY_ENSURE(a, n) do { \
if (UINT_MAX - (n) < (a)->num) \
fatalx("number too big"); \
if (SIZE_MAX / ((a)->num + (n)) < ARRAY_ITEMSIZE(a)) \
fatalx("size too big"); \
if ((a)->space == 0) { \
(a)->space = ARRAY_INITIALSPACE(a); \
(a)->list = xrealloc((a)->list, 1, (a)->space); \
} \
while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \
(a)->list = xrealloc((a)->list, 2, (a)->space); \
(a)->space *= 2; \
} \
} while (0)
#define ARRAY_EMPTY(a) (((void *) (a)) == NULL || (a)->num == 0)
#define ARRAY_LENGTH(a) ((a)->num)
#define ARRAY_DATA(a) ((a)->list)
#define ARRAY_FIRST(a) ARRAY_ITEM(a, 0)
#define ARRAY_LAST(a) ARRAY_ITEM(a, (a)->num - 1)
#define ARRAY_INIT(a) do { \
(a)->num = 0; \
(a)->list = NULL; \
(a)->space = 0; \
} while (0)
#define ARRAY_CLEAR(a) do { \
(a)->num = 0; \
} while (0)
#define ARRAY_SET(a, i, s) do { \
(a)->list[i] = s; \
} while (0)
#define ARRAY_ADD(a, s) do { \
ARRAY_ENSURE(a, 1); \
(a)->list[(a)->num] = s; \
(a)->num++; \
} while (0)
#define ARRAY_INSERT(a, i, s) do { \
ARRAY_ENSURE(a, 1); \
if ((i) < (a)->num) { \
memmove((a)->list + (i) + 1, (a)->list + (i), \
ARRAY_ITEMSIZE(a) * ((a)->num - (i))); \
} \
(a)->list[i] = s; \
(a)->num++; \
} while (0)
#define ARRAY_REMOVE(a, i) do { \
if ((i) < (a)->num - 1) { \
memmove((a)->list + (i), (a)->list + (i) + 1, \
ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \
} \
(a)->num--; \
if ((a)->num == 0) \
ARRAY_FREE(a); \
} while (0)
#define ARRAY_EXPAND(a, n) do { \
ARRAY_ENSURE(a, n); \
(a)->num += n; \
} while (0)
#define ARRAY_TRUNC(a, n) do { \
if ((a)->num > n) \
(a)->num -= n; \
else \
ARRAY_FREE(a); \
} while (0)
#define ARRAY_CONCAT(a, b) do { \
ARRAY_ENSURE(a, (b)->num); \
memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \
(a)->num += (b)->num; \
} while (0)
#define ARRAY_FREE(a) do { \
free((a)->list); \
ARRAY_INIT(a); \
} while (0)
#define ARRAY_FREEALL(a) do { \
ARRAY_FREE(a); \
free(a); \
} while (0)
#endif

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org> * Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -23,7 +23,7 @@
#include "tmux.h" #include "tmux.h"
const char * const char *
attributes_tostring(u_char attr) attributes_tostring(int attr)
{ {
static char buf[128]; static char buf[128];
size_t len; size_t len;
@@ -31,14 +31,15 @@ attributes_tostring(u_char attr)
if (attr == 0) if (attr == 0)
return ("none"); return ("none");
len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s", len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s%s",
attr & GRID_ATTR_BRIGHT ? "bright," : "", (attr & GRID_ATTR_BRIGHT) ? "bright," : "",
attr & GRID_ATTR_DIM ? "dim," : "", (attr & GRID_ATTR_DIM) ? "dim," : "",
attr & GRID_ATTR_UNDERSCORE ? "underscore," : "", (attr & GRID_ATTR_UNDERSCORE) ? "underscore," : "",
attr & GRID_ATTR_BLINK ? "blink," : "", (attr & GRID_ATTR_BLINK)? "blink," : "",
attr & GRID_ATTR_REVERSE ? "reverse," : "", (attr & GRID_ATTR_REVERSE) ? "reverse," : "",
attr & GRID_ATTR_HIDDEN ? "hidden," : "", (attr & GRID_ATTR_HIDDEN) ? "hidden," : "",
attr & GRID_ATTR_ITALICS ? "italics," : ""); (attr & GRID_ATTR_ITALICS) ? "italics," : "",
(attr & GRID_ATTR_STRIKETHROUGH) ? "strikethrough," : "");
if (len > 0) if (len > 0)
buf[len - 1] = '\0'; buf[len - 1] = '\0';
@@ -49,7 +50,7 @@ int
attributes_fromstring(const char *str) attributes_fromstring(const char *str)
{ {
const char delimiters[] = " ,|"; const char delimiters[] = " ,|";
u_char attr; int attr;
size_t end; size_t end;
if (*str == '\0' || strcspn(str, delimiters) == 0) if (*str == '\0' || strcspn(str, delimiters) == 0)
@@ -78,6 +79,8 @@ attributes_fromstring(const char *str)
attr |= GRID_ATTR_HIDDEN; attr |= GRID_ATTR_HIDDEN;
else if (end == 7 && strncasecmp(str, "italics", end) == 0) else if (end == 7 && strncasecmp(str, "italics", end) == 0)
attr |= GRID_ATTR_ITALICS; attr |= GRID_ATTR_ITALICS;
else if (end == 13 && strncasecmp(str, "strikethrough", end) == 0)
attr |= GRID_ATTR_STRIKETHROUGH;
else else
return (-1); return (-1);
str += end + strspn(str + end, delimiters); str += end + strspn(str + end, delimiters);

View File

@@ -1,8 +1,9 @@
#!/bin/sh #!/bin/sh
# $Id$
[ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.10 if [ "x$(uname)" = "xOpenBSD" ]; then
[ -z "$AUTOCONF_VERSION" ] && export AUTOCONF_VERSION=2.65 [ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.15
[ -z "$AUTOCONF_VERSION" ] && export AUTOCONF_VERSION=2.69
fi
die() die()
{ {

285
cfg.c
View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -17,159 +17,204 @@
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
/* static char *cfg_file;
* Config file parser. Pretty quick and simple, each line is parsed into a int cfg_finished;
* argv array and executed as a command. static char **cfg_causes;
*/ static u_int cfg_ncauses;
struct client *cfg_client;
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...); static enum cmd_retval
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); cfg_done(__unused struct cmdq_item *item, __unused void *data)
char *cfg_cause;
int cfg_finished;
struct causelist cfg_causes = ARRAY_INITIALIZER;
/* ARGSUSED */
void printflike2
cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
{ {
if (cfg_finished)
return (CMD_RETURN_NORMAL);
cfg_finished = 1;
if (!RB_EMPTY(&sessions))
cfg_show_causes(RB_MIN(sessions, &sessions));
if (cfg_client != NULL)
server_client_unref(cfg_client);
return (CMD_RETURN_NORMAL);
} }
/* ARGSUSED */ void
void printflike2 set_cfg_file(const char *path)
cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
{ {
va_list ap; free(cfg_file);
cfg_file = xstrdup(path);
va_start(ap, fmt);
xvasprintf(&cfg_cause, fmt, ap);
va_end(ap);
} }
void printflike2 void
cfg_add_cause(struct causelist *causes, const char *fmt, ...) start_cfg(void)
{ {
char *cause; const char *home;
va_list ap; int quiet = 0;
va_start(ap, fmt); cfg_client = TAILQ_FIRST(&clients);
xvasprintf(&cause, fmt, ap); if (cfg_client != NULL)
va_end(ap); cfg_client->references++;
ARRAY_ADD(causes, cause); load_cfg(TMUX_CONF, cfg_client, NULL, 1);
if (cfg_file == NULL && (home = find_home()) != NULL) {
xasprintf(&cfg_file, "%s/.tmux.conf", home);
quiet = 1;
}
if (cfg_file != NULL)
load_cfg(cfg_file, cfg_client, NULL, quiet);
cmdq_append(cfg_client, cmdq_get_callback(cfg_done, NULL));
} }
/*
* Load configuration file. Returns -1 for an error with a list of messages in
* causes. Note that causes must be initialised by the caller!
*/
int int
load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) load_cfg(const char *path, struct client *c, struct cmdq_item *item, int quiet)
{ {
FILE *f; FILE *f;
u_int n; const char delim[3] = { '\\', '\\', '\0' };
char *buf, *line, *cause; u_int found = 0;
size_t len; size_t line = 0;
struct cmd_list *cmdlist; char *buf, *cause1, *p, *q, *s;
struct cmd_ctx ctx; struct cmd_list *cmdlist;
enum cmd_retval retval; struct cmdq_item *new_item;
int condition = 0;
struct format_tree *ft;
log_debug("loading %s", path);
if ((f = fopen(path, "rb")) == NULL) { if ((f = fopen(path, "rb")) == NULL) {
cfg_add_cause(causes, "%s: %s", path, strerror(errno)); if (errno == ENOENT && quiet)
return (0);
cfg_add_cause("%s: %s", path, strerror(errno));
return (-1); return (-1);
} }
n = 0;
line = NULL; while ((buf = fparseln(f, NULL, &line, delim, 0)) != NULL) {
retval = CMD_RETURN_NORMAL; log_debug("%s: %s", path, buf);
while ((buf = fgetln(f, &len))) {
if (buf[len - 1] == '\n')
len--;
if (line != NULL) p = buf;
line = xrealloc(line, 1, strlen(line) + len + 1); while (isspace((u_char)*p))
else { p++;
line = xmalloc(len + 1); if (*p == '\0') {
*line = '\0';
}
/* Append buffer to line. strncat will terminate. */
strncat(line, buf, len);
n++;
/* Continuation: get next line? */
len = strlen(line);
if (len > 0 && line[len - 1] == '\\') {
line[len - 1] = '\0';
/* Ignore escaped backslash at EOL. */
if (len > 1 && line[len - 2] != '\\')
continue;
}
buf = line;
line = NULL;
if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
free(buf); free(buf);
if (cause == NULL)
continue;
cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
free(cause);
continue; continue;
} else }
q = p + strlen(p) - 1;
while (q != p && isspace((u_char)*q))
*q-- = '\0';
if (condition != 0 && strcmp(p, "%endif") == 0) {
condition = 0;
continue;
}
if (strncmp(p, "%if ", 4) == 0) {
if (condition != 0) {
cfg_add_cause("%s:%zu: nested %%if", path,
line);
continue;
}
ft = format_create(NULL, FORMAT_NONE, FORMAT_NOJOBS);
s = p + 3;
while (isspace((u_char)*s))
s++;
s = format_expand(ft, s);
if (*s != '\0' && (s[0] != '0' || s[1] != '\0'))
condition = 1;
else
condition = -1;
free(s);
format_free(ft);
continue;
}
if (condition == -1)
continue;
cmdlist = cmd_string_parse(p, path, line, &cause1);
if (cmdlist == NULL) {
free(buf); free(buf);
if (cause1 == NULL)
continue;
cfg_add_cause("%s:%zu: %s", path, line, cause1);
free(cause1);
continue;
}
free(buf);
if (cmdlist == NULL) if (cmdlist == NULL)
continue; continue;
cfg_cause = NULL; new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
if (item != NULL)
if (ctxin == NULL) { cmdq_insert_after(item, new_item);
ctx.msgdata = NULL; else
ctx.curclient = NULL; cmdq_append(c, new_item);
ctx.cmdclient = NULL;
} else {
ctx.msgdata = ctxin->msgdata;
ctx.curclient = ctxin->curclient;
ctx.cmdclient = ctxin->cmdclient;
}
ctx.error = cfg_error;
ctx.print = cfg_print;
ctx.info = cfg_print;
cfg_cause = NULL;
switch (cmd_list_exec(cmdlist, &ctx)) {
case CMD_RETURN_YIELD:
if (retval != CMD_RETURN_ATTACH)
retval = CMD_RETURN_YIELD;
break;
case CMD_RETURN_ATTACH:
retval = CMD_RETURN_ATTACH;
break;
case CMD_RETURN_ERROR:
case CMD_RETURN_NORMAL:
break;
}
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
if (cfg_cause != NULL) {
cfg_add_cause( found++;
causes, "%s: %d: %s", path, n, cfg_cause);
free(cfg_cause);
}
}
if (line != NULL) {
cfg_add_cause(causes,
"%s: %d: line continuation at end of file", path, n);
free(line);
} }
fclose(f); fclose(f);
return (retval); return (found);
}
void
cfg_add_cause(const char *fmt, ...)
{
va_list ap;
char *msg;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
cfg_ncauses++;
cfg_causes = xreallocarray(cfg_causes, cfg_ncauses, sizeof *cfg_causes);
cfg_causes[cfg_ncauses - 1] = msg;
}
void
cfg_print_causes(struct cmdq_item *item)
{
u_int i;
for (i = 0; i < cfg_ncauses; i++) {
cmdq_print(item, "%s", cfg_causes[i]);
free(cfg_causes[i]);
}
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
}
void
cfg_show_causes(struct session *s)
{
struct window_pane *wp;
u_int i;
if (s == NULL || cfg_ncauses == 0)
return;
wp = s->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < cfg_ncauses; i++) {
window_copy_add(wp, "%s", cfg_causes[i]);
free(cfg_causes[i]);
}
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
} }

847
client.c

File diff suppressed because it is too large Load Diff

159
clock.c
View File

@@ -1,159 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include <time.h>
#include "tmux.h"
const char clock_table[14][5][5] = {
{ { 1,1,1,1,1 }, /* 0 */
{ 1,0,0,0,1 },
{ 1,0,0,0,1 },
{ 1,0,0,0,1 },
{ 1,1,1,1,1 } },
{ { 0,0,0,0,1 }, /* 1 */
{ 0,0,0,0,1 },
{ 0,0,0,0,1 },
{ 0,0,0,0,1 },
{ 0,0,0,0,1 } },
{ { 1,1,1,1,1 }, /* 2 */
{ 0,0,0,0,1 },
{ 1,1,1,1,1 },
{ 1,0,0,0,0 },
{ 1,1,1,1,1 } },
{ { 1,1,1,1,1 }, /* 3 */
{ 0,0,0,0,1 },
{ 1,1,1,1,1 },
{ 0,0,0,0,1 },
{ 1,1,1,1,1 } },
{ { 1,0,0,0,1 }, /* 4 */
{ 1,0,0,0,1 },
{ 1,1,1,1,1 },
{ 0,0,0,0,1 },
{ 0,0,0,0,1 } },
{ { 1,1,1,1,1 }, /* 5 */
{ 1,0,0,0,0 },
{ 1,1,1,1,1 },
{ 0,0,0,0,1 },
{ 1,1,1,1,1 } },
{ { 1,1,1,1,1 }, /* 6 */
{ 1,0,0,0,0 },
{ 1,1,1,1,1 },
{ 1,0,0,0,1 },
{ 1,1,1,1,1 } },
{ { 1,1,1,1,1 }, /* 7 */
{ 0,0,0,0,1 },
{ 0,0,0,0,1 },
{ 0,0,0,0,1 },
{ 0,0,0,0,1 } },
{ { 1,1,1,1,1 }, /* 8 */
{ 1,0,0,0,1 },
{ 1,1,1,1,1 },
{ 1,0,0,0,1 },
{ 1,1,1,1,1 } },
{ { 1,1,1,1,1 }, /* 9 */
{ 1,0,0,0,1 },
{ 1,1,1,1,1 },
{ 0,0,0,0,1 },
{ 1,1,1,1,1 } },
{ { 0,0,0,0,0 }, /* : */
{ 0,0,1,0,0 },
{ 0,0,0,0,0 },
{ 0,0,1,0,0 },
{ 0,0,0,0,0 } },
{ { 1,1,1,1,1 }, /* A */
{ 1,0,0,0,1 },
{ 1,1,1,1,1 },
{ 1,0,0,0,1 },
{ 1,0,0,0,1 } },
{ { 1,1,1,1,1 }, /* P */
{ 1,0,0,0,1 },
{ 1,1,1,1,1 },
{ 1,0,0,0,0 },
{ 1,0,0,0,0 } },
{ { 1,0,0,0,1 }, /* M */
{ 1,1,0,1,1 },
{ 1,0,1,0,1 },
{ 1,0,0,0,1 },
{ 1,0,0,0,1 } },
};
void
clock_draw(struct screen_write_ctx *ctx, int colour, int style)
{
struct screen *s = ctx->s;
struct grid_cell gc;
char tim[64], *ptr;
time_t t;
u_int i, j, x, y, idx;
t = time(NULL);
if (style == 0)
strftime(tim, sizeof tim, "%l:%M %p", localtime(&t));
else
strftime(tim, sizeof tim, "%H:%M", localtime(&t));
screen_write_clearscreen(ctx);
if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) {
if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) {
x = (screen_size_x(s) / 2) - (strlen(tim) / 2);
y = screen_size_y(s) / 2;
screen_write_cursormove(ctx, x, y);
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_fg(&gc, colour);
screen_write_puts(ctx, &gc, "%s", tim);
}
return;
}
x = (screen_size_x(s) / 2) - 3 * strlen(tim);
y = (screen_size_y(s) / 2) - 3;
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_bg(&gc, colour);
for (ptr = tim; *ptr != '\0'; ptr++) {
if (*ptr >= '0' && *ptr <= '9')
idx = *ptr - '0';
else if (*ptr == ':')
idx = 10;
else if (*ptr == 'A')
idx = 11;
else if (*ptr == 'P')
idx = 12;
else if (*ptr == 'M')
idx = 13;
else {
x += 6;
continue;
}
for (j = 0; j < 5; j++) {
for (i = 0; i < 5; i++) {
screen_write_cursormove(ctx, x + i, y + j);
if (clock_table[idx][j][i])
screen_write_putc(ctx, &gc, ' ');
}
}
x += 6;
}
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +18,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -26,86 +30,121 @@
* Attach existing session to the current terminal. * Attach existing session to the current terminal.
*/ */
enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_attach_session_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_attach_session_entry = { const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach", .name = "attach-session",
"drt:", 0, 0, .alias = "attach",
"[-dr] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, .args = { "c:dErt:", 0, 0 },
NULL, .usage = "[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
NULL,
cmd_attach_session_exec .tflag = CMD_SESSION_WITHPANE,
.flags = CMD_STARTSERVER,
.exec = cmd_attach_session_exec
}; };
enum cmd_retval enum cmd_retval
cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_attach_session(struct cmdq_item *item, int dflag, int rflag,
const char *cflag, int Eflag)
{ {
struct args *args = self->args; struct session *s = item->state.tflag.s;
struct session *s; struct client *c = item->client, *c_loop;
struct client *c; struct winlink *wl = item->state.tflag.wl;
const char *update; struct window_pane *wp = item->state.tflag.wp;
char *cause; char *cause;
u_int i;
if (RB_EMPTY(&sessions)) { if (RB_EMPTY(&sessions)) {
ctx->error(ctx, "no sessions"); cmdq_error(item, "no sessions");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if ((s = cmd_find_session(ctx, args_get(args, 't'), 1)) == NULL) if (c == NULL)
return (CMD_RETURN_ERROR);
if (ctx->cmdclient == NULL && ctx->curclient == NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
if (server_client_check_nested(c)) {
cmdq_error(item, "sessions should be nested with care, "
"unset $TMUX to force");
return (CMD_RETURN_ERROR);
}
if (ctx->cmdclient == NULL) { if (wl != NULL) {
if (args_has(self->args, 'd')) { if (wp != NULL)
/* window_set_active_pane(wp->window, wp);
* Can't use server_write_session in case attaching to session_set_current(s, wl);
* the same session as currently attached to. }
*/
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { if (cflag != NULL) {
c = ARRAY_ITEM(&clients, i); free((void *)s->cwd);
if (c == NULL || c->session != s) s->cwd = format_single(item, cflag, c, s, wl, wp);
}
if (c->session != NULL) {
if (dflag) {
TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue; continue;
if (c == ctx->curclient) server_client_detach(c_loop, MSG_DETACH);
continue;
server_write_client(c, MSG_DETACH, NULL, 0);
} }
} }
if (!Eflag)
environ_update(s->options, c->environ, s->environ);
ctx->curclient->session = s; c->session = s;
notify_attached_session_changed(ctx->curclient); if (!item->repeat)
session_update_activity(s); server_client_set_key_table(c, NULL);
server_redraw_client(ctx->curclient); status_timer_start(c);
notify_client("client-session-changed", c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS; s->curw->flags &= ~WINLINK_ALERTFLAGS;
} else { } else {
if (server_client_open(ctx->cmdclient, s, &cause) != 0) { if (server_client_open(c, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause); cmdq_error(item, "open terminal failed: %s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (rflag)
c->flags |= CLIENT_READONLY;
if (args_has(self->args, 'r')) if (dflag) {
ctx->cmdclient->flags |= CLIENT_READONLY; TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue;
server_client_detach(c_loop, MSG_DETACH);
}
}
if (!Eflag)
environ_update(s->options, c->environ, s->environ);
if (args_has(self->args, 'd')) c->session = s;
server_write_session(s, MSG_DETACH, NULL, 0); server_client_set_key_table(c, NULL);
status_timer_start(c);
ctx->cmdclient->session = s; notify_client("client-session-changed", c);
notify_attached_session_changed(ctx->cmdclient); session_update_activity(s, NULL);
session_update_activity(s); gettimeofday(&s->last_attached_time, NULL);
server_write_ready(ctx->cmdclient); server_redraw_client(c);
update = options_get_string(&s->options, "update-environment");
environ_update(update, &ctx->cmdclient->environ, &s->environ);
server_redraw_client(ctx->cmdclient);
s->curw->flags &= ~WINLINK_ALERTFLAGS; s->curw->flags &= ~WINLINK_ALERTFLAGS;
if (~c->flags & CLIENT_CONTROL)
proc_send(c->peer, MSG_READY, -1, NULL, 0);
notify_client("client-attached", c);
c->flags |= CLIENT_ATTACHED;
} }
recalculate_sizes(); recalculate_sizes();
alerts_check_session(s);
server_update_socket(); server_update_socket();
return (CMD_RETURN_ATTACH); return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_attach_session_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
return (cmd_attach_session(item, args_has(args, 'd'),
args_has(args, 'r'), args_get(args, 'c'), args_has(args, 'E')));
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,98 +24,53 @@
#include "tmux.h" #include "tmux.h"
/* /*
* Bind a key to a command, this recurses through cmd_*. * Bind a key to a command.
*/ */
enum cmd_retval cmd_bind_key_check(struct args *); static enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_ctx *, int);
const struct cmd_entry cmd_bind_key_entry = { const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind", .name = "bind-key",
"cnrt:", 1, -1, .alias = "bind",
"[-cnr] [-t key-table] key command [arguments]",
0, .args = { "cnrT:", 2, -1 },
NULL, .usage = "[-cnr] [-T key-table] key "
cmd_bind_key_check, "command [arguments]",
cmd_bind_key_exec
.flags = CMD_AFTERHOOK,
.exec = cmd_bind_key_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_bind_key_check(struct args *args) cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
{
if (args_has(args, 't')) {
if (args->argc != 2)
return (CMD_RETURN_ERROR);
} else {
if (args->argc < 2)
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
char *cause; char *cause;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
int key; key_code key;
const char *tablename;
key = key_string_lookup_string(args->argv[0]); key = key_string_lookup_string(args->argv[0]);
if (key == KEYC_NONE) { if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
ctx->error(ctx, "unknown key: %s", args->argv[0]); cmdq_error(item, "unknown key: %s", args->argv[0]);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (args_has(args, 't')) if (args_has(args, 'T'))
return (cmd_bind_key_table(self, ctx, key)); tablename = args_get(args, 'T');
else if (args_has(args, 'n'))
tablename = "root";
else
tablename = "prefix";
cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, &cause); cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0,
&cause);
if (cmdlist == NULL) { if (cmdlist == NULL) {
ctx->error(ctx, "%s", cause); cmdq_error(item, "%s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (!args_has(args, 'n')) key_bindings_add(tablename, key, args_has(args, 'r'), cmdlist);
key |= KEYC_PREFIX;
key_bindings_add(key, args_has(args, 'r'), cmdlist);
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
{
struct args *args = self->args;
const char *tablename;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
enum mode_key_cmd cmd;
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
ctx->error(ctx, "unknown key table: %s", tablename);
return (CMD_RETURN_ERROR);
}
cmd = mode_key_fromstring(mtab->cmdstr, args->argv[1]);
if (cmd == MODEKEY_NONE) {
ctx->error(ctx, "unknown command: %s", args->argv[1]);
return (CMD_RETURN_ERROR);
}
mtmp.key = key;
mtmp.mode = !!args_has(args, 'c');
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
mbind->cmd = cmd;
return (CMD_RETURN_NORMAL);
}
mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key;
mbind->mode = mtmp.mode;
mbind->cmd = cmd;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,89 +26,89 @@
* Break pane off into a window. * Break pane off into a window.
*/ */
enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_ctx *); #define BREAK_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
static enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_break_pane_entry = { const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp", .name = "break-pane",
"dPF:t:", 0, 0, .alias = "breakp",
"[-dP] [-F format] " CMD_TARGET_PANE_USAGE,
0, .args = { "dPF:n:s:t:", 0, 0 },
NULL, .usage = "[-dP] [-F format] [-n window-name] [-s src-pane] [-t dst-window]",
NULL,
cmd_break_pane_exec .sflag = CMD_PANE,
.tflag = CMD_WINDOW_INDEX,
.flags = 0,
.exec = cmd_break_pane_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl; struct client *c = item->state.c;
struct session *s; struct winlink *wl = item->state.sflag.wl;
struct window_pane *wp; struct session *src_s = item->state.sflag.s;
struct window *w; struct session *dst_s = item->state.tflag.s;
char *name; struct window_pane *wp = item->state.sflag.wp;
char *cause; struct window *w = wl->window;
int base_idx; char *name, *cause;
struct client *c; int idx = item->state.tflag.idx;
struct format_tree *ft;
const char *template; const char *template;
char *cp; char *cp;
if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL) if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
return (CMD_RETURN_ERROR); cmdq_error(item, "index %d already in use", idx);
if (window_count_panes(wl->window) == 1) {
ctx->error(ctx, "can't break with only one pane");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
w = wl->window; if (window_count_panes(w) == 1) {
cmdq_error(item, "can't break with only one pane");
return (CMD_RETURN_ERROR);
}
server_unzoom_window(w);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
if (wp == w->active) { window_lost_pane(w, wp);
w->active = w->last;
w->last = NULL;
if (w->active == NULL) {
w->active = TAILQ_PREV(wp, window_panes, entry);
if (w->active == NULL)
w->active = TAILQ_NEXT(wp, entry);
}
} else if (wp == w->last)
w->last = NULL;
layout_close_pane(wp); layout_close_pane(wp);
w = wp->window = window_create1(s->sx, s->sy); w = wp->window = window_create(dst_s->sx, dst_s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp; w->active = wp;
name = default_window_name(w);
window_set_name(w, name);
free(name);
layout_init(w);
base_idx = options_get_number(&s->options, "base-index"); if (!args_has(args, 'n')) {
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */ name = default_window_name(w);
window_set_name(w, name);
free(name);
} else {
window_set_name(w, args_get(args, 'n'));
options_set_number(w->options, "automatic-rename", 0);
}
layout_init(w, wp);
wp->flags |= PANE_CHANGED;
if (idx == -1)
idx = -1 - options_get_number(dst_s->options, "base-index");
wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
if (!args_has(self->args, 'd')) if (!args_has(self->args, 'd'))
session_select(s, wl->idx); session_select(dst_s, wl->idx);
server_redraw_session(s); server_redraw_session(src_s);
server_status_session_group(s); if (src_s != dst_s)
server_redraw_session(dst_s);
server_status_session_group(src_s);
if (src_s != dst_s)
server_status_session_group(dst_s);
if (args_has(args, 'P')) { if (args_has(args, 'P')) {
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = BREAK_PANE_TEMPLATE; template = BREAK_PANE_TEMPLATE;
cp = format_single(item, template, c, dst_s, wl, wp);
ft = format_create(); cmdq_print(item, "%s", cp);
if ((c = cmd_find_client(ctx, NULL)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wp);
cp = format_expand(ft, template);
ctx->print(ctx, "%s", cp);
free(cp); free(cp);
format_free(ft);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net> * Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
@@ -24,62 +24,142 @@
#include "tmux.h" #include "tmux.h"
/* /*
* Write the entire contents of a pane to a buffer. * Write the entire contents of a pane to a buffer or stdout.
*/ */
enum cmd_retval cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_capture_pane_exec(struct cmd *, struct cmdq_item *);
static char *cmd_capture_pane_append(char *, size_t *, char *, size_t);
static char *cmd_capture_pane_pending(struct args *, struct window_pane *,
size_t *);
static char *cmd_capture_pane_history(struct args *, struct cmdq_item *,
struct window_pane *, size_t *);
const struct cmd_entry cmd_capture_pane_entry = { const struct cmd_entry cmd_capture_pane_entry = {
"capture-pane", "capturep", .name = "capture-pane",
"b:E:S:t:", 0, 0, .alias = "capturep",
"[-b buffer-index] [-E end-line] [-S start-line] [-t target-pane]",
0, .args = { "ab:CeE:JpPqS:t:", 0, 0 },
NULL, .usage = "[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] "
NULL, "[-S start-line]" CMD_TARGET_PANE_USAGE,
cmd_capture_pane_exec
.tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_capture_pane_exec
}; };
enum cmd_retval const struct cmd_entry cmd_clear_history_entry = {
cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "clear-history",
.alias = "clearhist",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_capture_pane_exec
};
static char *
cmd_capture_pane_append(char *buf, size_t *len, char *line, size_t linelen)
{
buf = xrealloc(buf, *len + linelen + 1);
memcpy(buf + *len, line, linelen);
*len += linelen;
return (buf);
}
static char *
cmd_capture_pane_pending(struct args *args, struct window_pane *wp,
size_t *len)
{
struct evbuffer *pending;
char *buf, *line, tmp[5];
size_t linelen;
u_int i;
pending = input_pending(wp);
if (pending == NULL)
return (xstrdup(""));
line = EVBUFFER_DATA(pending);
linelen = EVBUFFER_LENGTH(pending);
buf = xstrdup("");
if (args_has(args, 'C')) {
for (i = 0; i < linelen; i++) {
if (line[i] >= ' ' && line[i] != '\\') {
tmp[0] = line[i];
tmp[1] = '\0';
} else
xsnprintf(tmp, sizeof tmp, "\\%03hho", line[i]);
buf = cmd_capture_pane_append(buf, len, tmp,
strlen(tmp));
}
} else
buf = cmd_capture_pane_append(buf, len, line, linelen);
return (buf);
}
static char *
cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
struct window_pane *wp, size_t *len)
{ {
struct args *args = self->args;
struct window_pane *wp;
char *buf, *line, *cause;
struct screen *s;
struct grid *gd; struct grid *gd;
int buffer, n; const struct grid_line *gl;
u_int i, limit, top, bottom, tmp; struct grid_cell *gc = NULL;
size_t len, linelen; int n, with_codes, escape_c0, join_lines;
u_int i, sx, top, bottom, tmp;
char *cause, *buf, *line;
const char *Sflag, *Eflag;
size_t linelen;
if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) sx = screen_size_x(&wp->base);
return (CMD_RETURN_ERROR); if (args_has(args, 'a')) {
s = &wp->base; gd = wp->saved_grid;
gd = s->grid; if (gd == NULL) {
if (!args_has(args, 'q')) {
cmdq_error(item, "no alternate screen");
return (NULL);
}
return (xstrdup(""));
}
} else
gd = wp->base.grid;
buf = NULL; Sflag = args_get(args, 'S');
len = 0; if (Sflag != NULL && strcmp(Sflag, "-") == 0)
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; top = 0;
else else {
top = gd->hsize + n; n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
if (top > gd->hsize + gd->sy - 1) if (cause != NULL) {
top = gd->hsize + gd->sy - 1; 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); Eflag = args_get(args, 'E');
if (cause != NULL) { if (Eflag != NULL && strcmp(Eflag, "-") == 0)
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; bottom = gd->hsize + gd->sy - 1;
else {
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) { if (bottom < top) {
tmp = bottom; tmp = bottom;
@@ -87,37 +167,76 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
top = tmp; 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++) { for (i = top; i <= bottom; i++) {
line = grid_string_cells(s->grid, 0, i, screen_size_x(s)); line = grid_string_cells(gd, 0, i, sx, &gc, with_codes,
linelen = strlen(line); escape_c0, !join_lines);
linelen = strlen(line);
buf = xrealloc(buf, 1, len + linelen + 1); buf = cmd_capture_pane_append(buf, len, line, linelen);
memcpy(buf + len, line, linelen);
len += linelen;
buf[len++] = '\n';
free(line); gl = grid_peek_line(gd, i);
if (!join_lines || !(gl->flags & GRID_LINE_WRAPPED))
buf[(*len)++] = '\n';
free(line);
} }
return (buf);
}
limit = options_get_number(&global_options, "buffer-limit"); static enum cmd_retval
cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
struct client *c;
struct window_pane *wp = item->state.tflag.wp;
char *buf, *cause;
const char *bufname;
size_t len;
if (!args_has(args, 'b')) { if (self->entry == &cmd_clear_history_entry) {
paste_add(&global_buffers, buf, len, limit); if (wp->mode == &window_copy_mode)
window_pane_reset_mode(wp);
grid_clear_history(wp->base.grid);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); len = 0;
if (cause != NULL) { if (args_has(args, 'P'))
ctx->error(ctx, "buffer %s", cause); buf = cmd_capture_pane_pending(args, wp, &len);
free(buf); else
free(cause); buf = cmd_capture_pane_history(args, item, wp, &len);
if (buf == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
}
if (paste_replace(&global_buffers, buffer, buf, len) != 0) { if (args_has(args, 'p')) {
ctx->error(ctx, "no buffer %d", buffer); c = item->client;
if (c == NULL ||
(c->session != NULL && !(c->flags & CLIENT_CONTROL))) {
cmdq_error(item, "can't write to stdout");
free(buf);
return (CMD_RETURN_ERROR);
}
evbuffer_add(c->stdout_data, buf, len);
free(buf); free(buf);
return (CMD_RETURN_ERROR); if (args_has(args, 'P') && len > 0)
evbuffer_add(c->stdout_data, "\n", 1);
server_client_push_stdout(c);
} else {
bufname = NULL;
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
if (paste_set(buf, len, bufname, &cause) != 0) {
cmdq_error(item, "%s", cause);
free(cause);
free(buf);
return (CMD_RETURN_ERROR);
}
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,44 +27,46 @@
* Enter choice mode to choose a buffer. * Enter choice mode to choose a buffer.
*/ */
enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *); #define CHOOSE_BUFFER_TEMPLATE \
"#{buffer_name}: #{buffer_size} bytes: #{buffer_sample}"
void cmd_choose_buffer_callback(struct window_choose_data *); static enum cmd_retval cmd_choose_buffer_exec(struct cmd *,
void cmd_choose_buffer_free(struct window_choose_data *); struct cmdq_item *);
const struct cmd_entry cmd_choose_buffer_entry = { const struct cmd_entry cmd_choose_buffer_entry = {
"choose-buffer", NULL, .name = "choose-buffer",
"F:t:", 0, 1, .alias = NULL,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0, .args = { "F:t:", 0, 1 },
NULL, .usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
NULL,
cmd_choose_buffer_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_buffer_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_choose_buffer_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c = item->state.c;
struct winlink *wl = item->state.tflag.wl;
struct window_choose_data *cdata; struct window_choose_data *cdata;
struct winlink *wl;
struct paste_buffer *pb; struct paste_buffer *pb;
char *action, *action_data; char *action, *action_data;
const char *template; const char *template;
u_int idx; u_int idx;
if (ctx->curclient == NULL) { if (c == NULL) {
ctx->error(ctx, "must be run interactively"); cmdq_error(item, "no client available");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = CHOOSE_BUFFER_TEMPLATE; template = CHOOSE_BUFFER_TEMPLATE;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) if (paste_get_top(NULL) == NULL)
return (CMD_RETURN_ERROR);
if (paste_get_top(&global_buffers) == NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
@@ -76,51 +78,24 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
action = xstrdup("paste-buffer -b '%%'"); action = xstrdup("paste-buffer -b '%%'");
idx = 0; idx = 0;
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) { pb = NULL;
cdata = window_choose_data_create(ctx); while ((pb = paste_walk(pb)) != NULL) {
cdata->idx = idx - 1; cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->client->references++; cdata->idx = idx;
cdata->ft_template = xstrdup(template); cdata->ft_template = xstrdup(template);
format_add(cdata->ft, "line", "%u", idx - 1); format_defaults_paste_buffer(cdata->ft, pb);
format_paste_buffer(cdata->ft, pb);
xasprintf(&action_data, "%u", idx - 1); xasprintf(&action_data, "%s", paste_buffer_name(pb));
cdata->command = cmd_template_replace(action, action_data, 1); cdata->command = cmd_template_replace(action, action_data, 1);
free(action_data); free(action_data);
window_choose_add(wl->window->active, cdata); window_choose_add(wl->window->active, cdata);
idx++;
} }
free(action); free(action);
window_choose_ready(wl->window->active, window_choose_ready(wl->window->active, 0, NULL);
0, cmd_choose_buffer_callback, cmd_choose_buffer_free);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
void
cmd_choose_buffer_callback(struct window_choose_data *cdata)
{
if (cdata == NULL)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
window_choose_ctx(cdata);
}
void
cmd_choose_buffer_free(struct window_choose_data *data)
{
struct window_choose_data *cdata = data;
if (cdata == NULL)
return;
cdata->client->references--;
free(cdata->command);
free(cdata->ft_template);
free(cdata);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,45 +27,51 @@
* Enter choice mode to choose a client. * Enter choice mode to choose a client.
*/ */
enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_ctx *); #define CHOOSE_CLIENT_TEMPLATE \
"#{client_name}: #{session_name} " \
"[#{client_width}x#{client_height} #{client_termname}]" \
"#{?client_utf8, (utf8),}#{?client_readonly, (ro),} " \
"(last used #{t:client_activity})"
void cmd_choose_client_callback(struct window_choose_data *); static enum cmd_retval cmd_choose_client_exec(struct cmd *,
void cmd_choose_client_free(struct window_choose_data *); struct cmdq_item *);
static void cmd_choose_client_callback(struct window_choose_data *);
const struct cmd_entry cmd_choose_client_entry = { const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL, .name = "choose-client",
"F:t:", 0, 1, .alias = NULL,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0, .args = { "F:t:", 0, 1 },
NULL, .usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
NULL,
cmd_choose_client_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_client_exec
}; };
struct cmd_choose_client_data { struct cmd_choose_client_data {
struct client *client; struct client *client;
char *template;
}; };
enum cmd_retval static enum cmd_retval
cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_choose_client_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c = item->state.c;
struct client *c1;
struct window_choose_data *cdata; struct window_choose_data *cdata;
struct winlink *wl; struct winlink *wl = item->state.tflag.wl;
struct client *c;
const char *template; const char *template;
char *action; char *action;
u_int i, idx, cur; u_int idx, cur;
if (ctx->curclient == NULL) { if (c == NULL) {
ctx->error(ctx, "must be run interactively"); cmdq_error(item, "no client available");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
@@ -78,64 +84,52 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
action = xstrdup("detach-client -t '%%'"); action = xstrdup("detach-client -t '%%'");
cur = idx = 0; cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c1, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c1->session == NULL)
if (c == NULL || c->session == NULL)
continue; continue;
if (c == ctx->curclient) if (c1 == item->client)
cur = idx; cur = idx;
idx++;
cdata = window_choose_data_create(ctx); cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->idx = i; cdata->idx = idx;
cdata->client->references++;
cdata->ft_template = xstrdup(template); cdata->ft_template = xstrdup(template);
format_add(cdata->ft, "line", "%u", i); format_add(cdata->ft, "line", "%u", idx);
format_session(cdata->ft, c->session); format_defaults(cdata->ft, c1, NULL, NULL, NULL);
format_client(cdata->ft, c);
cdata->command = cmd_template_replace(action, c->tty.path, 1); cdata->command = cmd_template_replace(action, c1->name, 1);
window_choose_add(wl->window->active, cdata); window_choose_add(wl->window->active, cdata);
idx++;
} }
free(action); free(action);
window_choose_ready(wl->window->active, window_choose_ready(wl->window->active, cur,
cur, cmd_choose_client_callback, cmd_choose_client_free); cmd_choose_client_callback);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
void static void
cmd_choose_client_callback(struct window_choose_data *cdata) cmd_choose_client_callback(struct window_choose_data *cdata)
{ {
struct client *c; struct client *c;
u_int idx;
if (cdata == NULL) if (cdata == NULL)
return; return;
if (cdata->client->flags & CLIENT_DEAD) if (cdata->start_client->flags & CLIENT_DEAD)
return; return;
if (cdata->idx > ARRAY_LENGTH(&clients) - 1) idx = 0;
return; TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, cdata->idx); if (idx == cdata->idx)
break;
idx++;
}
if (c == NULL || c->session == NULL) if (c == NULL || c->session == NULL)
return; return;
window_choose_ctx(cdata); window_choose_data_run(cdata);
}
void
cmd_choose_client_free(struct window_choose_data *cdata)
{
if (cdata == NULL)
return;
cdata->client->references--;
free(cdata->ft_template);
free(cdata->command);
format_free(cdata->ft);
free(cdata);
} }

View File

@@ -1,123 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
#define CMD_CHOOSE_LIST_DEFAULT_TEMPLATE "run-shell '%%'"
/*
* Enter choose mode to choose a custom list.
*/
enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_list_callback(struct window_choose_data *);
void cmd_choose_list_free(struct window_choose_data *);
const struct cmd_entry cmd_choose_list_entry = {
"choose-list", NULL,
"l:t:", 0, 1,
"[-l items] " CMD_TARGET_WINDOW_USAGE "[template]",
0,
NULL,
NULL,
cmd_choose_list_exec
};
enum cmd_retval
cmd_choose_list_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct winlink *wl;
const char *list1;
char *template, *item, *copy, *list;
u_int idx;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (CMD_RETURN_ERROR);
}
if ((list1 = args_get(args, 'l')) == NULL)
return (CMD_RETURN_ERROR);
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (CMD_RETURN_NORMAL);
if (args->argc != 0)
template = xstrdup(args->argv[0]);
else
template = xstrdup(CMD_CHOOSE_LIST_DEFAULT_TEMPLATE);
copy = list = xstrdup(list1);
idx = 0;
while ((item = strsep(&list, ",")) != NULL)
{
if (*item == '\0') /* no empty entries */
continue;
window_choose_add_item(wl->window->active, ctx, wl, item,
template, idx);
idx++;
}
free(copy);
if (idx == 0) {
free(template);
window_pane_reset_mode(wl->window->active);
return (CMD_RETURN_ERROR);
}
window_choose_ready(wl->window->active, 0, cmd_choose_list_callback,
cmd_choose_list_free);
free(template);
return (CMD_RETURN_NORMAL);
}
void
cmd_choose_list_callback(struct window_choose_data *cdata)
{
if (cdata == NULL || (cdata->client->flags & CLIENT_DEAD))
return;
window_choose_ctx(cdata);
}
void
cmd_choose_list_free(struct window_choose_data *cdata)
{
cdata->session->references--;
cdata->client->references--;
free(cdata->ft_template);
free(cdata->command);
format_free(cdata->ft);
free(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org> * Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
@@ -32,48 +32,64 @@
* Enter choice mode to choose a session and/or window. * Enter choice mode to choose a session and/or window.
*/ */
enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_ctx *); #define CHOOSE_TREE_SESSION_TEMPLATE \
"#{session_name}: #{session_windows} windows" \
"#{?session_grouped, (group ,}" \
"#{session_group}#{?session_grouped,),}" \
"#{?session_attached, (attached),}"
#define CHOOSE_TREE_WINDOW_TEMPLATE \
"#{window_index}: #{window_name}#{window_flags} " \
"\"#{pane_title}\""
void cmd_choose_tree_callback(struct window_choose_data *); static enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmdq_item *);
void cmd_choose_tree_free(struct window_choose_data *);
const struct cmd_entry cmd_choose_tree_entry = { const struct cmd_entry cmd_choose_tree_entry = {
"choose-tree", NULL, .name = "choose-tree",
"S:W:swb:c:t:", 0, 1, .alias = NULL,
"[-sw] [-b session-template] [-c window template] [-S format] " \
"[-W format] " CMD_TARGET_WINDOW_USAGE, .args = { "S:W:swub:c:t:", 0, 1 },
0, .usage = "[-suw] [-b session-template] [-c window template] "
NULL, "[-S format] [-W format] " CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_choose_tree_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_tree_exec
}; };
const struct cmd_entry cmd_choose_session_entry = { const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL, .name = "choose-session",
"F:t:", 0, 1, .alias = NULL,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0, .args = { "F:t:", 0, 1 },
NULL, .usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
NULL,
cmd_choose_tree_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_tree_exec
}; };
const struct cmd_entry cmd_choose_window_entry = { const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL, .name = "choose-window",
"F:t:", 0, 1, .alias = NULL,
CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
0, .args = { "F:t:", 0, 1 },
NULL, .usage = CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
NULL,
cmd_choose_tree_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_tree_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl, *wm; struct client *c = item->state.c;
struct session *s, *s2; struct winlink *wl = item->state.tflag.wl, *wm;
struct session *s = item->state.tflag.s, *s2;
struct window_choose_data *wcd = NULL; struct window_choose_data *wcd = NULL;
const char *ses_template, *win_template; const char *ses_template, *win_template;
char *final_win_action, *cur_win_template; char *final_win_action, *cur_win_template;
@@ -86,16 +102,11 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx)
ses_template = win_template = NULL; ses_template = win_template = NULL;
ses_action = win_action = NULL; ses_action = win_action = NULL;
if (ctx->curclient == NULL) { if (c == NULL) {
ctx->error(ctx, "must be run interactively"); cmdq_error(item, "no client available");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
s = ctx->curclient->session;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
@@ -175,7 +186,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
wcd = window_choose_add_session(wl->window->active, wcd = window_choose_add_session(wl->window->active,
ctx, s2, ses_template, (char *)ses_action, idx_ses); c, s2, ses_template, ses_action, idx_ses);
/* If we're just choosing sessions, skip choosing windows. */ /* If we're just choosing sessions, skip choosing windows. */
if (sflag && !wflag) { if (sflag && !wflag) {
@@ -204,8 +215,9 @@ windows_only:
cur_win = idx_ses; cur_win = idx_ses;
} }
xasprintf(&final_win_action, "%s ; %s", win_action, xasprintf(&final_win_action, "%s %s %s",
wcd ? wcd->command : ""); wcd != NULL ? wcd->command : "",
wcd != NULL ? ";" : "", win_action);
if (win_ses != win_max) if (win_ses != win_max)
cur_win_template = final_win_template_middle; cur_win_template = final_win_template_middle;
@@ -213,12 +225,13 @@ windows_only:
cur_win_template = final_win_template_last; cur_win_template = final_win_template_last;
window_choose_add_window(wl->window->active, window_choose_add_window(wl->window->active,
ctx, s2, wm, cur_win_template, c, s2, wm, cur_win_template,
final_win_action, final_win_action,
(wflag && !sflag) ? win_ses : idx_ses); (wflag && !sflag) ? win_ses : idx_ses);
free(final_win_action); free(final_win_action);
} }
/* /*
* If we're just drawing windows, don't consider moving on to * If we're just drawing windows, don't consider moving on to
* other sessions as we only list windows in this session. * other sessions as we only list windows in this session.
@@ -229,33 +242,12 @@ windows_only:
free(final_win_template_middle); free(final_win_template_middle);
free(final_win_template_last); free(final_win_template_last);
window_choose_ready(wl->window->active, cur_win, window_choose_ready(wl->window->active, cur_win, NULL);
cmd_choose_tree_callback, cmd_choose_tree_free);
if (args_has(args, 'u')) {
window_choose_expand_all(wl->window->active);
window_choose_set_current(wl->window->active, cur_win);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
void
cmd_choose_tree_callback(struct window_choose_data *cdata)
{
if (cdata == NULL)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
window_choose_ctx(cdata);
}
void
cmd_choose_tree_free(struct window_choose_data *cdata)
{
cdata->session->references--;
cdata->client->references--;
free(cdata->ft_template);
free(cdata->command);
format_free(cdata->ft);
free(cdata);
}

View File

@@ -1,54 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
/*
* Clear pane history.
*/
enum cmd_retval cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
0,
NULL,
NULL,
cmd_clear_history_exec
};
enum cmd_retval
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct window_pane *wp;
struct grid *gd;
if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy);
gd->hsize = 0;
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -29,85 +29,64 @@
* Prompt for command in client. * Prompt for command in client.
*/ */
void cmd_command_prompt_key_binding(struct cmd *, int); static enum cmd_retval cmd_command_prompt_exec(struct cmd *,
int cmd_command_prompt_check(struct args *); struct cmdq_item *);
enum cmd_retval cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
int cmd_command_prompt_callback(void *, const char *); static int cmd_command_prompt_callback(void *, const char *, int);
void cmd_command_prompt_free(void *); static void cmd_command_prompt_free(void *);
const struct cmd_entry cmd_command_prompt_entry = { const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL, .name = "command-prompt",
"I:p:t:", 0, 1, .alias = NULL,
"[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
0, .args = { "1iI:Np:t:", 0, 1 },
cmd_command_prompt_key_binding, .usage = "[-1Ni] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
NULL, "[template]",
cmd_command_prompt_exec
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_command_prompt_exec
}; };
struct cmd_command_prompt_cdata { struct cmd_command_prompt_cdata {
struct client *c; struct client *c;
int flags;
char *inputs; char *inputs;
char *next_input; char *next_input;
char *next_prompt;
char *prompts; char *prompts;
char *next_prompt;
char *template; char *template;
int idx; int idx;
}; };
void static enum cmd_retval
cmd_command_prompt_key_binding(struct cmd *self, int key) cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
{
switch (key) {
case '$':
self->args = args_create(1, "rename-session '%%'");
args_set(self->args, 'I', "#S");
break;
case ',':
self->args = args_create(1, "rename-window '%%'");
args_set(self->args, 'I', "#W");
break;
case '.':
self->args = args_create(1, "move-window -t '%%'");
break;
case 'f':
self->args = args_create(1, "find-window '%%'");
break;
case '\'':
self->args = args_create(1, "select-window -t ':%%'");
args_set(self->args, 'p', "index");
break;
default:
self->args = args_create(0);
break;
}
}
enum cmd_retval
cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
const char *inputs, *prompts; const char *inputs, *prompts;
struct cmd_command_prompt_cdata *cdata; struct cmd_command_prompt_cdata *cdata;
struct client *c; struct client *c = item->state.c;
char *prompt, *ptr, *input = NULL; char *prompt, *ptr, *input = NULL;
size_t n; size_t n;
if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (CMD_RETURN_ERROR);
if (c->prompt_string != NULL) if (c->prompt_string != NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
cdata = xmalloc(sizeof *cdata); cdata = xcalloc(1, sizeof *cdata);
cdata->c = c; cdata->c = c;
cdata->idx = 1;
cdata->inputs = NULL; cdata->inputs = NULL;
cdata->next_input = NULL; cdata->next_input = NULL;
cdata->next_prompt = NULL;
cdata->prompts = NULL; cdata->prompts = NULL;
cdata->next_prompt = NULL;
cdata->template = NULL; cdata->template = NULL;
cdata->idx = 1;
if (args->argc != 0) if (args->argc != 0)
cdata->template = xstrdup(args->argv[0]); cdata->template = xstrdup(args->argv[0]);
@@ -137,35 +116,56 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
input = strsep(&cdata->next_input, ","); input = strsep(&cdata->next_input, ",");
} }
if (args_has(args, '1'))
cdata->flags |= PROMPT_SINGLE;
else if (args_has(args, 'N'))
cdata->flags |= PROMPT_NUMERIC;
else if (args_has(args, 'i'))
cdata->flags |= PROMPT_INCREMENTAL;
status_prompt_set(c, prompt, input, cmd_command_prompt_callback, status_prompt_set(c, prompt, input, cmd_command_prompt_callback,
cmd_command_prompt_free, cdata, 0); cmd_command_prompt_free, cdata, cdata->flags);
free(prompt); free(prompt);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
int static enum cmd_retval
cmd_command_prompt_callback(void *data, const char *s) cmd_command_prompt_error(struct cmdq_item *item, void *data)
{
char *error = data;
cmdq_error(item, "%s", error);
free(error);
return (CMD_RETURN_NORMAL);
}
static int
cmd_command_prompt_callback(void *data, const char *s, int done)
{ {
struct cmd_command_prompt_cdata *cdata = data; struct cmd_command_prompt_cdata *cdata = data;
struct client *c = cdata->c; struct client *c = cdata->c;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd_ctx ctx; struct cmdq_item *new_item;
char *cause, *new_template, *prompt, *ptr; char *cause, *new_template, *prompt, *ptr;
char *input = NULL; char *input = NULL;
if (s == NULL) if (s == NULL)
return (0); return (0);
if (done && (cdata->flags & PROMPT_INCREMENTAL))
return (0);
new_template = cmd_template_replace(cdata->template, s, cdata->idx); new_template = cmd_template_replace(cdata->template, s, cdata->idx);
free(cdata->template); if (done) {
cdata->template = new_template; free(cdata->template);
cdata->template = new_template;
}
/* /*
* Check if there are more prompts; if so, get its respective input * Check if there are more prompts; if so, get its respective input
* and update the prompt data. * and update the prompt data.
*/ */
if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) { if (done && (ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
xasprintf(&prompt, "%s ", ptr); xasprintf(&prompt, "%s ", ptr);
input = strsep(&cdata->next_input, ","); input = strsep(&cdata->next_input, ",");
status_prompt_update(c, prompt, input); status_prompt_update(c, prompt, input);
@@ -175,33 +175,29 @@ cmd_command_prompt_callback(void *data, const char *s)
return (1); return (1);
} }
if (cmd_string_parse(new_template, &cmdlist, &cause) != 0) { cmdlist = cmd_string_parse(new_template, NULL, 0, &cause);
if (cmdlist == NULL) {
if (cause != NULL) { if (cause != NULL) {
*cause = toupper((u_char) *cause); new_item = cmdq_get_callback(cmd_command_prompt_error,
status_message_set(c, "%s", cause); cause);
free(cause); } else
} new_item = NULL;
return (0); } else {
new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
cmd_list_free(cmdlist);
} }
ctx.msgdata = NULL; if (new_item != NULL)
ctx.curclient = c; cmdq_append(c, new_item);
ctx.error = key_bindings_error; if (!done)
ctx.print = key_bindings_print; free(new_template);
ctx.info = key_bindings_info; if (c->prompt_callbackfn != (void *)&cmd_command_prompt_callback)
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
return (1); return (1);
return (0); return (0);
} }
void static void
cmd_command_prompt_free(void *data) cmd_command_prompt_free(void *data)
{ {
struct cmd_command_prompt_cdata *cdata = data; struct cmd_command_prompt_cdata *cdata = data;

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -16,6 +16,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/types.h>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -26,62 +28,39 @@
* Asks for confirmation before executing a command. * Asks for confirmation before executing a command.
*/ */
void cmd_confirm_before_key_binding(struct cmd *, int); static enum cmd_retval cmd_confirm_before_exec(struct cmd *,
enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *); struct cmdq_item *);
int cmd_confirm_before_callback(void *, const char *); static int cmd_confirm_before_callback(void *, const char *, int);
void cmd_confirm_before_free(void *); static void cmd_confirm_before_free(void *);
const struct cmd_entry cmd_confirm_before_entry = { const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm", .name = "confirm-before",
"p:t:", 1, 1, .alias = "confirm",
"[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
0, .args = { "p:t:", 1, 1 },
cmd_confirm_before_key_binding, .usage = "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
NULL,
cmd_confirm_before_exec .tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_confirm_before_exec
}; };
struct cmd_confirm_before_data { struct cmd_confirm_before_data {
struct client *c;
char *cmd; char *cmd;
struct client *client;
}; };
void static enum cmd_retval
cmd_confirm_before_key_binding(struct cmd *self, int key) cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
{
switch (key) {
case '&':
self->args = args_create(1, "kill-window");
args_set(self->args, 'p', "kill-window #W? (y/n)");
break;
case 'x':
self->args = args_create(1, "kill-pane");
args_set(self->args, 'p', "kill-pane #P? (y/n)");
break;
default:
self->args = args_create(0);
break;
}
}
enum cmd_retval
cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct cmd_confirm_before_data *cdata; struct cmd_confirm_before_data *cdata;
struct client *c; struct client *c = item->state.c;
char *cmd, *copy, *new_prompt, *ptr; char *cmd, *copy, *new_prompt, *ptr;
const char *prompt; const char *prompt;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (CMD_RETURN_ERROR);
}
if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (CMD_RETURN_ERROR);
if ((prompt = args_get(args, 'p')) != NULL) if ((prompt = args_get(args, 'p')) != NULL)
xasprintf(&new_prompt, "%s ", prompt); xasprintf(&new_prompt, "%s ", prompt);
else { else {
@@ -93,57 +72,71 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(args->argv[0]); cdata->cmd = xstrdup(args->argv[0]);
cdata->c = c;
status_prompt_set(cdata->c, new_prompt, NULL, cdata->client = c;
cdata->client->references++;
status_prompt_set(c, new_prompt, NULL,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata, cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
PROMPT_SINGLE); PROMPT_SINGLE);
free(new_prompt); free(new_prompt);
return (CMD_RETURN_YIELD); return (CMD_RETURN_NORMAL);
} }
int static enum cmd_retval
cmd_confirm_before_callback(void *data, const char *s) cmd_confirm_before_error(struct cmdq_item *item, void *data)
{
char *error = data;
cmdq_error(item, "%s", error);
free(error);
return (CMD_RETURN_NORMAL);
}
static int
cmd_confirm_before_callback(void *data, const char *s, __unused int done)
{ {
struct cmd_confirm_before_data *cdata = data; struct cmd_confirm_before_data *cdata = data;
struct client *c = cdata->c; struct client *c = cdata->client;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd_ctx ctx; struct cmdq_item *new_item;
char *cause; char *cause;
if (c->flags & CLIENT_DEAD)
return (0);
if (s == NULL || *s == '\0') if (s == NULL || *s == '\0')
return (0); return (0);
if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
return (0); return (0);
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) { cmdlist = cmd_string_parse(cdata->cmd, NULL, 0, &cause);
if (cmdlist == NULL) {
if (cause != NULL) { if (cause != NULL) {
*cause = toupper((u_char) *cause); new_item = cmdq_get_callback(cmd_confirm_before_error,
status_message_set(c, "%s", cause); cause);
free(cause); } else
} new_item = NULL;
return (0); } else {
new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
cmd_list_free(cmdlist);
} }
ctx.msgdata = NULL; if (new_item != NULL)
ctx.curclient = c; cmdq_append(c, new_item);
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
return (0); return (0);
} }
void static void
cmd_confirm_before_free(void *data) cmd_confirm_before_free(void *data)
{ {
struct cmd_confirm_before_data *cdata = data; struct cmd_confirm_before_data *cdata = data;
struct client *c = cdata->client;
server_client_unref(c);
free(cdata->cmd); free(cdata->cmd);
free(cdata); free(cdata);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -21,44 +21,69 @@
#include "tmux.h" #include "tmux.h"
/* /*
* Enter copy mode. * Enter copy or clock mode.
*/ */
void cmd_copy_mode_key_binding(struct cmd *, int); static enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = { const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL, .name = "copy-mode",
"t:u", 0, 0, .alias = NULL,
"[-u] " CMD_TARGET_PANE_USAGE,
0, .args = { "Met:u", 0, 0 },
cmd_copy_mode_key_binding, .usage = "[-Mu] " CMD_TARGET_PANE_USAGE,
NULL,
cmd_copy_mode_exec .tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_copy_mode_exec
}; };
void const struct cmd_entry cmd_clock_mode_entry = {
cmd_copy_mode_key_binding(struct cmd *self, int key) .name = "clock-mode",
{ .alias = NULL,
self->args = args_create(0);
if (key == KEYC_PPAGE)
args_set(self->args, 'u', NULL);
}
enum cmd_retval .args = { "t:", 0, 0 },
cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) .usage = CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_copy_mode_exec
};
static enum cmd_retval
cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct window_pane *wp; struct client *c = item->client;
struct session *s;
struct window_pane *wp = item->state.tflag.wp;
if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) if (args_has(args, 'M')) {
return (CMD_RETURN_ERROR); if ((wp = cmd_mouse_pane(&item->mouse, &s, NULL)) == NULL)
return (CMD_RETURN_NORMAL);
if (c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
}
if (window_pane_set_mode(wp, &window_copy_mode) != 0) if (self->entry == &cmd_clock_mode_entry) {
window_pane_set_mode(wp, &window_clock_mode);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
window_copy_init_from_pane(wp); }
if (wp->mode != &window_copy_mode) {
if (window_pane_set_mode(wp, &window_copy_mode) != 0)
return (CMD_RETURN_NORMAL);
window_copy_init_from_pane(wp, args_has(self->args, 'e'));
}
if (args_has(args, 'M')) {
if (wp->mode != NULL && wp->mode != &window_copy_mode)
return (CMD_RETURN_NORMAL);
window_copy_start_drag(c, &item->mouse);
}
if (wp->mode == &window_copy_mode && args_has(self->args, 'u')) if (wp->mode == &window_copy_mode && args_has(self->args, 'u'))
window_copy_pageup(wp); window_copy_pageup(wp, 0);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,66 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Delete a paste buffer.
*/
enum cmd_retval cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb",
"b:", 0, 0,
CMD_BUFFER_USAGE,
0,
NULL,
NULL,
cmd_delete_buffer_exec
};
enum cmd_retval
cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
char *cause;
int buffer;
if (!args_has(args, 'b')) {
paste_free_top(&global_buffers);
return (CMD_RETURN_NORMAL);
}
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
ctx->error(ctx, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
if (paste_free_index(&global_buffers, buffer) != 0) {
ctx->error(ctx, "no buffer %d", buffer);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,32 +18,60 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
/* /*
* Detach a client. * Detach a client.
*/ */
enum cmd_retval cmd_detach_client_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_detach_client_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_detach_client_entry = { const struct cmd_entry cmd_detach_client_entry = {
"detach-client", "detach", .name = "detach-client",
"as:t:P", 0, 0, .alias = "detach",
"[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
CMD_READONLY, .args = { "aE:s:t:P", 0, 0 },
NULL, .usage = "[-aP] [-E shell-command] "
NULL, "[-s target-session] " CMD_TARGET_CLIENT_USAGE,
cmd_detach_client_exec
.sflag = CMD_SESSION,
.tflag = CMD_CLIENT,
.flags = CMD_READONLY,
.exec = cmd_detach_client_exec
}; };
enum cmd_retval const struct cmd_entry cmd_suspend_client_entry = {
cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "suspend-client",
.alias = "suspendc",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_CLIENT_USAGE,
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_detach_client_exec
};
static enum cmd_retval
cmd_detach_client_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c, *c2; struct client *c = item->state.c, *cloop;
struct session *s; struct session *s;
enum msgtype msgtype; enum msgtype msgtype;
u_int i; const char *cmd = args_get(args, 'E');
if (self->entry == &cmd_suspend_client_entry) {
tty_stop_tty(&c->tty);
c->flags |= CLIENT_SUSPENDED;
proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'P')) if (args_has(args, 'P'))
msgtype = MSG_DETACHKILL; msgtype = MSG_DETACHKILL;
@@ -51,30 +79,33 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx)
msgtype = MSG_DETACH; msgtype = MSG_DETACH;
if (args_has(args, 's')) { if (args_has(args, 's')) {
s = cmd_find_session(ctx, args_get(args, 's'), 0); s = item->state.sflag.s;
if (s == NULL) TAILQ_FOREACH(cloop, &clients, entry) {
return (CMD_RETURN_ERROR); if (cloop->session == s) {
if (cmd != NULL)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { server_client_exec(cloop, cmd);
c = ARRAY_ITEM(&clients, i); else
if (c != NULL && c->session == s) server_client_detach(cloop, msgtype);
server_write_client(c, msgtype, NULL, 0);
}
} else {
c = cmd_find_client(ctx, args_get(args, 't'));
if (c == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'a')) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c2 = ARRAY_ITEM(&clients, i);
if (c2 == NULL || c == c2)
continue;
server_write_client(c2, msgtype, NULL, 0);
} }
} else }
server_write_client(c, msgtype, NULL, 0); return (CMD_RETURN_STOP);
} }
return (CMD_RETURN_NORMAL); if (args_has(args, 'a')) {
TAILQ_FOREACH(cloop, &clients, entry) {
if (cloop->session != NULL && cloop != c) {
if (cmd != NULL)
server_client_exec(cloop, cmd);
else
server_client_detach(cloop, msgtype);
}
}
return (CMD_RETURN_NORMAL);
}
if (cmd != NULL)
server_client_exec(c, cmd);
else
server_client_detach(c, msgtype);
return (CMD_RETURN_STOP);
} }

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -27,48 +27,43 @@
* Displays a message in the status line. * Displays a message in the status line.
*/ */
enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_ctx *); #define DISPLAY_MESSAGE_TEMPLATE \
"[#{session_name}] #{window_index}:" \
"#{window_name}, current pane #{pane_index} " \
"- (%H:%M %d-%b-%y)"
static enum cmd_retval cmd_display_message_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_display_message_entry = { const struct cmd_entry cmd_display_message_entry = {
"display-message", "display", .name = "display-message",
"c:pt:F:", 0, 1, .alias = "display",
"[-p] [-c target-client] [-t target-pane] [-F format] [message]",
0, .args = { "c:pt:F:", 0, 1 },
NULL, .usage = "[-p] [-c target-client] [-F format] "
NULL, CMD_TARGET_PANE_USAGE " [message]",
cmd_display_message_exec
.cflag = CMD_CLIENT_CANFAIL,
.tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_display_message_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c; struct client *c = item->state.c;
struct session *s; struct session *s = item->state.tflag.s;
struct winlink *wl; struct winlink *wl = item->state.tflag.wl;
struct window_pane *wp; struct window_pane *wp = item->state.tflag.wp;
const char *template; const char *template;
char *msg; char *msg;
struct format_tree *ft; struct format_tree *ft;
char out[BUFSIZ];
time_t t;
size_t len;
if ((c = cmd_find_client(ctx, args_get(args, 'c'))) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 't')) {
wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp);
if (wl == NULL)
return (CMD_RETURN_ERROR);
} else {
wl = cmd_find_pane(ctx, NULL, &s, &wp);
if (wl == NULL)
return (CMD_RETURN_ERROR);
}
if (args_has(args, 'F') && args->argc != 0) { if (args_has(args, 'F') && args->argc != 0) {
ctx->error(ctx, "only one of -F or argument must be given"); cmdq_error(item, "only one of -F or argument must be given");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@@ -78,23 +73,17 @@ cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx)
if (template == NULL) if (template == NULL)
template = DISPLAY_MESSAGE_TEMPLATE; template = DISPLAY_MESSAGE_TEMPLATE;
ft = format_create(); ft = format_create(item, FORMAT_NONE, 0);
format_client(ft, c); format_defaults(ft, c, s, wl, wp);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wp);
t = time(NULL); msg = format_expand_time(ft, template, time(NULL));
len = strftime(out, sizeof out, template, localtime(&t));
out[len] = '\0';
msg = format_expand(ft, out);
if (args_has(self->args, 'p')) if (args_has(self->args, 'p'))
ctx->print(ctx, "%s", msg); cmdq_print(item, "%s", msg);
else else if (c != NULL)
status_message_set(c, "%s", msg); status_message_set(c, "%s", msg);
free(msg); free(msg);
format_free(ft); format_free(ft);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,34 +18,98 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include "tmux.h" #include "tmux.h"
/* /*
* Display panes on a client. * Display panes on a client.
*/ */
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_display_panes_exec(struct cmd *,
struct cmdq_item *);
static void cmd_display_panes_callback(struct client *,
struct window_pane *);
const struct cmd_entry cmd_display_panes_entry = { const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp", .name = "display-panes",
"t:", 0, 0, .alias = "displayp",
CMD_TARGET_CLIENT_USAGE,
0, .args = { "t:", 0, 1 },
NULL, .usage = CMD_TARGET_CLIENT_USAGE,
NULL,
cmd_display_panes_exec .tflag = CMD_CLIENT,
.flags = CMD_AFTERHOOK,
.exec = cmd_display_panes_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c; struct client *c = item->state.c;
if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL) if (c->identify_callback != NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_NORMAL);
server_set_identify(c); c->identify_callback = cmd_display_panes_callback;
if (args->argc != 0)
c->identify_callback_data = xstrdup(args->argv[0]);
else
c->identify_callback_data = xstrdup("select-pane -t '%%'");
server_client_set_identify(c);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
static enum cmd_retval
cmd_display_panes_error(struct cmdq_item *item, void *data)
{
char *error = data;
cmdq_error(item, "%s", error);
free(error);
return (CMD_RETURN_NORMAL);
}
static void
cmd_display_panes_callback(struct client *c, struct window_pane *wp)
{
struct cmd_list *cmdlist;
struct cmdq_item *new_item;
char *template, *cmd, *expanded, *cause;
template = c->identify_callback_data;
if (wp == NULL)
goto out;
xasprintf(&expanded, "%%%u", wp->id);
cmd = cmd_template_replace(template, expanded, 1);
cmdlist = cmd_string_parse(cmd, NULL, 0, &cause);
if (cmdlist == NULL) {
if (cause != NULL) {
new_item = cmdq_get_callback(cmd_display_panes_error,
cause);
} else
new_item = NULL;
} else {
new_item = cmdq_get_command(cmdlist, NULL, NULL, 0);
cmd_list_free(cmdlist);
}
if (new_item != NULL)
cmdq_append(c, new_item);
free(cmd);
free(expanded);
out:
free(c->identify_callback_data);
c->identify_callback_data = NULL;
c->identify_callback = NULL;
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -28,10 +28,14 @@
* Find window containing text. * Find window containing text.
*/ */
enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_ctx *); #define FIND_WINDOW_TEMPLATE \
"#{window_index}: #{window_name} " \
"[#{window_width}x#{window_height}] " \
"(#{window_panes} panes) #{window_find_matches}"
void cmd_find_window_callback(struct window_choose_data *); static enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmdq_item *);
void cmd_find_window_free(struct window_choose_data *);
static void cmd_find_window_callback(struct window_choose_data *);
/* Flags for determining matching behavior. */ /* Flags for determining matching behavior. */
#define CMD_FIND_WINDOW_BY_TITLE 0x1 #define CMD_FIND_WINDOW_BY_TITLE 0x1
@@ -44,27 +48,31 @@ void cmd_find_window_free(struct window_choose_data *);
CMD_FIND_WINDOW_BY_NAME) CMD_FIND_WINDOW_BY_NAME)
const struct cmd_entry cmd_find_window_entry = { const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw", .name = "find-window",
"F:CNt:T", 1, 4, .alias = "findw",
"[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
0, .args = { "F:CNt:T", 1, 4 },
NULL, .usage = "[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
NULL,
cmd_find_window_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_find_window_exec
}; };
struct cmd_find_window_data { struct cmd_find_window_data {
struct winlink *wl; struct winlink *wl;
char *list_ctx; char *list_ctx;
u_int pane_id; u_int pane_id;
TAILQ_ENTRY(cmd_find_window_data) entry;
}; };
ARRAY_DECL(cmd_find_window_data_list, struct cmd_find_window_data); TAILQ_HEAD(cmd_find_window_list, cmd_find_window_data);
u_int cmd_find_window_match_flags(struct args *); static u_int cmd_find_window_match_flags(struct args *);
void cmd_find_window_match(struct cmd_find_window_data_list *, int, static void cmd_find_window_match(struct cmd_find_window_list *, int,
struct winlink *, const char *, const char *); struct winlink *, const char *, const char *);
u_int static u_int
cmd_find_window_match_flags(struct args *args) cmd_find_window_match_flags(struct args *args)
{ {
u_int match_flags = 0; u_int match_flags = 0;
@@ -84,16 +92,17 @@ cmd_find_window_match_flags(struct args *args)
return (match_flags); return (match_flags);
} }
void static void
cmd_find_window_match(struct cmd_find_window_data_list *find_list, cmd_find_window_match(struct cmd_find_window_list *find_list,
int match_flags, struct winlink *wl, const char *str, const char *searchstr) int match_flags, struct winlink *wl, const char *str,
const char *searchstr)
{ {
struct cmd_find_window_data find_data; struct cmd_find_window_data *find_data;
struct window_pane *wp; struct window_pane *wp;
u_int i, line; u_int i, line;
char *sres; char *sres;
memset(&find_data, 0, sizeof find_data); find_data = xcalloc(1, sizeof *find_data);
i = 0; i = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) { TAILQ_FOREACH(wp, &wl->window->panes, entry) {
@@ -101,52 +110,53 @@ cmd_find_window_match(struct cmd_find_window_data_list *find_list,
if ((match_flags & CMD_FIND_WINDOW_BY_NAME) && if ((match_flags & CMD_FIND_WINDOW_BY_NAME) &&
fnmatch(searchstr, wl->window->name, 0) == 0) { fnmatch(searchstr, wl->window->name, 0) == 0) {
find_data.list_ctx = xstrdup(""); find_data->list_ctx = xstrdup("");
break; break;
} }
if ((match_flags & CMD_FIND_WINDOW_BY_TITLE) && if ((match_flags & CMD_FIND_WINDOW_BY_TITLE) &&
fnmatch(searchstr, wp->base.title, 0) == 0) { fnmatch(searchstr, wp->base.title, 0) == 0) {
xasprintf(&find_data.list_ctx, xasprintf(&find_data->list_ctx,
"pane %u title: \"%s\"", i - 1, wp->base.title); "pane %u title: \"%s\"", i - 1, wp->base.title);
break; break;
} }
if (match_flags & CMD_FIND_WINDOW_BY_CONTENT && if (match_flags & CMD_FIND_WINDOW_BY_CONTENT &&
(sres = window_pane_search(wp, str, &line)) != NULL) { (sres = window_pane_search(wp, str, &line)) != NULL) {
xasprintf(&find_data.list_ctx, xasprintf(&find_data->list_ctx,
"pane %u line %u: \"%s\"", i - 1, line + 1, sres); "pane %u line %u: \"%s\"", i - 1, line + 1, sres);
free(sres); free(sres);
break; break;
} }
} }
if (find_data.list_ctx != NULL) {
find_data.wl = wl; if (find_data->list_ctx != NULL) {
find_data.pane_id = i - 1; find_data->wl = wl;
ARRAY_ADD(find_list, find_data); find_data->pane_id = i - 1;
} TAILQ_INSERT_TAIL(find_list, find_data, entry);
} else
free(find_data);
} }
enum cmd_retval static enum cmd_retval
cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_find_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c = item->state.c;
struct window_choose_data *cdata; struct window_choose_data *cdata;
struct session *s; struct session *s = item->state.tflag.s;
struct winlink *wl, *wm; struct winlink *wl = item->state.tflag.wl, *wm;
struct cmd_find_window_data_list find_list; struct cmd_find_window_list find_list;
struct cmd_find_window_data *find_data;
struct cmd_find_window_data *find_data1;
char *str, *searchstr; char *str, *searchstr;
const char *template; const char *template;
u_int i, match_flags; u_int i, match_flags;
if (ctx->curclient == NULL) { if (c == NULL) {
ctx->error(ctx, "must be run interactively"); cmdq_error(item, "no client available");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
s = ctx->curclient->session;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = FIND_WINDOW_TEMPLATE; template = FIND_WINDOW_TEMPLATE;
@@ -154,21 +164,20 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
match_flags = cmd_find_window_match_flags(args); match_flags = cmd_find_window_match_flags(args);
str = args->argv[0]; str = args->argv[0];
ARRAY_INIT(&find_list); TAILQ_INIT(&find_list);
xasprintf(&searchstr, "*%s*", str); xasprintf(&searchstr, "*%s*", str);
RB_FOREACH(wm, winlinks, &s->windows) RB_FOREACH(wm, winlinks, &s->windows)
cmd_find_window_match (&find_list, match_flags, wm, str, searchstr); cmd_find_window_match(&find_list, match_flags, wm, str, searchstr);
free(searchstr); free(searchstr);
if (ARRAY_LENGTH(&find_list) == 0) { if (TAILQ_EMPTY(&find_list)) {
ctx->error(ctx, "no windows matching: %s", str); cmdq_error(item, "no windows matching: %s", str);
ARRAY_FREE(&find_list);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (ARRAY_LENGTH(&find_list) == 1) { if (TAILQ_NEXT(TAILQ_FIRST(&find_list), entry) == NULL) {
if (session_select(s, ARRAY_FIRST(&find_list).wl->idx) == 0) if (session_select(s, TAILQ_FIRST(&find_list)->wl->idx) == 0)
server_redraw_session(s); server_redraw_session(s);
recalculate_sizes(); recalculate_sizes();
goto out; goto out;
@@ -177,35 +186,37 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
goto out; goto out;
for (i = 0; i < ARRAY_LENGTH(&find_list); i++) { i = 0;
wm = ARRAY_ITEM(&find_list, i).wl; TAILQ_FOREACH(find_data, &find_list, entry) {
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata = window_choose_data_create(ctx); cdata->idx = find_data->wl->idx;
cdata->idx = wm->idx; cdata->wl = find_data->wl;
cdata->client->references++;
cdata->wl = wm;
cdata->ft_template = xstrdup(template); cdata->ft_template = xstrdup(template);
cdata->pane_id = ARRAY_ITEM(&find_list, i).pane_id; cdata->pane_id = find_data->pane_id;
format_add(cdata->ft, "line", "%u", i); format_add(cdata->ft, "line", "%u", i);
format_add(cdata->ft, "window_find_matches", "%s", format_add(cdata->ft, "window_find_matches", "%s",
ARRAY_ITEM(&find_list, i).list_ctx); find_data->list_ctx);
format_session(cdata->ft, s); format_defaults(cdata->ft, NULL, s, find_data->wl, NULL);
format_winlink(cdata->ft, s, wm);
window_choose_add(wl->window->active, cdata); window_choose_add(wl->window->active, cdata);
i++;
} }
window_choose_ready(wl->window->active, window_choose_ready(wl->window->active, 0, cmd_find_window_callback);
0, cmd_find_window_callback, cmd_find_window_free);
out: out:
ARRAY_FREE(&find_list); TAILQ_FOREACH_SAFE(find_data, &find_list, entry, find_data1) {
free(find_data->list_ctx);
TAILQ_REMOVE(&find_list, find_data, entry);
free(find_data);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
void static void
cmd_find_window_callback(struct window_choose_data *cdata) cmd_find_window_callback(struct window_choose_data *cdata)
{ {
struct session *s; struct session *s;
@@ -214,7 +225,7 @@ cmd_find_window_callback(struct window_choose_data *cdata)
if (cdata == NULL) if (cdata == NULL)
return; return;
s = cdata->session; s = cdata->start_session;
if (!session_alive(s)) if (!session_alive(s))
return; return;
@@ -227,16 +238,3 @@ cmd_find_window_callback(struct window_choose_data *cdata)
recalculate_sizes(); recalculate_sizes();
} }
} }
void
cmd_find_window_free(struct window_choose_data *cdata)
{
if (cdata == NULL)
return;
cdata->session->references--;
free(cdata->ft_template);
format_free(cdata->ft);
free(cdata);
}

1295
cmd-find.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -29,92 +29,174 @@
* Executes a tmux command if a shell command returns true or false. * Executes a tmux command if a shell command returns true or false.
*/ */
enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmdq_item *);
void cmd_if_shell_callback(struct job *); static enum cmd_retval cmd_if_shell_error(struct cmdq_item *, void *);
void cmd_if_shell_free(void *); static void cmd_if_shell_callback(struct job *);
static void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = { const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if", .name = "if-shell",
"", 2, 3, .alias = "if",
"shell-command command [command]",
0, .args = { "bFt:", 2, 3 },
NULL, .usage = "[-bF] " CMD_TARGET_PANE_USAGE " shell-command command "
NULL, "[command]",
cmd_if_shell_exec
.tflag = CMD_PANE_CANFAIL,
.flags = 0,
.exec = cmd_if_shell_exec
}; };
struct cmd_if_shell_data { struct cmd_if_shell_data {
char *cmd_if; char *file;
char *cmd_else; u_int line;
struct cmd_ctx ctx;
char *cmd_if;
char *cmd_else;
struct client *client;
struct cmdq_item *item;
struct mouse_event mouse;
}; };
enum cmd_retval static enum cmd_retval
cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct cmd_if_shell_data *cdata; struct cmd_if_shell_data *cdata;
const char *shellcmd = args->argv[0]; char *shellcmd, *cmd, *cause;
struct cmd_list *cmdlist;
struct cmdq_item *new_item;
struct client *c = item->state.c;
struct session *s = item->state.tflag.s;
struct winlink *wl = item->state.tflag.wl;
struct window_pane *wp = item->state.tflag.wp;
const char *cwd;
if (item->client != NULL && item->client->session == NULL)
cwd = item->client->cwd;
else if (s != NULL)
cwd = s->cwd;
else
cwd = NULL;
shellcmd = format_single(item, args->argv[0], c, s, wl, wp);
if (args_has(args, 'F')) {
cmd = NULL;
if (*shellcmd != '0' && *shellcmd != '\0')
cmd = args->argv[1];
else if (args->argc == 3)
cmd = args->argv[2];
free(shellcmd);
if (cmd == NULL)
return (CMD_RETURN_NORMAL);
cmdlist = cmd_string_parse(cmd, NULL, 0, &cause);
if (cmdlist == NULL) {
if (cause != NULL) {
cmdq_error(item, "%s", cause);
free(cause);
}
return (CMD_RETURN_ERROR);
}
new_item = cmdq_get_command(cmdlist, NULL, &item->mouse, 0);
cmdq_insert_after(item, new_item);
cmd_list_free(cmdlist);
return (CMD_RETURN_NORMAL);
}
cdata = xcalloc(1, sizeof *cdata);
if (self->file != NULL) {
cdata->file = xstrdup(self->file);
cdata->line = self->line;
}
cdata = xmalloc(sizeof *cdata);
cdata->cmd_if = xstrdup(args->argv[1]); cdata->cmd_if = xstrdup(args->argv[1]);
if (args->argc == 3) if (args->argc == 3)
cdata->cmd_else = xstrdup(args->argv[2]); cdata->cmd_else = xstrdup(args->argv[2]);
else else
cdata->cmd_else = NULL; cdata->cmd_else = NULL;
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL) cdata->client = item->client;
ctx->cmdclient->references++; cdata->client->references++;
if (ctx->curclient != NULL)
ctx->curclient->references++;
job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata); if (!args_has(args, 'b'))
cdata->item = item;
else
cdata->item = NULL;
memcpy(&cdata->mouse, &item->mouse, sizeof cdata->mouse);
return (CMD_RETURN_YIELD); /* don't let client exit */ job_run(shellcmd, s, cwd, cmd_if_shell_callback, cmd_if_shell_free,
cdata);
free(shellcmd);
if (args_has(args, 'b'))
return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT);
} }
void static enum cmd_retval
cmd_if_shell_error(struct cmdq_item *item, void *data)
{
char *error = data;
cmdq_error(item, "%s", error);
free(error);
return (CMD_RETURN_NORMAL);
}
static void
cmd_if_shell_callback(struct job *job) cmd_if_shell_callback(struct job *job)
{ {
struct cmd_if_shell_data *cdata = job->data; struct cmd_if_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx; struct client *c = cdata->client;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
char *cause, *cmd; struct cmdq_item *new_item;
char *cause, *cmd, *file = cdata->file;
u_int line = cdata->line;
if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) { if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
cmd = cdata->cmd_else; cmd = cdata->cmd_else;
if (cmd == NULL) else
return;
} else
cmd = cdata->cmd_if; cmd = cdata->cmd_if;
if (cmd_string_parse(cmd, &cmdlist, &cause) != 0) { if (cmd == NULL)
if (cause != NULL) { goto out;
ctx->error(ctx, "%s", cause);
free(cause); cmdlist = cmd_string_parse(cmd, file, line, &cause);
} if (cmdlist == NULL) {
return; if (cause != NULL)
new_item = cmdq_get_callback(cmd_if_shell_error, cause);
else
new_item = NULL;
} else {
new_item = cmdq_get_command(cmdlist, NULL, &cdata->mouse, 0);
cmd_list_free(cmdlist);
} }
cmd_list_exec(cmdlist, ctx); if (new_item != NULL) {
cmd_list_free(cmdlist); if (cdata->item == NULL)
cmdq_append(c, new_item);
else
cmdq_insert_after(cdata->item, new_item);
}
out:
if (cdata->item != NULL)
cdata->item->flags &= ~CMDQ_WAITING;
} }
void static void
cmd_if_shell_free(void *data) cmd_if_shell_free(void *data)
{ {
struct cmd_if_shell_data *cdata = data; struct cmd_if_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
if (ctx->cmdclient != NULL) { server_client_unref(cdata->client);
ctx->cmdclient->references--;
ctx->cmdclient->flags |= CLIENT_EXIT;
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
free(cdata->cmd_else); free(cdata->cmd_else);
free(cdata->cmd_if); free(cdata->cmd_if);
free(cdata->file);
free(cdata); free(cdata);
} }

View File

@@ -1,8 +1,8 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2011 George Nachman <tmux@georgester.com> * Copyright (c) 2011 George Nachman <tmux@georgester.com>
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -28,53 +28,38 @@
* Join or move a pane into another (like split/swap/kill). * Join or move a pane into another (like split/swap/kill).
*/ */
void cmd_join_pane_key_binding(struct cmd *, int); static enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmd_ctx *);
enum cmd_retval join_pane(struct cmd *, struct cmd_ctx *, int);
const struct cmd_entry cmd_join_pane_entry = { const struct cmd_entry cmd_join_pane_entry = {
"join-pane", "joinp", .name = "join-pane",
"bdhvp:l:s:t:", 0, 0, .alias = "joinp",
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
0, .args = { "bdhvp:l:s:t:", 0, 0 },
cmd_join_pane_key_binding, .usage = "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
NULL,
cmd_join_pane_exec .sflag = CMD_PANE_MARKED,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_join_pane_exec
}; };
const struct cmd_entry cmd_move_pane_entry = { const struct cmd_entry cmd_move_pane_entry = {
"move-pane", "movep", .name = "move-pane",
"bdhvp:l:s:t:", 0, 0, .alias = "movep",
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
0, .args = { "bdhvp:l:s:t:", 0, 0 },
NULL, .usage = "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
NULL,
cmd_join_pane_exec .sflag = CMD_PANE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_join_pane_exec
}; };
void static enum cmd_retval
cmd_join_pane_key_binding(struct cmd *self, int key) cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
{
switch (key) {
case '%':
self->args = args_create(0);
args_set(self->args, 'h', NULL);
break;
default:
self->args = args_create(0);
break;
}
}
enum cmd_retval
cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
return (join_pane(self, ctx, self->entry == &cmd_join_pane_entry));
}
enum cmd_retval
join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *dst_s; struct session *dst_s;
@@ -85,24 +70,31 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window)
int size, percentage, dst_idx; int size, percentage, dst_idx;
enum layout_type type; enum layout_type type;
struct layout_cell *lc; struct layout_cell *lc;
int not_same_window;
dst_wl = cmd_find_pane(ctx, args_get(args, 't'), &dst_s, &dst_wp); if (self->entry == &cmd_join_pane_entry)
if (dst_wl == NULL) not_same_window = 1;
return (CMD_RETURN_ERROR); else
not_same_window = 0;
dst_s = item->state.tflag.s;
dst_wl = item->state.tflag.wl;
dst_wp = item->state.tflag.wp;
dst_w = dst_wl->window; dst_w = dst_wl->window;
dst_idx = dst_wl->idx; dst_idx = dst_wl->idx;
server_unzoom_window(dst_w);
src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp); src_wl = item->state.sflag.wl;
if (src_wl == NULL) src_wp = item->state.sflag.wp;
return (CMD_RETURN_ERROR);
src_w = src_wl->window; src_w = src_wl->window;
server_unzoom_window(src_w);
if (not_same_window && src_w == dst_w) { if (not_same_window && src_w == dst_w) {
ctx->error(ctx, "can't join a pane to its own window"); cmdq_error(item, "can't join a pane to its own window");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (!not_same_window && src_wp == dst_wp) { if (!not_same_window && src_wp == dst_wp) {
ctx->error(ctx, "source and target panes must be different"); cmdq_error(item, "source and target panes must be different");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@@ -114,14 +106,14 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window)
if (args_has(args, 'l')) { if (args_has(args, 'l')) {
size = args_strtonum(args, 'l', 0, INT_MAX, &cause); size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
if (cause != NULL) { if (cause != NULL) {
ctx->error(ctx, "size %s", cause); cmdq_error(item, "size %s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else if (args_has(args, 'p')) { } else if (args_has(args, 'p')) {
percentage = args_strtonum(args, 'p', 0, 100, &cause); percentage = args_strtonum(args, 'p', 0, 100, &cause);
if (cause != NULL) { if (cause != NULL) {
ctx->error(ctx, "percentage %s", cause); cmdq_error(item, "percentage %s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@@ -130,26 +122,17 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window)
else else
size = (dst_wp->sx * percentage) / 100; size = (dst_wp->sx * percentage) / 100;
} }
lc = layout_split_pane(dst_wp, type, size, args_has(args, 'b')); lc = layout_split_pane(dst_wp, type, size, args_has(args, 'b'), 0);
if (lc == NULL) { if (lc == NULL) {
ctx->error(ctx, "create pane failed: pane too small"); cmdq_error(item, "create pane failed: pane too small");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
layout_close_pane(src_wp); layout_close_pane(src_wp);
if (src_w->active == src_wp) { window_lost_pane(src_w, src_wp);
src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
if (src_w->active == NULL)
src_w->active = TAILQ_NEXT(src_wp, entry);
}
TAILQ_REMOVE(&src_w->panes, src_wp, entry); TAILQ_REMOVE(&src_w->panes, src_wp, entry);
if (window_count_panes(src_w) == 0)
server_kill_window(src_w);
else
notify_window_layout_changed(src_w);
src_wp->window = dst_w; src_wp->window = dst_w;
TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry); TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
layout_assign_pane(lc, src_wp); layout_assign_pane(lc, src_wp);
@@ -166,6 +149,11 @@ join_pane(struct cmd *self, struct cmd_ctx *ctx, int not_same_window)
} else } else
server_status_session(dst_s); server_status_session(dst_s);
notify_window_layout_changed(dst_w); if (window_count_panes(src_w) == 0)
server_kill_window(src_w);
else
notify_window("window-layout-changed", src_w);
notify_window("window-layout-changed", dst_w);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,34 +26,28 @@
* Kill pane. * Kill pane.
*/ */
enum cmd_retval cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_kill_pane_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_kill_pane_entry = { const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp", .name = "kill-pane",
"at:", 0, 0, .alias = "killp",
"[-a] " CMD_TARGET_PANE_USAGE,
0, .args = { "at:", 0, 0 },
NULL, .usage = "[-a] " CMD_TARGET_PANE_USAGE,
NULL,
cmd_kill_pane_exec .tflag = CMD_PANE,
.flags = 0,
.exec = cmd_kill_pane_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_kill_pane_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct winlink *wl = item->state.tflag.wl;
struct winlink *wl; struct window_pane *loopwp, *tmpwp, *wp = item->state.tflag.wp;
struct window_pane *loopwp, *tmpwp, *wp;
if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL) server_unzoom_window(wl->window);
return (CMD_RETURN_ERROR);
if (window_count_panes(wl->window) == 1) {
/* Only one pane, kill the window. */
server_kill_window(wl->window);
recalculate_sizes();
return (CMD_RETURN_NORMAL);
}
if (args_has(self->args, 'a')) { if (args_has(self->args, 'a')) {
TAILQ_FOREACH_SAFE(loopwp, &wl->window->panes, entry, tmpwp) { TAILQ_FOREACH_SAFE(loopwp, &wl->window->panes, entry, tmpwp) {
@@ -62,11 +56,17 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
layout_close_pane(loopwp); layout_close_pane(loopwp);
window_remove_pane(wl->window, loopwp); window_remove_pane(wl->window, loopwp);
} }
server_redraw_window(wl->window);
return (CMD_RETURN_NORMAL);
}
if (window_count_panes(wl->window) == 1) {
server_kill_window(wl->window);
recalculate_sizes();
} else { } else {
layout_close_pane(wp); layout_close_pane(wp);
window_remove_pane(wl->window, wp); window_remove_pane(wl->window, wp);
server_redraw_window(wl->window);
} }
server_redraw_window(wl->window);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,23 +27,35 @@
* Kill the server and do nothing else. * Kill the server and do nothing else.
*/ */
enum cmd_retval cmd_kill_server_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_kill_server_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_kill_server_entry = { const struct cmd_entry cmd_kill_server_entry = {
"kill-server", NULL, .name = "kill-server",
"", 0, 0, .alias = NULL,
"",
0, .args = { "", 0, 0 },
NULL, .usage = "",
NULL,
cmd_kill_server_exec .flags = 0,
.exec = cmd_kill_server_exec
}; };
/* ARGSUSED */ const struct cmd_entry cmd_start_server_entry = {
enum cmd_retval .name = "start-server",
cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx) .alias = "start",
.args = { "", 0, 0 },
.usage = "",
.flags = CMD_STARTSERVER,
.exec = cmd_kill_server_exec
};
static enum cmd_retval
cmd_kill_server_exec(struct cmd *self, __unused struct cmdq_item *item)
{ {
kill(getpid(), SIGTERM); if (self->entry == &cmd_kill_server_entry)
kill(getpid(), SIGTERM);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,32 +27,41 @@
* Note this deliberately has no alias to make it hard to hit by accident. * Note this deliberately has no alias to make it hard to hit by accident.
*/ */
enum cmd_retval cmd_kill_session_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_kill_session_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_kill_session_entry = { const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL, .name = "kill-session",
"at:", 0, 0, .alias = NULL,
"[-a] " CMD_TARGET_SESSION_USAGE,
0, .args = { "aCt:", 0, 0 },
NULL, .usage = "[-aC] " CMD_TARGET_SESSION_USAGE,
NULL,
cmd_kill_session_exec .tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_kill_session_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_kill_session_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s, *s2, *s3; struct session *s, *sloop, *stmp;
struct winlink *wl;
if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) s = item->state.tflag.s;
return (CMD_RETURN_ERROR);
if (args_has(args, 'a')) { if (args_has(args, 'C')) {
RB_FOREACH_SAFE(s2, sessions, &sessions, s3) { RB_FOREACH(wl, winlinks, &s->windows) {
if (s != s2) { wl->window->flags &= ~WINDOW_ALERTFLAGS;
server_destroy_session(s2); wl->flags &= ~WINLINK_ALERTFLAGS;
session_destroy(s2); }
server_redraw_session(s);
} else if (args_has(args, 'a')) {
RB_FOREACH_SAFE(sloop, sessions, &sessions, stmp) {
if (sloop != s) {
server_destroy_session(sloop);
session_destroy(sloop);
} }
} }
} else { } else {

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,35 +24,57 @@
* Destroy window. * Destroy window.
*/ */
enum cmd_retval cmd_kill_window_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_kill_window_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_kill_window_entry = { const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw", .name = "kill-window",
"at:", 0, 0, .alias = "killw",
"[-a] " CMD_TARGET_WINDOW_USAGE,
0, .args = { "at:", 0, 0 },
NULL, .usage = "[-a] " CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_kill_window_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_kill_window_exec
}; };
enum cmd_retval const struct cmd_entry cmd_unlink_window_entry = {
cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "unlink-window",
.alias = "unlinkw",
.args = { "kt:", 0, 0 },
.usage = "[-k] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_kill_window_exec
};
static enum cmd_retval
cmd_kill_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl, *wl2, *wl3; struct winlink *wl = item->state.tflag.wl, *wl2, *wl3;
struct session *s; struct window *w = wl->window;
struct session *s = item->state.tflag.s;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL) if (self->entry == &cmd_unlink_window_entry) {
return (CMD_RETURN_ERROR); if (!args_has(self->args, 'k') && !session_is_linked(s, w)) {
cmdq_error(item, "window only linked to one session");
if (args_has(args, 'a')) { return (CMD_RETURN_ERROR);
RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
if (wl != wl2)
server_kill_window(wl2->window);
} }
} else server_unlink_window(s, wl);
server_kill_window(wl->window); } else {
if (args_has(args, 'a')) {
RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
if (wl != wl2)
server_kill_window(wl2->window);
}
} else
server_kill_window(wl->window);
}
recalculate_sizes(); recalculate_sizes();
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,65 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Link a window into another session.
*/
enum cmd_retval cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"dks:t:", 0, 0,
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0,
NULL,
NULL,
cmd_link_window_exec
};
enum cmd_retval
cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct session *src, *dst;
struct winlink *wl;
char *cause;
int idx, kflag, dflag;
if ((wl = cmd_find_window(ctx, args_get(args, 's'), &src)) == NULL)
return (CMD_RETURN_ERROR);
if ((idx = cmd_find_index(ctx, args_get(args, 't'), &dst)) == -2)
return (CMD_RETURN_ERROR);
kflag = args_has(self->args, 'k');
dflag = args_has(self->args, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't link window: %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
recalculate_sizes();
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,40 +27,41 @@
* List paste buffers. * List paste buffers.
*/ */
enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *); #define LIST_BUFFERS_TEMPLATE \
"#{buffer_name}: #{buffer_size} bytes: \"#{buffer_sample}\""
static enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_list_buffers_entry = { const struct cmd_entry cmd_list_buffers_entry = {
"list-buffers", "lsb", .name = "list-buffers",
"F:", 0, 0, .alias = "lsb",
"[-F format]",
0, .args = { "F:", 0, 0 },
NULL, .usage = "[-F format]",
NULL,
cmd_list_buffers_exec .flags = CMD_AFTERHOOK,
.exec = cmd_list_buffers_exec
}; };
/* ARGSUSED */ static enum cmd_retval
enum cmd_retval cmd_list_buffers_exec(struct cmd *self, struct cmdq_item *item)
cmd_list_buffers_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct paste_buffer *pb; struct paste_buffer *pb;
struct format_tree *ft; struct format_tree *ft;
u_int idx;
char *line; char *line;
const char *template; const char *template;
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = LIST_BUFFERS_TEMPLATE; template = LIST_BUFFERS_TEMPLATE;
idx = 0; pb = NULL;
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) { while ((pb = paste_walk(pb)) != NULL) {
ft = format_create(); ft = format_create(item, FORMAT_NONE, 0);
format_add(ft, "line", "%u", idx - 1); format_defaults_paste_buffer(ft, pb);
format_paste_buffer(ft, pb);
line = format_expand(ft, template); line = format_expand(ft, template);
ctx->print(ctx, "%s", line); cmdq_print(item, "%s", line);
free(line); free(line);
format_free(ft); format_free(ft);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -28,58 +28,61 @@
* List all clients. * List all clients.
*/ */
int cmd_list_clients_exec(struct cmd *, struct cmd_ctx *); #define LIST_CLIENTS_TEMPLATE \
"#{client_name}: #{session_name} " \
"[#{client_width}x#{client_height} #{client_termname}]" \
"#{?client_utf8, (utf8),} #{?client_readonly, (ro),}"
static enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_list_clients_entry = { const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc", .name = "list-clients",
"F:t:", 0, 0, .alias = "lsc",
"[-F format] " CMD_TARGET_SESSION_USAGE,
CMD_READONLY, .args = { "F:t:", 0, 0 },
NULL, .usage = "[-F format] " CMD_TARGET_SESSION_USAGE,
NULL,
cmd_list_clients_exec .tflag = CMD_SESSION,
.flags = CMD_READONLY|CMD_AFTERHOOK,
.exec = cmd_list_clients_exec
}; };
/* ARGSUSED */ static enum cmd_retval
enum cmd_retval cmd_list_clients_exec(struct cmd *self, struct cmdq_item *item)
cmd_list_clients_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c; struct client *c;
struct session *s; struct session *s;
struct format_tree *ft; struct format_tree *ft;
const char *template; const char *template;
u_int i; u_int idx;
char *line; char *line;
if (args_has(args, 't')) { if (args_has(args, 't'))
s = cmd_find_session(ctx, args_get(args, 't'), 0); s = item->state.tflag.s;
if (s == NULL) else
return (CMD_RETURN_ERROR);
} else
s = NULL; s = NULL;
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = LIST_CLIENTS_TEMPLATE; template = LIST_CLIENTS_TEMPLATE;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { idx = 0;
c = ARRAY_ITEM(&clients, i); TAILQ_FOREACH(c, &clients, entry) {
if (c == NULL || c->session == NULL) if (c->session == NULL || (s != NULL && s != c->session))
continue; continue;
if (s != NULL && s != c->session) ft = format_create(item, FORMAT_NONE, 0);
continue; format_add(ft, "line", "%u", idx);
format_defaults(ft, c, NULL, NULL, NULL);
ft = format_create();
format_add(ft, "line", "%u", i);
format_session(ft, c->session);
format_client(ft, c);
line = format_expand(ft, template); line = format_expand(ft, template);
ctx->print(ctx, "%s", line); cmdq_print(item, "%s", line);
free(line); free(line);
format_free(ft); format_free(ft);
idx++;
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,6 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "tmux.h" #include "tmux.h"
@@ -26,123 +27,147 @@
* List key bindings. * List key bindings.
*/ */
enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_ctx *);
static enum cmd_retval cmd_list_keys_commands(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_list_keys_entry = { const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk", .name = "list-keys",
"t:", 0, 0, .alias = "lsk",
"[-t key-table]",
0, .args = { "T:", 0, 0 },
NULL, .usage = "[-T key-table]",
NULL,
cmd_list_keys_exec .flags = CMD_STARTSERVER|CMD_AFTERHOOK,
.exec = cmd_list_keys_exec
}; };
enum cmd_retval const struct cmd_entry cmd_list_commands_entry = {
cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "list-commands",
.alias = "lscm",
.args = { "F:", 0, 0 },
.usage = "[-F format]",
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
.exec = cmd_list_keys_exec
};
static enum cmd_retval
cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct key_table *table;
struct key_binding *bd; struct key_binding *bd;
const char *key; const char *key, *tablename, *r;
char tmp[BUFSIZ], flags[8]; char *cp, tmp[BUFSIZ];
size_t used; int repeat, width, tablewidth, keywidth;
int width, keywidth;
if (args_has(args, 't')) if (self->entry == &cmd_list_commands_entry)
return (cmd_list_keys_table(self, ctx)); return (cmd_list_keys_commands(self, item));
width = 0; tablename = args_get(args, 'T');
if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
RB_FOREACH(bd, key_bindings, &key_bindings) { cmdq_error(item, "table %s doesn't exist", tablename);
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
keywidth = strlen(key);
if (!(bd->key & KEYC_PREFIX)) {
if (bd->can_repeat)
keywidth += 4;
else
keywidth += 3;
} else if (bd->can_repeat)
keywidth += 3;
if (keywidth > width)
width = keywidth;
}
RB_FOREACH(bd, key_bindings, &key_bindings) {
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
*flags = '\0';
if (!(bd->key & KEYC_PREFIX)) {
if (bd->can_repeat)
xsnprintf(flags, sizeof flags, "-rn ");
else
xsnprintf(flags, sizeof flags, "-n ");
} else if (bd->can_repeat)
xsnprintf(flags, sizeof flags, "-r ");
used = xsnprintf(tmp, sizeof tmp, "%s%*s ",
flags, (int) (width - strlen(flags)), key);
if (used >= sizeof tmp)
continue;
cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
ctx->print(ctx, "bind-key %s", tmp);
}
return (CMD_RETURN_NORMAL);
}
int
cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
const char *tablename;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind;
const char *key, *cmdstr, *mode;
int width, keywidth, any_mode;
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
ctx->error(ctx, "unknown key table: %s", tablename);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
width = 0; repeat = 0;
any_mode = 0; tablewidth = keywidth = 0;
RB_FOREACH(mbind, mode_key_tree, mtab->tree) { RB_FOREACH(table, key_tables, &key_tables) {
key = key_string_lookup_key(mbind->key); if (tablename != NULL && strcmp(table->name, tablename) != 0)
if (key == NULL)
continue; continue;
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
key = key_string_lookup_key(bd->key);
if (mbind->mode != 0) if (bd->can_repeat)
any_mode = 1; repeat = 1;
keywidth = strlen(key); width = utf8_cstrwidth(table->name);
if (keywidth > width) if (width > tablewidth)
width = keywidth; tablewidth = width;
width = utf8_cstrwidth(key);
if (width > keywidth)
keywidth = width;
}
} }
RB_FOREACH(mbind, mode_key_tree, mtab->tree) { RB_FOREACH(table, key_tables, &key_tables) {
key = key_string_lookup_key(mbind->key); if (tablename != NULL && strcmp(table->name, tablename) != 0)
if (key == NULL)
continue; continue;
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
key = key_string_lookup_key(bd->key);
mode = ""; if (!repeat)
if (mbind->mode != 0) r = "";
mode = "c"; else if (bd->can_repeat)
cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd); r = "-r ";
if (cmdstr != NULL) { else
ctx->print(ctx, "bind-key -%st %s%s %*s %s", r = " ";
mode, any_mode && *mode == '\0' ? " " : "", xsnprintf(tmp, sizeof tmp, "%s-T ", r);
mtab->name, (int) width, key, cmdstr);
cp = utf8_padcstr(table->name, tablewidth);
strlcat(tmp, cp, sizeof tmp);
strlcat(tmp, " ", sizeof tmp);
free(cp);
cp = utf8_padcstr(key, keywidth);
strlcat(tmp, cp, sizeof tmp);
strlcat(tmp, " ", sizeof tmp);
free(cp);
cp = cmd_list_print(bd->cmdlist);
strlcat(tmp, cp, sizeof tmp);
free(cp);
cmdq_print(item, "bind-key %s", tmp);
} }
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
static enum cmd_retval
cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
const struct cmd_entry **entryp;
const struct cmd_entry *entry;
struct format_tree *ft;
const char *template, *s;
char *line;
if ((template = args_get(args, 'F')) == NULL) {
template = "#{command_list_name}"
"#{?command_list_alias, (#{command_list_alias}),} "
"#{command_list_usage}";
}
ft = format_create(item, FORMAT_NONE, 0);
format_defaults(ft, NULL, NULL, NULL, NULL);
for (entryp = cmd_table; *entryp != NULL; entryp++) {
entry = *entryp;
format_add(ft, "command_list_name", "%s", entry->name);
if (entry->alias != NULL)
s = entry->alias;
else
s = "";
format_add(ft, "command_list_alias", "%s", s);
if (entry->usage != NULL)
s = entry->usage;
else
s = "";
format_add(ft, "command_list_usage", "%s", s);
line = format_expand(ft, template);
if (*line != '\0')
cmdq_print(item, "%s", line);
free(line);
}
format_free(ft);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -27,70 +26,66 @@
* List panes on given window. * List panes on given window.
*/ */
enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmdq_item *);
void cmd_list_panes_server(struct cmd *, struct cmd_ctx *); static void cmd_list_panes_server(struct cmd *, struct cmdq_item *);
void cmd_list_panes_session( static void cmd_list_panes_session(struct cmd *, struct session *,
struct cmd *, struct session *, struct cmd_ctx *, int); struct cmdq_item *, int);
void cmd_list_panes_window(struct cmd *, static void cmd_list_panes_window(struct cmd *, struct session *,
struct session *, struct winlink *, struct cmd_ctx *, int); struct winlink *, struct cmdq_item *, int);
const struct cmd_entry cmd_list_panes_entry = { const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp", .name = "list-panes",
"asF:t:", 0, 0, .alias = "lsp",
"[-as] [-F format] [-t target]",
0, .args = { "asF:t:", 0, 0 },
NULL, .usage = "[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_list_panes_exec .tflag = CMD_WINDOW,
.flags = CMD_AFTERHOOK,
.exec = cmd_list_panes_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_list_panes_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s; struct session *s = item->state.tflag.s;
struct winlink *wl; struct winlink *wl = item->state.tflag.wl;
if (args_has(args, 'a')) if (args_has(args, 'a'))
cmd_list_panes_server(self, ctx); cmd_list_panes_server(self, item);
else if (args_has(args, 's')) { else if (args_has(args, 's'))
s = cmd_find_session(ctx, args_get(args, 't'), 0); cmd_list_panes_session(self, s, item, 1);
if (s == NULL) else
return (CMD_RETURN_ERROR); cmd_list_panes_window(self, s, wl, item, 0);
cmd_list_panes_session(self, s, ctx, 1);
} else {
wl = cmd_find_window(ctx, args_get(args, 't'), &s);
if (wl == NULL)
return (CMD_RETURN_ERROR);
cmd_list_panes_window(self, s, wl, ctx, 0);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
void static void
cmd_list_panes_server(struct cmd *self, struct cmd_ctx *ctx) cmd_list_panes_server(struct cmd *self, struct cmdq_item *item)
{ {
struct session *s; struct session *s;
RB_FOREACH(s, sessions, &sessions) RB_FOREACH(s, sessions, &sessions)
cmd_list_panes_session(self, s, ctx, 2); cmd_list_panes_session(self, s, item, 2);
} }
void static void
cmd_list_panes_session( cmd_list_panes_session(struct cmd *self, struct session *s,
struct cmd *self, struct session *s, struct cmd_ctx *ctx, int type) struct cmdq_item *item, int type)
{ {
struct winlink *wl; struct winlink *wl;
RB_FOREACH(wl, winlinks, &s->windows) RB_FOREACH(wl, winlinks, &s->windows)
cmd_list_panes_window(self, s, wl, ctx, type); cmd_list_panes_window(self, s, wl, item, type);
} }
void static void
cmd_list_panes_window(struct cmd *self, cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl,
struct session *s, struct winlink *wl, struct cmd_ctx *ctx, int type) struct cmdq_item *item, int type)
{ {
struct args *args = self->args; struct args *args = self->args;
struct window_pane *wp; struct window_pane *wp;
@@ -117,9 +112,9 @@ cmd_list_panes_window(struct cmd *self,
"#{?pane_active, (active),}#{?pane_dead, (dead),}"; "#{?pane_active, (active),}#{?pane_dead, (dead),}";
break; break;
case 2: case 2:
template = "#{session_name}:#{window_index}.#{pane_index}: " template = "#{session_name}:#{window_index}."
"[#{pane_width}x#{pane_height}] [history " "#{pane_index}: [#{pane_width}x#{pane_height}] "
"#{history_size}/#{history_limit}, " "[history #{history_size}/#{history_limit}, "
"#{history_bytes} bytes] #{pane_id}" "#{history_bytes} bytes] #{pane_id}"
"#{?pane_active, (active),}#{?pane_dead, (dead),}"; "#{?pane_active, (active),}#{?pane_dead, (dead),}";
break; break;
@@ -128,14 +123,12 @@ cmd_list_panes_window(struct cmd *self,
n = 0; n = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) { TAILQ_FOREACH(wp, &wl->window->panes, entry) {
ft = format_create(); ft = format_create(item, FORMAT_NONE, 0);
format_add(ft, "line", "%u", n); format_add(ft, "line", "%u", n);
format_session(ft, s); format_defaults(ft, NULL, s, wl, wp);
format_winlink(ft, s, wl);
format_window_pane(ft, wp);
line = format_expand(ft, template); line = format_expand(ft, template);
ctx->print(ctx, "%s", line); cmdq_print(item, "%s", line);
free(line); free(line);
format_free(ft); format_free(ft);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -28,20 +28,30 @@
* List all sessions. * List all sessions.
*/ */
enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *); #define LIST_SESSIONS_TEMPLATE \
"#{session_name}: #{session_windows} windows " \
"(created #{t:session_created}) " \
"[#{session_width}x#{session_height}]" \
"#{?session_grouped, (group ,}" \
"#{session_group}#{?session_grouped,),}" \
"#{?session_attached, (attached),}"
static enum cmd_retval cmd_list_sessions_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_list_sessions_entry = { const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", .name = "list-sessions",
"F:", 0, 0, .alias = "ls",
"[-F format]",
0, .args = { "F:", 0, 0 },
NULL, .usage = "[-F format]",
NULL,
cmd_list_sessions_exec .flags = CMD_AFTERHOOK,
.exec = cmd_list_sessions_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_list_sessions_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_list_sessions_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s; struct session *s;
@@ -55,12 +65,12 @@ cmd_list_sessions_exec(struct cmd *self, struct cmd_ctx *ctx)
n = 0; n = 0;
RB_FOREACH(s, sessions, &sessions) { RB_FOREACH(s, sessions, &sessions) {
ft = format_create(); ft = format_create(item, FORMAT_NONE, 0);
format_add(ft, "line", "%u", n); format_add(ft, "line", "%u", n);
format_session(ft, s); format_defaults(ft, NULL, s, NULL, NULL);
line = format_expand(ft, template); line = format_expand(ft, template);
ctx->print(ctx, "%s", line); cmdq_print(item, "%s", line);
free(line); free(line);
format_free(ft); format_free(ft);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,52 +27,62 @@
* List windows on given session. * List windows on given session.
*/ */
enum cmd_retval cmd_list_windows_exec(struct cmd *, struct cmd_ctx *); #define LIST_WINDOWS_TEMPLATE \
"#{window_index}: #{window_name}#{window_flags} " \
"(#{window_panes} panes) " \
"[#{window_width}x#{window_height}] " \
"[layout #{window_layout}] #{window_id}" \
"#{?window_active, (active),}";
#define LIST_WINDOWS_WITH_SESSION_TEMPLATE \
"#{session_name}:" \
"#{window_index}: #{window_name}#{window_flags} " \
"(#{window_panes} panes) " \
"[#{window_width}x#{window_height}] "
void cmd_list_windows_server(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_list_windows_exec(struct cmd *, struct cmdq_item *);
void cmd_list_windows_session(
struct cmd *, struct session *, struct cmd_ctx *, int); static void cmd_list_windows_server(struct cmd *, struct cmdq_item *);
static void cmd_list_windows_session(struct cmd *, struct session *,
struct cmdq_item *, int);
const struct cmd_entry cmd_list_windows_entry = { const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw", .name = "list-windows",
"F:at:", 0, 0, .alias = "lsw",
"[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
0, .args = { "F:at:", 0, 0 },
NULL, .usage = "[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
NULL,
cmd_list_windows_exec .tflag = CMD_SESSION,
.flags = CMD_AFTERHOOK,
.exec = cmd_list_windows_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_list_windows_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s;
if (args_has(args, 'a')) if (args_has(args, 'a'))
cmd_list_windows_server(self, ctx); cmd_list_windows_server(self, item);
else { else
s = cmd_find_session(ctx, args_get(args, 't'), 0); cmd_list_windows_session(self, item->state.tflag.s, item, 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
cmd_list_windows_session(self, s, ctx, 0);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
void static void
cmd_list_windows_server(struct cmd *self, struct cmd_ctx *ctx) cmd_list_windows_server(struct cmd *self, struct cmdq_item *item)
{ {
struct session *s; struct session *s;
RB_FOREACH(s, sessions, &sessions) RB_FOREACH(s, sessions, &sessions)
cmd_list_windows_session(self, s, ctx, 1); cmd_list_windows_session(self, s, item, 1);
} }
void static void
cmd_list_windows_session( cmd_list_windows_session(struct cmd *self, struct session *s,
struct cmd *self, struct session *s, struct cmd_ctx *ctx, int type) struct cmdq_item *item, int type)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl; struct winlink *wl;
@@ -95,13 +105,12 @@ cmd_list_windows_session(
n = 0; n = 0;
RB_FOREACH(wl, winlinks, &s->windows) { RB_FOREACH(wl, winlinks, &s->windows) {
ft = format_create(); ft = format_create(item, FORMAT_NONE, 0);
format_add(ft, "line", "%u", n); format_add(ft, "line", "%u", n);
format_session(ft, s); format_defaults(ft, NULL, s, wl, NULL);
format_winlink(ft, s, wl);
line = format_expand(ft, template); line = format_expand(ft, template);
ctx->print(ctx, "%s", line); cmdq_print(item, "%s", line);
free(line); free(line);
format_free(ft); format_free(ft);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,7 +24,8 @@
#include "tmux.h" #include "tmux.h"
struct cmd_list * struct cmd_list *
cmd_list_parse(int argc, char **argv, char **cause) cmd_list_parse(int argc, char **argv, const char *file, u_int line,
char **cause)
{ {
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd *cmd; struct cmd *cmd;
@@ -34,7 +35,7 @@ cmd_list_parse(int argc, char **argv, char **cause)
copy_argv = cmd_copy_argv(argc, argv); copy_argv = cmd_copy_argv(argc, argv);
cmdlist = xmalloc(sizeof *cmdlist); cmdlist = xcalloc(1, sizeof *cmdlist);
cmdlist->references = 1; cmdlist->references = 1;
TAILQ_INIT(&cmdlist->list); TAILQ_INIT(&cmdlist->list);
@@ -55,7 +56,7 @@ cmd_list_parse(int argc, char **argv, char **cause)
if (arglen != 1) if (arglen != 1)
new_argc++; new_argc++;
cmd = cmd_parse(new_argc, new_argv, cause); cmd = cmd_parse(new_argc, new_argv, file, line, cause);
if (cmd == NULL) if (cmd == NULL)
goto bad; goto bad;
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry); TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
@@ -64,7 +65,8 @@ cmd_list_parse(int argc, char **argv, char **cause)
} }
if (lastsplit != argc) { if (lastsplit != argc) {
cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit, cause); cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit,
file, line, cause);
if (cmd == NULL) if (cmd == NULL)
goto bad; goto bad;
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry); TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
@@ -79,93 +81,46 @@ bad:
return (NULL); return (NULL);
} }
enum cmd_retval
cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
{
struct client *c = ctx->curclient;
struct cmd *cmd;
enum cmd_retval retval;
int guards, n;
guards = 0;
if (c != NULL && c->session != NULL)
guards = c->flags & CLIENT_CONTROL;
notify_disable();
retval = 0;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (guards)
ctx->print(ctx, "%%begin");
n = cmd_exec(cmd, ctx);
if (guards)
ctx->print(ctx, "%%end");
switch (n)
{
case CMD_RETURN_ERROR:
return (CMD_RETURN_ERROR);
case CMD_RETURN_ATTACH:
/* Client is being attached (send MSG_READY). */
retval = CMD_RETURN_ATTACH;
/*
* Mangle the context to treat any following commands
* as if they were called from inside.
*/
if (ctx->curclient == NULL) {
ctx->curclient = ctx->cmdclient;
ctx->cmdclient = NULL;
ctx->error = key_bindings_error;
ctx->print = key_bindings_print;
ctx->info = key_bindings_info;
}
break;
case CMD_RETURN_YIELD:
if (retval == CMD_RETURN_NORMAL)
retval = CMD_RETURN_YIELD;
break;
case CMD_RETURN_NORMAL:
break;
}
}
notify_enable();
return (retval);
}
void void
cmd_list_free(struct cmd_list *cmdlist) cmd_list_free(struct cmd_list *cmdlist)
{ {
struct cmd *cmd; struct cmd *cmd, *cmd1;
if (--cmdlist->references != 0) if (--cmdlist->references != 0)
return; return;
while (!TAILQ_EMPTY(&cmdlist->list)) { TAILQ_FOREACH_SAFE(cmd, &cmdlist->list, qentry, cmd1) {
cmd = TAILQ_FIRST(&cmdlist->list);
TAILQ_REMOVE(&cmdlist->list, cmd, qentry); TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
cmd_free(cmd); args_free(cmd->args);
free(cmd->file);
free(cmd);
} }
free(cmdlist); free(cmdlist);
} }
size_t char *
cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len) cmd_list_print(struct cmd_list *cmdlist)
{ {
struct cmd *cmd; struct cmd *cmd;
size_t off; char *buf, *this;
size_t len;
len = 1;
buf = xcalloc(1, len);
off = 0;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (off >= len) this = cmd_print(cmd);
break;
off += cmd_print(cmd, buf + off, len - off); len += strlen(this) + 3;
if (off >= len) buf = xrealloc(buf, len);
break;
strlcat(buf, this, len);
if (TAILQ_NEXT(cmd, qentry) != NULL) if (TAILQ_NEXT(cmd, qentry) != NULL)
off += xsnprintf(buf + off, len - off, " ; "); strlcat(buf, " ; ", len);
free(this);
} }
return (off);
return (buf);
} }

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -19,6 +19,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -30,73 +31,65 @@
* Loads a paste buffer from a file. * Loads a paste buffer from a file.
*/ */
enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmdq_item *);
void cmd_load_buffer_callback(struct client *, int, void *);
static void cmd_load_buffer_callback(struct client *, int, void *);
const struct cmd_entry cmd_load_buffer_entry = { const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb", .name = "load-buffer",
"b:", 1, 1, .alias = "loadb",
CMD_BUFFER_USAGE " path",
0, .args = { "b:", 1, 1 },
NULL, .usage = CMD_BUFFER_USAGE " path",
NULL,
cmd_load_buffer_exec .flags = CMD_AFTERHOOK,
.exec = cmd_load_buffer_exec
}; };
enum cmd_retval struct cmd_load_buffer_data {
cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) struct cmdq_item *item;
{ char *bufname;
struct args *args = self->args; };
struct client *c = ctx->cmdclient;
struct session *s;
FILE *f;
const char *path, *newpath, *wd;
char *pdata, *new_pdata, *cause;
size_t psize;
u_int limit;
int ch, error, buffer, *buffer_ptr;
if (!args_has(args, 'b')) static enum cmd_retval
buffer = -1; cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item)
else { {
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); struct args *args = self->args;
if (cause != NULL) { struct cmd_load_buffer_data *cdata;
ctx->error(ctx, "buffer %s", cause); struct client *c = item->client;
free(cause); FILE *f;
return (CMD_RETURN_ERROR); const char *path, *bufname;
} char *pdata, *new_pdata, *cause, *file;
} size_t psize;
int ch, error;
bufname = NULL;
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
path = args->argv[0]; path = args->argv[0];
if (strcmp(path, "-") == 0) { if (strcmp(path, "-") == 0) {
buffer_ptr = xmalloc(sizeof *buffer_ptr); cdata = xcalloc(1, sizeof *cdata);
*buffer_ptr = buffer; cdata->item = item;
error = server_set_stdin_callback (c, cmd_load_buffer_callback, if (bufname != NULL)
buffer_ptr, &cause); cdata->bufname = xstrdup(bufname);
error = server_set_stdin_callback(c, cmd_load_buffer_callback,
cdata, &cause);
if (error != 0) { if (error != 0) {
ctx->error(ctx, "%s: %s", path, cause); cmdq_error(item, "%s: %s", path, cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
return (CMD_RETURN_YIELD); return (CMD_RETURN_WAIT);
} }
if (c != NULL) file = server_client_get_path(c, path);
wd = c->cwd; f = fopen(file, "rb");
else if ((s = cmd_current_session(ctx, 0)) != NULL) { if (f == NULL) {
wd = options_get_string(&s->options, "default-path"); cmdq_error(item, "%s: %s", file, strerror(errno));
if (*wd == '\0') free(file);
wd = s->cwd;
} else
wd = NULL;
if (wd != NULL && *wd != '\0') {
newpath = get_full_path(wd, path);
if (newpath != NULL)
path = newpath;
}
if ((f = fopen(path, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", path, strerror(errno));
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@@ -105,29 +98,26 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
while ((ch = getc(f)) != EOF) { while ((ch = getc(f)) != EOF) {
/* Do not let the server die due to memory exhaustion. */ /* Do not let the server die due to memory exhaustion. */
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) { if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
ctx->error(ctx, "realloc error: %s", strerror(errno)); cmdq_error(item, "realloc error: %s", strerror(errno));
goto error; goto error;
} }
pdata = new_pdata; pdata = new_pdata;
pdata[psize++] = ch; pdata[psize++] = ch;
} }
if (ferror(f)) { if (ferror(f)) {
ctx->error(ctx, "%s: read error", path); cmdq_error(item, "%s: read error", file);
goto error; goto error;
} }
if (pdata != NULL) if (pdata != NULL)
pdata[psize] = '\0'; pdata[psize] = '\0';
fclose(f); fclose(f);
free(file);
limit = options_get_number(&global_options, "buffer-limit"); if (paste_set(pdata, psize, bufname, &cause) != 0) {
if (buffer == -1) { cmdq_error(item, "%s", cause);
paste_add(&global_buffers, pdata, psize, limit);
return (CMD_RETURN_NORMAL);
}
if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
ctx->error(ctx, "no buffer %d", buffer);
free(pdata); free(pdata);
free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@@ -140,38 +130,44 @@ error:
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
void static void
cmd_load_buffer_callback(struct client *c, int closed, void *data) cmd_load_buffer_callback(struct client *c, int closed, void *data)
{ {
int *buffer = data; struct cmd_load_buffer_data *cdata = data;
char *pdata; char *pdata, *cause, *saved;
size_t psize; size_t psize;
u_int limit;
if (!closed) if (!closed)
return; return;
c->stdin_callback = NULL; c->stdin_callback = NULL;
c->references--; server_client_unref(c);
c->flags |= CLIENT_EXIT; if (c->flags & CLIENT_DEAD)
goto out;
psize = EVBUFFER_LENGTH(c->stdin_data); psize = EVBUFFER_LENGTH(c->stdin_data);
if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) { if (psize == 0 || (pdata = malloc(psize + 1)) == NULL)
free(data); goto out;
return;
}
memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize); memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize);
pdata[psize] = '\0'; pdata[psize] = '\0';
evbuffer_drain(c->stdin_data, psize); evbuffer_drain(c->stdin_data, psize);
limit = options_get_number(&global_options, "buffer-limit"); if (paste_set(pdata, psize, cdata->bufname, &cause) != 0) {
if (*buffer == -1)
paste_add(&global_buffers, pdata, psize, limit);
else if (paste_replace(&global_buffers, *buffer, pdata, psize) != 0) {
/* No context so can't use server_client_msg_error. */ /* No context so can't use server_client_msg_error. */
evbuffer_add_printf(c->stderr_data, "no buffer %d\n", *buffer); if (~c->flags & CLIENT_UTF8) {
server_push_stderr(c); saved = cause;
cause = utf8_sanitize(saved);
free(saved);
}
evbuffer_add_printf(c->stderr_data, "%s", cause);
server_client_push_stderr(c);
free(pdata);
free(cause);
} }
out:
cdata->item->flags &= ~CMDQ_WAITING;
free(data); free(cdata->bufname);
free(cdata);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,67 +18,61 @@
#include <sys/types.h> #include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
/* /*
* Lock commands. * Lock commands.
*/ */
enum cmd_retval cmd_lock_server_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_lock_server_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_lock_server_entry = { const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock", .name = "lock-server",
"", 0, 0, .alias = "lock",
"",
0, .args = { "", 0, 0 },
NULL, .usage = "",
NULL,
cmd_lock_server_exec .flags = CMD_AFTERHOOK,
.exec = cmd_lock_server_exec
}; };
const struct cmd_entry cmd_lock_session_entry = { const struct cmd_entry cmd_lock_session_entry = {
"lock-session", "locks", .name = "lock-session",
"t:", 0, 0, .alias = "locks",
CMD_TARGET_SESSION_USAGE,
0, .args = { "t:", 0, 0 },
NULL, .usage = CMD_TARGET_SESSION_USAGE,
NULL,
cmd_lock_server_exec .tflag = CMD_SESSION,
.flags = CMD_AFTERHOOK,
.exec = cmd_lock_server_exec
}; };
const struct cmd_entry cmd_lock_client_entry = { const struct cmd_entry cmd_lock_client_entry = {
"lock-client", "lockc", .name = "lock-client",
"t:", 0, 0, .alias = "lockc",
CMD_TARGET_CLIENT_USAGE,
0, .args = { "t:", 0, 0 },
NULL, .usage = CMD_TARGET_CLIENT_USAGE,
NULL,
cmd_lock_server_exec .tflag = CMD_CLIENT,
.flags = CMD_AFTERHOOK,
.exec = cmd_lock_server_exec
}; };
/* ARGSUSED */ static enum cmd_retval
enum cmd_retval cmd_lock_server_exec(struct cmd *self, __unused struct cmdq_item *item)
cmd_lock_server_exec(struct cmd *self, unused struct cmd_ctx *ctx)
{ {
struct args *args = self->args;
struct client *c;
struct session *s;
if (self->entry == &cmd_lock_server_entry) if (self->entry == &cmd_lock_server_entry)
server_lock(); server_lock();
else if (self->entry == &cmd_lock_session_entry) { else if (self->entry == &cmd_lock_session_entry)
if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) server_lock_session(item->state.tflag.s);
return (CMD_RETURN_ERROR); else
server_lock_session(s); server_lock_client(item->state.c);
} else {
if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (CMD_RETURN_ERROR);
server_lock_client(c);
}
recalculate_sizes(); recalculate_sizes();
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,50 +26,79 @@
* Move a window. * Move a window.
*/ */
enum cmd_retval cmd_move_window_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_move_window_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_move_window_entry = { const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew", .name = "move-window",
"dkrs:t:", 0, 0, .alias = "movew",
"[-dkr] " CMD_SRCDST_WINDOW_USAGE,
0, .args = { "adkrs:t:", 0, 0 },
NULL, .usage = "[-dkr] " CMD_SRCDST_WINDOW_USAGE,
NULL,
cmd_move_window_exec .sflag = CMD_WINDOW,
.tflag = CMD_MOVEW_R,
.flags = 0,
.exec = cmd_move_window_exec
}; };
enum cmd_retval const struct cmd_entry cmd_link_window_entry = {
cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "link-window",
.alias = "linkw",
.args = { "adks:t:", 0, 0 },
.usage = "[-dk] " CMD_SRCDST_WINDOW_USAGE,
.sflag = CMD_WINDOW,
.tflag = CMD_WINDOW_INDEX,
.flags = 0,
.exec = cmd_move_window_exec
};
static enum cmd_retval
cmd_move_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *src, *dst, *s; struct session *src = item->state.sflag.s;
struct winlink *wl; struct session *dst = item->state.tflag.s;
struct winlink *wl = item->state.sflag.wl;
char *cause; char *cause;
int idx, kflag, dflag; int idx = item->state.tflag.idx, kflag, dflag, sflag;
if (args_has(args, 'r')) { if (args_has(args, 'r')) {
if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) session_renumber_windows(dst);
return (CMD_RETURN_ERROR);
session_renumber_windows(s);
recalculate_sizes(); recalculate_sizes();
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
if ((wl = cmd_find_window(ctx, args_get(args, 's'), &src)) == NULL)
return (CMD_RETURN_ERROR);
if ((idx = cmd_find_index(ctx, args_get(args, 't'), &dst)) == -2)
return (CMD_RETURN_ERROR);
kflag = args_has(self->args, 'k'); kflag = args_has(self->args, 'k');
dflag = args_has(self->args, 'd'); dflag = args_has(self->args, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) { sflag = args_has(self->args, 's');
ctx->error(ctx, "can't move window: %s", cause);
if (args_has(self->args, 'a')) {
if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1)
return (CMD_RETURN_ERROR);
}
if (server_link_window(src, wl, dst, idx, kflag, !dflag,
&cause) != 0) {
cmdq_error(item, "can't link window: %s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
server_unlink_window(src, wl); if (self->entry == &cmd_move_window_entry)
server_unlink_window(src, wl);
/*
* Renumber the winlinks in the src session only, the destination
* session already has the correct winlink id to us, either
* automatically or specified by -s.
*/
if (!sflag && options_get_number(src->options, "renumber-windows"))
session_renumber_windows(src);
recalculate_sizes(); recalculate_sizes();
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +18,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <pwd.h> #include <errno.h>
#include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <termios.h> #include <termios.h>
@@ -30,152 +31,189 @@
* Create a new session and attach to the current terminal unless -d is given. * Create a new session and attach to the current terminal unless -d is given.
*/ */
enum cmd_retval cmd_new_session_check(struct args *); #define NEW_SESSION_TEMPLATE "#{session_name}:"
enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmd_ctx *);
static enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_new_session_entry = { const struct cmd_entry cmd_new_session_entry = {
"new-session", "new", .name = "new-session",
"dn:s:t:x:y:", 0, 1, .alias = "new",
"[-d] [-n window-name] [-s session-name] [-t target-session] "
"[-x width] [-y height] [command]", .args = { "Ac:dDEF:n:Ps:t:x:y:", 0, -1 },
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, .usage = "[-AdDEP] [-c start-directory] [-F format] [-n window-name] "
NULL, "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
cmd_new_session_check, "[-y height] [command]",
cmd_new_session_exec
.tflag = CMD_SESSION_CANFAIL,
.flags = CMD_STARTSERVER,
.exec = cmd_new_session_exec
}; };
enum cmd_retval const struct cmd_entry cmd_has_session_entry = {
cmd_new_session_check(struct args *args) .name = "has-session",
{ .alias = "has",
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n')))
return (CMD_RETURN_ERROR);
return (CMD_RETURN_NORMAL);
}
enum cmd_retval .args = { "t:", 0, 0 },
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) .usage = CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_new_session_exec
};
static enum cmd_retval
cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s, *old_s, *groupwith; struct client *c = item->client;
struct session *s, *as, *groupwith;
struct window *w; struct window *w;
struct window_pane *wp; struct environ *env;
struct environ env;
struct termios tio, *tiop; struct termios tio, *tiop;
struct passwd *pw; struct session_group *sg;
const char *newname, *target, *update, *cwd, *errstr; const char *newname, *errstr, *template, *group, *prefix;
char *cmd, *cause; const char *path, *cmd, *cwd, *to_free = NULL;
int detached, idx; char **argv, *cause, *cp;
u_int sx, sy, i; int detached, already_attached, idx, argc;
u_int sx, sy;
struct environ_entry *envent;
struct cmd_find_state fs;
if (self->entry == &cmd_has_session_entry) {
/*
* cmd_prepare() will fail if the session cannot be found,
* hence always return success here.
*/
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
cmdq_error(item, "command or window name given with target");
return (CMD_RETURN_ERROR);
}
newname = args_get(args, 's'); newname = args_get(args, 's');
if (newname != NULL) { if (newname != NULL) {
if (!session_check_name(newname)) { if (!session_check_name(newname)) {
ctx->error(ctx, "bad session name: %s", newname); cmdq_error(item, "bad session name: %s", newname);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (session_find(newname) != NULL) { if ((as = session_find(newname)) != NULL) {
ctx->error(ctx, "duplicate session: %s", newname); if (args_has(args, 'A')) {
/*
* This item is now destined for
* attach-session. Because attach-session will
* have already been prepared, copy this
* session into its tflag so it can be used.
*/
cmd_find_from_session(&item->state.tflag, as);
return (cmd_attach_session(item,
args_has(args, 'D'), 0, NULL,
args_has(args, 'E')));
}
cmdq_error(item, "duplicate session: %s", newname);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} }
target = args_get(args, 't'); /* Is this going to be part of a session group? */
if (target != NULL) { group = args_get(args, 't');
groupwith = cmd_find_session(ctx, target, 0); if (group != NULL) {
if (groupwith == NULL) groupwith = item->state.tflag.s;
return (CMD_RETURN_ERROR); if (groupwith == NULL) {
} else if (!session_check_name(group)) {
cmdq_error(item, "bad group name: %s", group);
goto error;
}
sg = session_group_find(group);
} else
sg = session_group_contains(groupwith);
if (sg != NULL)
prefix = sg->name;
else if (groupwith != NULL)
prefix = groupwith->name;
else
prefix = group;
} else {
groupwith = NULL; groupwith = NULL;
sg = NULL;
/* prefix = NULL;
* There are three cases: }
*
* 1. If cmdclient is non-NULL, new-session has been called from the
* command-line - cmdclient is to become a new attached, interactive
* client. Unless -d is given, the terminal must be opened and then
* the client sent MSG_READY.
*
* 2. If cmdclient is NULL, new-session has been called from an
* existing client (such as a key binding).
*
* 3. Both are NULL, the command was in the configuration file. Treat
* this as if -d was given even if it was not.
*
* In all cases, a new additional session needs to be created and
* (unless -d) set as the current session for the client.
*/
/* Set -d if no client. */ /* Set -d if no client. */
detached = args_has(args, 'd'); detached = args_has(args, 'd');
if (ctx->cmdclient == NULL && ctx->curclient == NULL) if (c == NULL)
detached = 1; detached = 1;
/* Is this client already attached? */
already_attached = 0;
if (c != NULL && c->session != NULL)
already_attached = 1;
/* Get the new session working directory. */
if (args_has(args, 'c')) {
cwd = args_get(args, 'c');
to_free = cwd = format_single(item, cwd, c, NULL, NULL, NULL);
} else if (c != NULL && c->session == NULL && c->cwd != NULL)
cwd = c->cwd;
else
cwd = ".";
/* /*
* Save the termios settings, part of which is used for new windows in * If this is a new client, check for nesting and save the termios
* this session. * settings (part of which is used for new windows in this session).
* *
* This is read again with tcgetattr() rather than using tty.tio as if * tcgetattr() is used rather than using tty.tio since if the client is
* detached, tty_open won't be called. Because of this, it must be done * detached, tty_open won't be called. It must be done before opening
* before opening the terminal as that calls tcsetattr() to prepare for * the terminal as that calls tcsetattr() to prepare for tmux taking
* tmux taking over. * over.
*/ */
if (ctx->cmdclient != NULL && ctx->cmdclient->tty.fd != -1) { if (!detached && !already_attached && c->tty.fd != -1) {
if (tcgetattr(ctx->cmdclient->tty.fd, &tio) != 0) if (server_client_check_nested(item->client)) {
cmdq_error(item, "sessions should be nested with care, "
"unset $TMUX to force");
return (CMD_RETURN_ERROR);
}
if (tcgetattr(c->tty.fd, &tio) != 0)
fatal("tcgetattr failed"); fatal("tcgetattr failed");
tiop = &tio; tiop = &tio;
} else } else
tiop = NULL; tiop = NULL;
/* Open the terminal if necessary. */ /* Open the terminal if necessary. */
if (!detached && ctx->cmdclient != NULL) { if (!detached && !already_attached) {
if (server_client_open(ctx->cmdclient, NULL, &cause) != 0) { if (server_client_open(c, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause); cmdq_error(item, "open terminal failed: %s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); goto error;
} }
} }
/* Get the new session working directory. */
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
cwd = ctx->cmdclient->cwd;
else {
pw = getpwuid(getuid());
if (pw->pw_dir != NULL && *pw->pw_dir != '\0')
cwd = pw->pw_dir;
else
cwd = "/";
}
/* Find new session size. */ /* Find new session size. */
if (ctx->cmdclient != NULL) { if (c != NULL) {
sx = ctx->cmdclient->tty.sx; sx = c->tty.sx;
sy = ctx->cmdclient->tty.sy; sy = c->tty.sy;
} else if (ctx->curclient != NULL) {
sx = ctx->curclient->tty.sx;
sy = ctx->curclient->tty.sy;
} else { } else {
sx = 80; sx = 80;
sy = 24; sy = 24;
} }
if (detached) { if (detached && args_has(args, 'x')) {
if (args_has(args, 'x')) { sx = strtonum(args_get(args, 'x'), 1, USHRT_MAX, &errstr);
sx = strtonum( if (errstr != NULL) {
args_get(args, 'x'), 1, USHRT_MAX, &errstr); cmdq_error(item, "width %s", errstr);
if (errstr != NULL) { goto error;
ctx->error(ctx, "width %s", errstr);
return (CMD_RETURN_ERROR);
}
}
if (args_has(args, 'y')) {
sy = strtonum(
args_get(args, 'y'), 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "height %s", errstr);
return (CMD_RETURN_ERROR);
}
} }
} }
if (sy > 0 && options_get_number(&global_s_options, "status")) if (detached && args_has(args, 'y')) {
sy = strtonum(args_get(args, 'y'), 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(item, "height %s", errstr);
goto error;
}
}
if (sy > 0 && options_get_number(global_s_options, "status"))
sy--; sy--;
if (sx == 0) if (sx == 0)
sx = 1; sx = 1;
@@ -183,72 +221,89 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
sy = 1; sy = 1;
/* Figure out the command for the new window. */ /* Figure out the command for the new window. */
if (target != NULL) argc = -1;
cmd = NULL; argv = NULL;
else if (args->argc != 0) if (!args_has(args, 't') && args->argc != 0) {
cmd = args->argv[0]; argc = args->argc;
argv = args->argv;
} else if (sg == NULL && groupwith == NULL) {
cmd = options_get_string(global_s_options, "default-command");
if (cmd != NULL && *cmd != '\0') {
argc = 1;
argv = (char **)&cmd;
} else {
argc = 0;
argv = NULL;
}
}
path = NULL;
if (c != NULL && c->session == NULL)
envent = environ_find(c->environ, "PATH");
else else
cmd = options_get_string(&global_s_options, "default-command"); envent = environ_find(global_environ, "PATH");
if (envent != NULL)
path = envent->value;
/* Construct the environment. */ /* Construct the environment. */
environ_init(&env); env = environ_create();
update = options_get_string(&global_s_options, "update-environment"); if (c != NULL && !args_has(args, 'E'))
if (ctx->cmdclient != NULL) environ_update(global_s_options, c->environ, env);
environ_update(update, &ctx->cmdclient->environ, &env);
/* Create the new session. */ /* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index"); idx = -1 - options_get_number(global_s_options, "base-index");
s = session_create(newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause); s = session_create(prefix, newname, argc, argv, path, cwd, env, tiop,
idx, sx, sy, &cause);
environ_free(env);
if (s == NULL) { if (s == NULL) {
ctx->error(ctx, "create session failed: %s", cause); cmdq_error(item, "create session failed: %s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); goto error;
} }
environ_free(&env);
/* Set the initial window name if one given. */ /* Set the initial window name if one given. */
if (cmd != NULL && args_has(args, 'n')) { if (argc >= 0 && args_has(args, 'n')) {
w = s->curw->window; w = s->curw->window;
window_set_name(w, args_get(args, 'n')); window_set_name(w, args_get(args, 'n'));
options_set_number(w->options, "automatic-rename", 0);
options_set_number(&w->options, "automatic-rename", 0);
} }
/* /*
* If a target session is given, this is to be part of a session group, * If a target session is given, this is to be part of a session group,
* so add it to the group and synchronize. * so add it to the group and synchronize.
*/ */
if (groupwith != NULL) { if (group != NULL) {
session_group_add(groupwith, s); if (sg == NULL) {
if (groupwith != NULL) {
sg = session_group_new(groupwith->name);
session_group_add(sg, groupwith);
} else
sg = session_group_new(group);
}
session_group_add(sg, s);
session_group_synchronize_to(s); session_group_synchronize_to(s);
session_select(s, RB_ROOT(&s->windows)->idx); session_select(s, RB_MIN(winlinks, &s->windows)->idx);
} }
notify_session("session-created", s);
/* /*
* Set the client to the new session. If a command client exists, it is * Set the client to the new session. If a command client exists, it is
* taking this session and needs to get MSG_READY and stay around. * taking this session and needs to get MSG_READY and stay around.
*/ */
if (!detached) { if (!detached) {
if (ctx->cmdclient != NULL) { if (!already_attached) {
server_write_ready(ctx->cmdclient); if (~c->flags & CLIENT_CONTROL)
proc_send(c->peer, MSG_READY, -1, NULL, 0);
old_s = ctx->cmdclient->session; } else if (c->session != NULL)
if (old_s != NULL) c->last_session = c->session;
ctx->cmdclient->last_session = old_s; c->session = s;
ctx->cmdclient->session = s; if (!item->repeat)
notify_attached_session_changed(ctx->cmdclient); server_client_set_key_table(c, NULL);
session_update_activity(s); status_timer_start(c);
server_redraw_client(ctx->cmdclient); notify_client("client-session-changed", c);
} else { session_update_activity(s, NULL);
old_s = ctx->curclient->session; gettimeofday(&s->last_attached_time, NULL);
if (old_s != NULL) server_redraw_client(c);
ctx->curclient->last_session = old_s;
ctx->curclient->session = s;
notify_attached_session_changed(ctx->curclient);
session_update_activity(s);
server_redraw_client(ctx->curclient);
}
} }
recalculate_sizes(); recalculate_sizes();
server_update_socket(); server_update_socket();
@@ -257,17 +312,31 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
* If there are still configuration file errors to display, put the new * If there are still configuration file errors to display, put the new
* session's current window into more mode and display them now. * session's current window into more mode and display them now.
*/ */
if (cfg_finished && !ARRAY_EMPTY(&cfg_causes)) { if (cfg_finished)
wp = s->curw->window->active; cfg_show_causes(s);
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp); /* Print if requested. */
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) { if (args_has(args, 'P')) {
cause = ARRAY_ITEM(&cfg_causes, i); if ((template = args_get(args, 'F')) == NULL)
window_copy_add(wp, "%s", cause); template = NEW_SESSION_TEMPLATE;
free(cause); cp = format_single(item, template, c, s, NULL, NULL);
} cmdq_print(item, "%s", cp);
ARRAY_FREE(&cfg_causes); free(cp);
} }
return (detached ? CMD_RETURN_NORMAL : CMD_RETURN_ATTACH); if (!detached)
c->flags |= CLIENT_ATTACHED;
if (to_free != NULL)
free((void *)to_free);
cmd_find_from_session(&fs, s);
hooks_insert(s->hooks, item, &fs, "after-new-session");
return (CMD_RETURN_NORMAL);
error:
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_ERROR);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +18,11 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -26,61 +30,77 @@
* Create a new window. * Create a new window.
*/ */
int cmd_new_window_exec(struct cmd *, struct cmd_ctx *); #define NEW_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
static enum cmd_retval cmd_new_window_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_new_window_entry = { const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww", .name = "new-window",
"ac:dF:kn:Pt:", 0, 1, .alias = "neww",
"[-adkP] [-c start-directory] [-F format] [-n window-name] "
"[-t target-window] [command]", .args = { "ac:dF:kn:Pt:", 0, -1 },
0, .usage = "[-adkP] [-c start-directory] [-F format] [-n window-name] "
NULL, CMD_TARGET_WINDOW_USAGE " [command]",
NULL,
cmd_new_window_exec .tflag = CMD_WINDOW_INDEX,
.flags = 0,
.exec = cmd_new_window_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s; struct session *s = item->state.tflag.s;
struct winlink *wl; struct winlink *wl = item->state.tflag.wl;
struct client *c; struct client *c = item->state.c;
const char *cmd, *cwd; int idx = item->state.tflag.idx;
const char *template; const char *cmd, *path, *template, *cwd, *to_free;
char *cause; char **argv, *cause, *cp;
int idx, last, detached; int argc, detached;
struct format_tree *ft; struct environ_entry *envent;
char *cp; struct cmd_find_state fs;
if (args_has(args, 'a')) { if (args_has(args, 'a')) {
wl = cmd_find_window(ctx, args_get(args, 't'), &s); if ((idx = winlink_shuffle_up(s, wl)) == -1) {
if (wl == NULL) cmdq_error(item, "no free window indexes");
return (CMD_RETURN_ERROR);
idx = wl->idx + 1;
/* Find the next free index. */
for (last = idx; last < INT_MAX; last++) {
if (winlink_find_by_index(&s->windows, last) == NULL)
break;
}
if (last == INT_MAX) {
ctx->error(ctx, "no free window indexes");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
/* Move everything from last - 1 to idx up a bit. */
for (; last > idx; last--) {
wl = winlink_find_by_index(&s->windows, last - 1);
server_link_window(s, wl, s, last, 0, 0, NULL);
server_unlink_window(s, wl);
}
} else {
if ((idx = cmd_find_index(ctx, args_get(args, 't'), &s)) == -2)
return (CMD_RETURN_ERROR);
} }
detached = args_has(args, 'd'); detached = args_has(args, 'd');
if (args->argc == 0) {
cmd = options_get_string(s->options, "default-command");
if (cmd != NULL && *cmd != '\0') {
argc = 1;
argv = (char **)&cmd;
} else {
argc = 0;
argv = NULL;
}
} else {
argc = args->argc;
argv = args->argv;
}
path = NULL;
if (item->client != NULL && item->client->session == NULL)
envent = environ_find(item->client->environ, "PATH");
else
envent = environ_find(s->environ, "PATH");
if (envent != NULL)
path = envent->value;
to_free = NULL;
if (args_has(args, 'c')) {
cwd = args_get(args, 'c');
to_free = cwd = format_single(item, cwd, c, s, NULL, NULL);
} else if (item->client != NULL && item->client->session == NULL)
cwd = item->client->cwd;
else
cwd = s->cwd;
wl = NULL; wl = NULL;
if (idx != -1) if (idx != -1)
wl = winlink_find_by_index(&s->windows, idx); wl = winlink_find_by_index(&s->windows, idx);
@@ -89,7 +109,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
* Can't use session_detach as it will destroy session if this * Can't use session_detach as it will destroy session if this
* makes it empty. * makes it empty.
*/ */
notify_window_unlinked(s, wl->window); notify_session_window("window-unlinked", s, wl->window);
wl->flags &= ~WINLINK_ALERTFLAGS; wl->flags &= ~WINLINK_ALERTFLAGS;
winlink_stack_remove(&s->lastw, wl); winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl); winlink_remove(&s->windows, wl);
@@ -101,19 +121,14 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
} }
if (args->argc == 0)
cmd = options_get_string(&s->options, "default-command");
else
cmd = args->argv[0];
cwd = cmd_get_default_path(ctx, args_get(args, 'c'));
if (idx == -1) if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index"); idx = -1 - options_get_number(s->options, "base-index");
wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause); wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
&cause);
if (wl == NULL) { if (wl == NULL) {
ctx->error(ctx, "create window failed: %s", cause); cmdq_error(item, "create window failed: %s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); goto error;
} }
if (!detached) { if (!detached) {
session_select(s, wl->idx); session_select(s, wl->idx);
@@ -124,20 +139,21 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (args_has(args, 'P')) { if (args_has(args, 'P')) {
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = NEW_WINDOW_TEMPLATE; template = NEW_WINDOW_TEMPLATE;
cp = format_single(item, template, c, s, wl, NULL);
ft = format_create(); cmdq_print(item, "%s", cp);
if ((c = cmd_find_client(ctx, NULL)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wl->window->active);
cp = format_expand(ft, template);
ctx->print(ctx, "%s", cp);
free(cp); free(cp);
format_free(ft);
} }
if (to_free != NULL)
free((void *)to_free);
cmd_find_from_winlink(&fs, s, wl);
hooks_insert(s->hooks, item, &fs, "after-new-window");
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
error:
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_ERROR);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,58 +27,47 @@
* Paste paste buffer if present. * Paste paste buffer if present.
*/ */
enum cmd_retval cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_paste_buffer_exec(struct cmd *, struct cmdq_item *);
void cmd_paste_buffer_filter(struct window_pane *,
const char *, size_t, const char *, int bracket);
const struct cmd_entry cmd_paste_buffer_entry = { const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb", .name = "paste-buffer",
"db:prs:t:", 0, 0, .alias = "pasteb",
"[-dpr] [-s separator] [-b buffer-index] [-t target-pane]",
0, .args = { "db:prs:t:", 0, 0 },
NULL, .usage = "[-dpr] [-s separator] " CMD_BUFFER_USAGE " "
NULL, CMD_TARGET_PANE_USAGE,
cmd_paste_buffer_exec
.tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_paste_buffer_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct window_pane *wp; struct window_pane *wp = item->state.tflag.wp;
struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
const char *sepstr; const char *sepstr, *bufname, *bufdata, *bufend, *line;
char *cause; size_t seplen, bufsize;
int buffer; int bracket = args_has(args, 'p');
int pflag;
if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL) bufname = NULL;
return (CMD_RETURN_ERROR); if (args_has(args, 'b'))
bufname = args_get(args, 'b');
if (!args_has(args, 'b')) if (bufname == NULL)
buffer = -1; pb = paste_get_top(NULL);
else { else {
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); pb = paste_get_name(bufname);
if (cause != NULL) {
ctx->error(ctx, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
}
if (buffer == -1)
pb = paste_get_top(&global_buffers);
else {
pb = paste_get_index(&global_buffers, buffer);
if (pb == NULL) { if (pb == NULL) {
ctx->error(ctx, "no buffer %d", buffer); cmdq_error(item, "no buffer %s", bufname);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} }
if (pb != NULL) { if (pb != NULL && ~wp->flags & PANE_INPUTOFF) {
sepstr = args_get(args, 's'); sepstr = args_get(args, 's');
if (sepstr == NULL) { if (sepstr == NULL) {
if (args_has(args, 'r')) if (args_has(args, 'r'))
@@ -86,45 +75,33 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
else else
sepstr = "\r"; sepstr = "\r";
} }
pflag = args_has(args, 'p') && seplen = strlen(sepstr);
(wp->screen->mode & MODE_BRACKETPASTE);
cmd_paste_buffer_filter(wp, pb->data, pb->size, sepstr, pflag); if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
bufferevent_write(wp->event, "\033[200~", 6);
bufdata = paste_buffer_data(pb, &bufsize);
bufend = bufdata + bufsize;
for (;;) {
line = memchr(bufdata, '\n', bufend - bufdata);
if (line == NULL)
break;
bufferevent_write(wp->event, bufdata, line - bufdata);
bufferevent_write(wp->event, sepstr, seplen);
bufdata = line + 1;
}
if (bufdata != bufend)
bufferevent_write(wp->event, bufdata, bufend - bufdata);
if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
bufferevent_write(wp->event, "\033[201~", 6);
} }
/* Delete the buffer if -d. */ if (pb != NULL && args_has(args, 'd'))
if (args_has(args, 'd')) { paste_free(pb);
if (buffer == -1)
paste_free_top(&global_buffers);
else
paste_free_index(&global_buffers, buffer);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
/* Add bytes to a buffer and filter '\n' according to separator. */
void
cmd_paste_buffer_filter(struct window_pane *wp,
const char *data, size_t size, const char *sep, int bracket)
{
const char *end = data + size;
const char *lf;
size_t seplen;
if (bracket)
bufferevent_write(wp->event, "\033[200~", 6);
seplen = strlen(sep);
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
bufferevent_write(wp->event, data, lf - data);
bufferevent_write(wp->event, sep, seplen);
data = lf + 1;
}
if (end != data)
bufferevent_write(wp->event, data, end - data);
if (bracket)
bufferevent_write(wp->event, "\033[201~", 6);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +21,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
@@ -31,32 +32,34 @@
* Open pipe to redirect pane output. If already open, close first. * Open pipe to redirect pane output. If already open, close first.
*/ */
enum cmd_retval cmd_pipe_pane_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_pipe_pane_exec(struct cmd *, struct cmdq_item *);
void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *); static void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
const struct cmd_entry cmd_pipe_pane_entry = { const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep", .name = "pipe-pane",
"ot:", 0, 1, .alias = "pipep",
"[-o] " CMD_TARGET_PANE_USAGE " [command]",
0, .args = { "ot:", 0, 1 },
NULL, .usage = "[-o] " CMD_TARGET_PANE_USAGE " [command]",
NULL,
cmd_pipe_pane_exec .tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_pipe_pane_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c; struct client *c = item->state.c;
struct window_pane *wp; struct window_pane *wp = item->state.tflag.wp;
char *command; struct session *s = item->state.tflag.s;
struct winlink *wl = item->state.tflag.wl;
char *cmd;
int old_fd, pipe_fd[2], null_fd; int old_fd, pipe_fd[2], null_fd;
struct format_tree *ft;
if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
c = cmd_find_client(ctx, NULL);
/* Destroy the old pipe. */ /* Destroy the old pipe. */
old_fd = wp->pipe_fd; old_fd = wp->pipe_fd;
@@ -81,14 +84,22 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Open the new pipe. */ /* Open the new pipe. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) { if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
ctx->error(ctx, "socketpair error: %s", strerror(errno)); cmdq_error(item, "socketpair error: %s", strerror(errno));
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
/* Expand the command. */
ft = format_create(item, FORMAT_NONE, 0);
format_defaults(ft, c, s, wl, wp);
cmd = format_expand_time(ft, args->argv[0], time(NULL));
format_free(ft);
/* Fork the child. */ /* Fork the child. */
switch (fork()) { switch (fork()) {
case -1: case -1:
ctx->error(ctx, "fork error: %s", strerror(errno)); cmdq_error(item, "fork error: %s", strerror(errno));
free(cmd);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
case 0: case 0:
/* Child process. */ /* Child process. */
@@ -110,9 +121,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
closefrom(STDERR_FILENO + 1); closefrom(STDERR_FILENO + 1);
command = status_replace( execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
c, NULL, NULL, NULL, args->argv[0], time(NULL), 0);
execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
_exit(1); _exit(1);
default: default:
/* Parent process. */ /* Parent process. */
@@ -126,14 +135,15 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
bufferevent_enable(wp->pipe_event, EV_WRITE); bufferevent_enable(wp->pipe_event, EV_WRITE);
setblocking(wp->pipe_fd, 0); setblocking(wp->pipe_fd, 0);
free(cmd);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
} }
/* ARGSUSED */ static void
void cmd_pipe_pane_error_callback(__unused struct bufferevent *bufev,
cmd_pipe_pane_error_callback( __unused short what, void *data)
unused struct bufferevent *bufev, unused short what, void *data)
{ {
struct window_pane *wp = data; struct window_pane *wp = data;

445
cmd-queue.c Normal file
View File

@@ -0,0 +1,445 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "tmux.h"
/* Global command queue. */
static struct cmdq_list global_queue = TAILQ_HEAD_INITIALIZER(global_queue);
/* Get command queue name. */
static const char *
cmdq_name(struct client *c)
{
static char s[32];
if (c == NULL)
return ("<global>");
xsnprintf(s, sizeof s, "<%p>", c);
return (s);
}
/* Get command queue from client. */
static struct cmdq_list *
cmdq_get(struct client *c)
{
if (c == NULL)
return (&global_queue);
return (&c->queue);
}
/* Append an item. */
void
cmdq_append(struct client *c, struct cmdq_item *item)
{
struct cmdq_list *queue = cmdq_get(c);
struct cmdq_item *next;
do {
next = item->next;
item->next = NULL;
if (c != NULL)
c->references++;
item->client = c;
item->queue = queue;
TAILQ_INSERT_TAIL(queue, item, entry);
item = next;
} while (item != NULL);
}
/* Insert an item. */
void
cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
{
struct client *c = after->client;
struct cmdq_list *queue = after->queue;
struct cmdq_item *next;
do {
next = item->next;
item->next = NULL;
if (c != NULL)
c->references++;
item->client = c;
item->queue = queue;
if (after->next != NULL)
TAILQ_INSERT_AFTER(queue, after->next, item, entry);
else
TAILQ_INSERT_AFTER(queue, after, item, entry);
after->next = item;
item = next;
} while (item != NULL);
}
/* Remove an item. */
static void
cmdq_remove(struct cmdq_item *item)
{
if (item->formats != NULL)
format_free(item->formats);
if (item->client != NULL)
server_client_unref(item->client);
if (item->type == CMDQ_COMMAND)
cmd_list_free(item->cmdlist);
TAILQ_REMOVE(item->queue, item, entry);
free((void *)item->name);
free(item);
}
/* Set command group. */
static u_int
cmdq_next_group(void)
{
static u_int group;
return (++group);
}
/* Remove all subsequent items that match this item's group. */
static void
cmdq_remove_group(struct cmdq_item *item)
{
struct cmdq_item *this, *next;
this = TAILQ_NEXT(item, entry);
while (this != NULL) {
next = TAILQ_NEXT(this, entry);
if (this->group == item->group)
cmdq_remove(this);
this = next;
}
}
/* Get a command for the command queue. */
struct cmdq_item *
cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current,
struct mouse_event *m, int flags)
{
struct cmdq_item *item, *first = NULL, *last = NULL;
struct cmd *cmd;
u_int group = cmdq_next_group();
char *tmp;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
xasprintf(&tmp, "command[%s]", cmd->entry->name);
item = xcalloc(1, sizeof *item);
item->name = tmp;
item->type = CMDQ_COMMAND;
item->group = group;
item->flags = flags;
item->cmdlist = cmdlist;
item->cmd = cmd;
if (current != NULL)
cmd_find_copy_state(&item->current, current);
if (m != NULL)
memcpy(&item->mouse, m, sizeof item->mouse);
cmdlist->references++;
if (first == NULL)
first = item;
if (last != NULL)
last->next = item;
last = item;
}
return (first);
}
/* Fire command on command queue. */
static enum cmd_retval
cmdq_fire_command(struct cmdq_item *item)
{
struct client *c = item->client;
struct cmd *cmd = item->cmd;
enum cmd_retval retval;
const char *name;
struct cmd_find_state *fsp, fs;
int flags;
flags = !!(cmd->flags & CMD_CONTROL);
cmdq_guard(item, "begin", flags);
if (cmd_prepare_state(cmd, item) != 0) {
retval = CMD_RETURN_ERROR;
goto out;
}
if (item->client == NULL)
item->client = cmd_find_client(item, NULL, CMD_FIND_QUIET);
retval = cmd->entry->exec(cmd, item);
if (retval == CMD_RETURN_ERROR)
goto out;
if (cmd->entry->flags & CMD_AFTERHOOK) {
name = cmd->entry->name;
if (cmd_find_valid_state(&item->state.tflag))
fsp = &item->state.tflag;
else {
if (cmd_find_current(&fs, item, CMD_FIND_QUIET) != 0)
goto out;
fsp = &fs;
}
hooks_insert(fsp->s->hooks, item, fsp, "after-%s", name);
}
out:
item->client = c;
if (retval == CMD_RETURN_ERROR)
cmdq_guard(item, "error", flags);
else
cmdq_guard(item, "end", flags);
return (retval);
}
/* Get a callback for the command queue. */
struct cmdq_item *
cmdq_get_callback1(const char *name, cmdq_cb cb, void *data)
{
struct cmdq_item *item;
char *tmp;
xasprintf(&tmp, "callback[%s]", name);
item = xcalloc(1, sizeof *item);
item->name = tmp;
item->type = CMDQ_CALLBACK;
item->group = 0;
item->flags = 0;
item->cb = cb;
item->data = data;
return (item);
}
/* Fire callback on callback queue. */
static enum cmd_retval
cmdq_fire_callback(struct cmdq_item *item)
{
return (item->cb(item, item->data));
}
/* Add a format to command queue. */
void
cmdq_format(struct cmdq_item *item, const char *key, const char *fmt, ...)
{
va_list ap;
struct cmdq_item *loop;
char *value;
va_start(ap, fmt);
xvasprintf(&value, fmt, ap);
va_end(ap);
for (loop = item; loop != NULL; loop = item->next) {
if (loop->formats == NULL)
loop->formats = format_create(NULL, FORMAT_NONE, 0);
format_add(loop->formats, key, "%s", value);
}
free(value);
}
/* Process next item on command queue. */
u_int
cmdq_next(struct client *c)
{
struct cmdq_list *queue = cmdq_get(c);
const char *name = cmdq_name(c);
struct cmdq_item *item;
enum cmd_retval retval;
u_int items = 0;
static u_int number;
if (TAILQ_EMPTY(queue)) {
log_debug("%s %s: empty", __func__, name);
return (0);
}
if (TAILQ_FIRST(queue)->flags & CMDQ_WAITING) {
log_debug("%s %s: waiting", __func__, name);
return (0);
}
log_debug("%s %s: enter", __func__, name);
for (;;) {
item = TAILQ_FIRST(queue);
if (item == NULL)
break;
log_debug("%s %s: %s (%d), flags %x", __func__, name,
item->name, item->type, item->flags);
/*
* Any item with the waiting flag set waits until an external
* event clears the flag (for example, a job - look at
* run-shell).
*/
if (item->flags & CMDQ_WAITING)
goto waiting;
/*
* Items are only fired once, once the fired flag is set, a
* waiting flag can only be cleared by an external event.
*/
if (~item->flags & CMDQ_FIRED) {
item->time = time(NULL);
item->number = ++number;
switch (item->type)
{
case CMDQ_COMMAND:
retval = cmdq_fire_command(item);
/*
* If a command returns an error, remove any
* subsequent commands in the same group.
*/
if (retval == CMD_RETURN_ERROR)
cmdq_remove_group(item);
break;
case CMDQ_CALLBACK:
retval = cmdq_fire_callback(item);
break;
default:
retval = CMD_RETURN_ERROR;
break;
}
item->flags |= CMDQ_FIRED;
if (retval == CMD_RETURN_WAIT) {
item->flags |= CMDQ_WAITING;
goto waiting;
}
items++;
}
cmdq_remove(item);
}
log_debug("%s %s: exit (empty)", __func__, name);
return (items);
waiting:
log_debug("%s %s: exit (wait)", __func__, name);
return (items);
}
/* Print a guard line. */
void
cmdq_guard(struct cmdq_item *item, const char *guard, int flags)
{
struct client *c = item->client;
if (c == NULL || !(c->flags & CLIENT_CONTROL))
return;
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
(long)item->time, item->number, flags);
server_client_push_stdout(c);
}
/* Show message from command. */
void
cmdq_print(struct cmdq_item *item, const char *fmt, ...)
{
struct client *c = item->client;
struct window *w;
va_list ap;
char *tmp, *msg;
va_start(ap, fmt);
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
if (~c->flags & CLIENT_UTF8) {
xvasprintf(&tmp, fmt, ap);
msg = utf8_sanitize(tmp);
free(tmp);
evbuffer_add(c->stdout_data, msg, strlen(msg));
free(msg);
} else
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_client_push_stdout(c);
} else {
w = c->session->curw->window;
if (w->active->mode != &window_copy_mode) {
window_pane_reset_mode(w->active);
window_pane_set_mode(w->active, &window_copy_mode);
window_copy_init_for_output(w->active);
}
window_copy_vadd(w->active, fmt, ap);
}
va_end(ap);
}
/* Show error from command. */
void
cmdq_error(struct cmdq_item *item, const char *fmt, ...)
{
struct client *c = item->client;
struct cmd *cmd = item->cmd;
va_list ap;
char *msg;
size_t msglen;
char *tmp;
va_start(ap, fmt);
msglen = xvasprintf(&msg, fmt, ap);
va_end(ap);
if (c == NULL)
cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
if (~c->flags & CLIENT_UTF8) {
tmp = msg;
msg = utf8_sanitize(tmp);
free(tmp);
msglen = strlen(msg);
}
evbuffer_add(c->stderr_data, msg, msglen);
evbuffer_add(c->stderr_data, "\n", 1);
server_client_push_stderr(c);
c->retval = 1;
} else {
*msg = toupper((u_char) *msg);
status_message_set(c, "%s", msg);
}
free(msg);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,32 +24,57 @@
* Refresh client. * Refresh client.
*/ */
enum cmd_retval cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_refresh_client_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_refresh_client_entry = { const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh", .name = "refresh-client",
"St:", 0, 0, .alias = "refresh",
"[-S] " CMD_TARGET_CLIENT_USAGE,
0, .args = { "C:St:", 0, 0 },
NULL, .usage = "[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
NULL,
cmd_refresh_client_exec .tflag = CMD_CLIENT,
.flags = CMD_AFTERHOOK,
.exec = cmd_refresh_client_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_refresh_client_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c; struct client *c = item->state.c;
const char *size;
u_int w, h;
if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL) if (args_has(args, 'C')) {
return (CMD_RETURN_ERROR); if ((size = args_get(args, 'C')) == NULL) {
cmdq_error(item, "missing size");
if (args_has(args, 'S')) { return (CMD_RETURN_ERROR);
status_update_jobs(c); }
if (sscanf(size, "%u,%u", &w, &h) != 2) {
cmdq_error(item, "bad size argument");
return (CMD_RETURN_ERROR);
}
if (w < PANE_MINIMUM || w > 5000 ||
h < PANE_MINIMUM || h > 5000) {
cmdq_error(item, "size too small or too big");
return (CMD_RETURN_ERROR);
}
if (!(c->flags & CLIENT_CONTROL)) {
cmdq_error(item, "not a control client");
return (CMD_RETURN_ERROR);
}
if (tty_set_size(&c->tty, w, h))
recalculate_sizes();
} else if (args_has(args, 'S')) {
c->flags |= CLIENT_STATUSFORCE;
server_status_client(c); server_status_client(c);
} else } else {
c->flags |= CLIENT_STATUSFORCE;
server_redraw_client(c); server_redraw_client(c);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +19,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
@@ -26,45 +27,49 @@
* Change session name. * Change session name.
*/ */
enum cmd_retval cmd_rename_session_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_rename_session_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_rename_session_entry = { const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename", .name = "rename-session",
"t:", 1, 1, .alias = "rename",
CMD_TARGET_SESSION_USAGE " new-name",
0, .args = { "t:", 1, 1 },
NULL, .usage = CMD_TARGET_SESSION_USAGE " new-name",
NULL,
cmd_rename_session_exec .tflag = CMD_SESSION,
.flags = CMD_AFTERHOOK,
.exec = cmd_rename_session_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s; struct session *s = item->state.tflag.s;
const char *newname; const char *newname;
newname = args->argv[0]; newname = args->argv[0];
if (strcmp(newname, s->name) == 0)
return (CMD_RETURN_NORMAL);
if (!session_check_name(newname)) { if (!session_check_name(newname)) {
ctx->error(ctx, "bad session name: %s", newname); cmdq_error(item, "bad session name: %s", newname);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (session_find(newname) != NULL) { if (session_find(newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", newname); cmdq_error(item, "duplicate session: %s", newname);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
RB_REMOVE(sessions, &sessions, s); RB_REMOVE(sessions, &sessions, s);
free(s->name); free(s->name);
s->name = xstrdup(newname); s->name = xstrdup(newname);
RB_INSERT(sessions, &sessions, s); RB_INSERT(sessions, &sessions, s);
server_status_session(s); server_status_session(s);
notify_session_renamed(s); notify_session("session-renamed", s);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,30 +26,30 @@
* Rename a window. * Rename a window.
*/ */
enum cmd_retval cmd_rename_window_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_rename_window_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_rename_window_entry = { const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew", .name = "rename-window",
"t:", 1, 1, .alias = "renamew",
CMD_TARGET_WINDOW_USAGE " new-name",
0, .args = { "t:", 1, 1 },
NULL, .usage = CMD_TARGET_WINDOW_USAGE " new-name",
NULL,
cmd_rename_window_exec .tflag = CMD_WINDOW,
.flags = CMD_AFTERHOOK,
.exec = cmd_rename_window_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_rename_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s; struct winlink *wl = item->state.tflag.wl;
struct winlink *wl;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
window_set_name(wl->window, args->argv[0]); window_set_name(wl->window, args->argv[0]);
options_set_number(&wl->window->options, "automatic-rename", 0); options_set_number(wl->window->options, "automatic-rename", 0);
server_status_window(wl->window); server_status_window(wl->window);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,93 +26,149 @@
* Increase or decrease pane size. * Increase or decrease pane size.
*/ */
void cmd_resize_pane_key_binding(struct cmd *, int); static enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
static void cmd_resize_pane_mouse_update(struct client *,
struct mouse_event *);
const struct cmd_entry cmd_resize_pane_entry = { const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep", .name = "resize-pane",
"DLRt:U", 0, 1, .alias = "resizep",
"[-DLRU] " CMD_TARGET_PANE_USAGE " [adjustment]",
0, .args = { "DLMRt:Ux:y:Z", 0, 1 },
cmd_resize_pane_key_binding, .usage = "[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " "
NULL, "[adjustment]",
cmd_resize_pane_exec
.tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_resize_pane_exec
}; };
void static enum cmd_retval
cmd_resize_pane_key_binding(struct cmd *self, int key) cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
{
switch (key) {
case KEYC_UP | KEYC_CTRL:
self->args = args_create(0);
args_set(self->args, 'U', NULL);
break;
case KEYC_DOWN | KEYC_CTRL:
self->args = args_create(0);
args_set(self->args, 'D', NULL);
break;
case KEYC_LEFT | KEYC_CTRL:
self->args = args_create(0);
args_set(self->args, 'L', NULL);
break;
case KEYC_RIGHT | KEYC_CTRL:
self->args = args_create(0);
args_set(self->args, 'R', NULL);
break;
case KEYC_UP | KEYC_ESCAPE:
self->args = args_create(1, "5");
args_set(self->args, 'U', NULL);
break;
case KEYC_DOWN | KEYC_ESCAPE:
self->args = args_create(1, "5");
args_set(self->args, 'D', NULL);
break;
case KEYC_LEFT | KEYC_ESCAPE:
self->args = args_create(1, "5");
args_set(self->args, 'L', NULL);
break;
case KEYC_RIGHT | KEYC_ESCAPE:
self->args = args_create(1, "5");
args_set(self->args, 'R', NULL);
break;
default:
self->args = args_create(0);
break;
}
}
enum cmd_retval
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl; struct window_pane *wp = item->state.tflag.wp;
struct winlink *wl = item->state.tflag.wl;
struct window *w = wl->window;
struct client *c = item->client;
struct session *s = item->state.tflag.s;
const char *errstr; const char *errstr;
struct window_pane *wp; char *cause;
u_int adjust; u_int adjust;
int x, y;
if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL) if (args_has(args, 'M')) {
return (CMD_RETURN_ERROR); if (cmd_mouse_window(&item->mouse, &s) == NULL)
return (CMD_RETURN_NORMAL);
if (c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update;
cmd_resize_pane_mouse_update(c, &item->mouse);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'Z')) {
if (w->flags & WINDOW_ZOOMED)
window_unzoom(w);
else
window_zoom(wp);
server_redraw_window(w);
server_status_window(w);
return (CMD_RETURN_NORMAL);
}
server_unzoom_window(w);
if (args->argc == 0) if (args->argc == 0)
adjust = 1; adjust = 1;
else { else {
adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr); adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
ctx->error(ctx, "adjustment %s", errstr); cmdq_error(item, "adjustment %s", errstr);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} }
layout_list_add(wp->window); if (args_has(self->args, 'x')) {
x = args_strtonum(self->args, 'x', PANE_MINIMUM, INT_MAX,
&cause);
if (cause != NULL) {
cmdq_error(item, "width %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
layout_resize_pane_to(wp, LAYOUT_LEFTRIGHT, x);
}
if (args_has(self->args, 'y')) {
y = args_strtonum(self->args, 'y', PANE_MINIMUM, INT_MAX,
&cause);
if (cause != NULL) {
cmdq_error(item, "height %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
layout_resize_pane_to(wp, LAYOUT_TOPBOTTOM, y);
}
if (args_has(self->args, 'L')) if (args_has(self->args, 'L'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust); layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust, 1);
else if (args_has(self->args, 'R')) else if (args_has(self->args, 'R'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust); layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust, 1);
else if (args_has(self->args, 'U')) else if (args_has(self->args, 'U'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust); layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust, 1);
else if (args_has(self->args, 'D')) else if (args_has(self->args, 'D'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust); layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust, 1);
server_redraw_window(wl->window); server_redraw_window(wl->window);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
static void
cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
{
struct winlink *wl;
struct window_pane *wp;
int found;
u_int y, ly;
wl = cmd_mouse_window(m, NULL);
if (wl == NULL) {
c->tty.mouse_drag_update = NULL;
return;
}
y = m->y;
if (m->statusat == 0 && y > 0)
y--;
else if (m->statusat > 0 && y >= (u_int)m->statusat)
y = m->statusat - 1;
ly = m->ly;
if (m->statusat == 0 && ly > 0)
ly--;
else if (m->statusat > 0 && ly >= (u_int)m->statusat)
ly = m->statusat - 1;
found = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
if (!window_pane_visible(wp))
continue;
if (wp->xoff + wp->sx == m->lx &&
wp->yoff <= 1 + ly &&
wp->yoff + wp->sy >= ly) {
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, m->x - m->lx, 0);
found = 1;
}
if (wp->yoff + wp->sy == ly &&
wp->xoff <= 1 + m->lx &&
wp->xoff + wp->sx >= m->lx) {
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, y - ly, 0);
found = 1;
}
}
if (found)
server_redraw_window(wl->window);
else
c->tty.mouse_drag_update = NULL;
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* Copyright (c) 2011 Marcel P. Partap <mpartap@gmx.net> * Copyright (c) 2011 Marcel P. Partap <mpartap@gmx.net>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@@ -28,65 +28,67 @@
* Respawn a pane (restart the command). Kill existing if -k given. * Respawn a pane (restart the command). Kill existing if -k given.
*/ */
enum cmd_retval cmd_respawn_pane_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_respawn_pane_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_respawn_pane_entry = { const struct cmd_entry cmd_respawn_pane_entry = {
"respawn-pane", "respawnp", .name = "respawn-pane",
"kt:", 0, 1, .alias = "respawnp",
"[-k] " CMD_TARGET_PANE_USAGE " [command]",
0, .args = { "kt:", 0, -1 },
NULL, .usage = "[-k] " CMD_TARGET_PANE_USAGE " [command]",
NULL,
cmd_respawn_pane_exec .tflag = CMD_PANE,
.flags = 0,
.exec = cmd_respawn_pane_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_respawn_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl; struct winlink *wl = item->state.tflag.wl;
struct window *w; struct window *w = wl->window;
struct window_pane *wp; struct window_pane *wp = item->state.tflag.wp;
struct session *s; struct session *s = item->state.tflag.s;
struct environ env; struct environ *env;
const char *cmd; const char *path;
char *cause; char *cause;
u_int idx; u_int idx;
struct environ_entry *envent;
if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (!args_has(self->args, 'k') && wp->fd != -1) { if (!args_has(self->args, 'k') && wp->fd != -1) {
if (window_pane_index(wp, &idx) != 0) if (window_pane_index(wp, &idx) != 0)
fatalx("index not found"); fatalx("index not found");
ctx->error(ctx, "pane still active: %s:%u.%u", cmdq_error(item, "pane still active: %s:%d.%u",
s->name, wl->idx, idx); s->name, wl->idx, idx);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
environ_init(&env);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
window_pane_reset_mode(wp); window_pane_reset_mode(wp);
screen_reinit(&wp->base); screen_reinit(&wp->base);
input_init(wp); input_init(wp);
if (args->argc != 0) path = NULL;
cmd = args->argv[0]; if (item->client != NULL && item->client->session == NULL)
envent = environ_find(item->client->environ, "PATH");
else else
cmd = NULL; envent = environ_find(s->environ, "PATH");
if (window_pane_spawn(wp, cmd, NULL, NULL, &env, s->tio, &cause) != 0) { if (envent != NULL)
ctx->error(ctx, "respawn pane failed: %s", cause); path = envent->value;
env = environ_for_session(s);
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
s->tio, &cause) != 0) {
cmdq_error(item, "respawn pane failed: %s", cause);
free(cause); free(cause);
environ_free(&env); environ_free(env);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
environ_free(env);
wp->flags |= PANE_REDRAW; wp->flags |= PANE_REDRAW;
server_status_window(w); server_status_window(w);
environ_free(&env);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,67 +27,71 @@
* Respawn a window (restart the command). Kill existing if -k given. * Respawn a window (restart the command). Kill existing if -k given.
*/ */
enum cmd_retval cmd_respawn_window_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_respawn_window_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_respawn_window_entry = { const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw", .name = "respawn-window",
"kt:", 0, 1, .alias = "respawnw",
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
0, .args = { "kt:", 0, -1 },
NULL, .usage = "[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
NULL,
cmd_respawn_window_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_respawn_window_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl; struct session *s = item->state.tflag.s;
struct window *w; struct winlink *wl = item->state.tflag.wl;
struct window *w = wl->window;
struct window_pane *wp; struct window_pane *wp;
struct session *s; struct environ *env;
struct environ env; const char *path;
const char *cmd;
char *cause; char *cause;
struct environ_entry *envent;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (!args_has(self->args, 'k')) { if (!args_has(self->args, 'k')) {
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1) if (wp->fd == -1)
continue; continue;
ctx->error(ctx, cmdq_error(item, "window still active: %s:%d", s->name,
"window still active: %s:%d", s->name, wl->idx); wl->idx);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} }
environ_init(&env);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
layout_free(w); layout_free(w);
window_destroy_panes(w); window_destroy_panes(w);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy); window_pane_resize(wp, w->sx, w->sy);
if (args->argc != 0)
cmd = args->argv[0]; path = NULL;
if (item->client != NULL && item->client->session == NULL)
envent = environ_find(item->client->environ, "PATH");
else else
cmd = NULL; envent = environ_find(s->environ, "PATH");
if (window_pane_spawn(wp, cmd, NULL, NULL, &env, s->tio, &cause) != 0) { if (envent != NULL)
ctx->error(ctx, "respawn window failed: %s", cause); path = envent->value;
env = environ_for_session(s);
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
s->tio, &cause) != 0) {
cmdq_error(item, "respawn window failed: %s", cause);
free(cause); free(cause);
environ_free(&env); environ_free(env);
server_destroy_pane(wp); server_destroy_pane(wp, 0);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
layout_init(w); environ_free(env);
layout_init(w, wp);
window_pane_reset_mode(wp); window_pane_reset_mode(wp);
screen_reinit(&wp->base); screen_reinit(&wp->base);
input_init(wp); input_init(wp);
@@ -96,6 +100,5 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
recalculate_sizes(); recalculate_sizes();
server_redraw_window(w); server_redraw_window(w);
environ_free(&env);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,40 +24,32 @@
* Rotate the panes in a window. * Rotate the panes in a window.
*/ */
void cmd_rotate_window_key_binding(struct cmd *, int); static enum cmd_retval cmd_rotate_window_exec(struct cmd *,
enum cmd_retval cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *); struct cmdq_item *);
const struct cmd_entry cmd_rotate_window_entry = { const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew", .name = "rotate-window",
"Dt:U", 0, 0, .alias = "rotatew",
"[-DU] " CMD_TARGET_WINDOW_USAGE,
0, .args = { "Dt:U", 0, 0 },
cmd_rotate_window_key_binding, .usage = "[-DU] " CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_rotate_window_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_rotate_window_exec
}; };
void static enum cmd_retval
cmd_rotate_window_key_binding(struct cmd *self, int key) cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
self->args = args_create(0); struct winlink *wl = item->state.tflag.wl;
if (key == ('o' | KEYC_ESCAPE)) struct window *w = wl->window;
args_set(self->args, 'D', NULL);
}
enum cmd_retval
cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct window_pane *wp, *wp2; struct window_pane *wp, *wp2;
struct layout_cell *lc; struct layout_cell *lc;
u_int sx, sy, xoff, yoff; u_int sx, sy, xoff, yoff;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) server_unzoom_window(w);
return (CMD_RETURN_ERROR);
w = wl->window;
if (args_has(self->args, 'D')) { if (args_has(self->args, 'D')) {
wp = TAILQ_LAST(&w->panes, window_panes); wp = TAILQ_LAST(&w->panes, window_panes);

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -29,66 +29,107 @@
* Runs a command without a window. * Runs a command without a window.
*/ */
enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmdq_item *);
void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *); static void cmd_run_shell_callback(struct job *);
static void cmd_run_shell_free(void *);
static void cmd_run_shell_print(struct job *, const char *);
const struct cmd_entry cmd_run_shell_entry = { const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run", .name = "run-shell",
"", 1, 1, .alias = "run",
"command",
0, .args = { "bt:", 1, 1 },
NULL, .usage = "[-b] " CMD_TARGET_PANE_USAGE " shell-command",
NULL,
cmd_run_shell_exec .tflag = CMD_PANE_CANFAIL,
.flags = 0,
.exec = cmd_run_shell_exec
}; };
struct cmd_run_shell_data { struct cmd_run_shell_data {
char *cmd; char *cmd;
struct cmd_ctx ctx; struct cmdq_item *item;
int wp_id;
}; };
enum cmd_retval static void
cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_run_shell_print(struct job *job, const char *msg)
{
struct cmd_run_shell_data *cdata = job->data;
struct window_pane *wp = NULL;
struct cmd_find_state fs;
if (cdata->wp_id != -1)
wp = window_pane_find_by_id(cdata->wp_id);
if (wp == NULL) {
if (cdata->item != NULL) {
cmdq_print(cdata->item, "%s", msg);
return;
}
if (cmd_find_current (&fs, NULL, CMD_FIND_QUIET) != 0)
return;
wp = fs.wp;
if (wp == NULL)
return;
}
if (window_pane_set_mode(wp, &window_copy_mode) == 0)
window_copy_init_for_output(wp);
if (wp->mode == &window_copy_mode)
window_copy_add(wp, "%s", msg);
}
static enum cmd_retval
cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct cmd_run_shell_data *cdata; struct cmd_run_shell_data *cdata;
const char *shellcmd = args->argv[0]; struct client *c = item->state.c;
struct session *s = item->state.tflag.s;
struct winlink *wl = item->state.tflag.wl;
struct window_pane *wp = item->state.tflag.wp;
const char *cwd;
cdata = xmalloc(sizeof *cdata); if (item->client != NULL && item->client->session == NULL)
cdata->cmd = xstrdup(args->argv[0]); cwd = item->client->cwd;
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); else if (s != NULL)
cwd = s->cwd;
else
cwd = NULL;
if (ctx->cmdclient != NULL) cdata = xcalloc(1, sizeof *cdata);
ctx->cmdclient->references++; cdata->cmd = format_single(item, args->argv[0], c, s, wl, wp);
if (ctx->curclient != NULL)
ctx->curclient->references++;
job_run(shellcmd, cmd_run_shell_callback, cmd_run_shell_free, cdata); if (args_has(args, 't') && wp != NULL)
cdata->wp_id = wp->id;
else
cdata->wp_id = -1;
return (CMD_RETURN_YIELD); /* don't let client exit */ if (!args_has(args, 'b'))
cdata->item = item;
job_run(cdata->cmd, s, cwd, cmd_run_shell_callback, cmd_run_shell_free,
cdata);
if (args_has(args, 'b'))
return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT);
} }
void static void
cmd_run_shell_callback(struct job *job) cmd_run_shell_callback(struct job *job)
{ {
struct cmd_run_shell_data *cdata = job->data; struct cmd_run_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx; char *cmd = cdata->cmd, *msg, *line;
char *cmd, *msg, *line;
size_t size; size_t size;
int retcode; int retcode;
u_int lines;
if (ctx->cmdclient != NULL && ctx->cmdclient->flags & CLIENT_DEAD)
return;
if (ctx->curclient != NULL && ctx->curclient->flags & CLIENT_DEAD)
return;
lines = 0;
do { do {
if ((line = evbuffer_readline(job->event->input)) != NULL) { if ((line = evbuffer_readline(job->event->input)) != NULL) {
ctx->print(ctx, "%s", line); cmd_run_shell_print(job, line);
lines++; free(line);
} }
} while (line != NULL); } while (line != NULL);
@@ -98,14 +139,11 @@ cmd_run_shell_callback(struct job *job)
memcpy(line, EVBUFFER_DATA(job->event->input), size); memcpy(line, EVBUFFER_DATA(job->event->input), size);
line[size] = '\0'; line[size] = '\0';
ctx->print(ctx, "%s", line); cmd_run_shell_print(job, line);
lines++;
free(line); free(line);
} }
cmd = cdata->cmd;
msg = NULL; msg = NULL;
if (WIFEXITED(job->status)) { if (WIFEXITED(job->status)) {
if ((retcode = WEXITSTATUS(job->status)) != 0) if ((retcode = WEXITSTATUS(job->status)) != 0)
@@ -114,27 +152,18 @@ cmd_run_shell_callback(struct job *job)
retcode = WTERMSIG(job->status); retcode = WTERMSIG(job->status);
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
} }
if (msg != NULL) { if (msg != NULL)
if (lines != 0) cmd_run_shell_print(job, msg);
ctx->print(ctx, "%s", msg); free(msg);
else
ctx->info(ctx, "%s", msg); if (cdata->item != NULL)
free(msg); cdata->item->flags &= ~CMDQ_WAITING;
}
} }
void static void
cmd_run_shell_free(void *data) cmd_run_shell_free(void *data)
{ {
struct cmd_run_shell_data *cdata = data; struct cmd_run_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
ctx->cmdclient->flags |= CLIENT_EXIT;
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
free(cdata->cmd); free(cdata->cmd);
free(cdata); free(cdata);

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -20,8 +20,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -29,91 +31,124 @@
* Saves a paste buffer to a file. * Saves a paste buffer to a file.
*/ */
enum cmd_retval cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_save_buffer_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_save_buffer_entry = { const struct cmd_entry cmd_save_buffer_entry = {
"save-buffer", "saveb", .name = "save-buffer",
"ab:", 1, 1, .alias = "saveb",
"[-a] " CMD_BUFFER_USAGE " path",
0, .args = { "ab:", 1, 1 },
NULL, .usage = "[-a] " CMD_BUFFER_USAGE " path",
NULL,
cmd_save_buffer_exec .flags = CMD_AFTERHOOK,
.exec = cmd_save_buffer_exec
}; };
enum cmd_retval const struct cmd_entry cmd_show_buffer_entry = {
cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "show-buffer",
.alias = "showb",
.args = { "b:", 0, 0 },
.usage = CMD_BUFFER_USAGE,
.flags = CMD_AFTERHOOK,
.exec = cmd_save_buffer_exec
};
static enum cmd_retval
cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c = ctx->cmdclient; struct client *c = item->client;
struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
const char *path, *newpath, *wd; const char *path, *bufname, *bufdata, *start, *end;
char *cause; const char *flags;
int buffer; char *msg, *file;
mode_t mask; size_t size, used, msglen, bufsize;
FILE *f; FILE *f;
if (!args_has(args, 'b')) { if (!args_has(args, 'b')) {
if ((pb = paste_get_top(&global_buffers)) == NULL) { if ((pb = paste_get_top(NULL)) == NULL) {
ctx->error(ctx, "no buffers"); cmdq_error(item, "no buffers");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else { } else {
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); bufname = args_get(args, 'b');
if (cause != NULL) { pb = paste_get_name(bufname);
ctx->error(ctx, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
pb = paste_get_index(&global_buffers, buffer);
if (pb == NULL) { if (pb == NULL) {
ctx->error(ctx, "no buffer %d", buffer); cmdq_error(item, "no buffer %s", bufname);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} }
bufdata = paste_buffer_data(pb, &bufsize);
path = args->argv[0]; if (self->entry == &cmd_show_buffer_entry)
path = "-";
else
path = args->argv[0];
if (strcmp(path, "-") == 0) { if (strcmp(path, "-") == 0) {
if (c == NULL) { if (c == NULL) {
ctx->error(ctx, "%s: can't write to stdout", path); cmdq_error(item, "can't write to stdout");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
evbuffer_add(c->stdout_data, pb->data, pb->size); if (c->session == NULL || (c->flags & CLIENT_CONTROL))
server_push_stdout(c); goto do_stdout;
} else { goto do_print;
if (c != NULL)
wd = c->cwd;
else if ((s = cmd_current_session(ctx, 0)) != NULL) {
wd = options_get_string(&s->options, "default-path");
if (*wd == '\0')
wd = s->cwd;
} else
wd = NULL;
if (wd != NULL && *wd != '\0') {
newpath = get_full_path(wd, path);
if (newpath != NULL)
path = newpath;
}
mask = umask(S_IRWXG | S_IRWXO);
if (args_has(self->args, 'a'))
f = fopen(path, "ab");
else
f = fopen(path, "wb");
umask(mask);
if (f == NULL) {
ctx->error(ctx, "%s: %s", path, strerror(errno));
return (CMD_RETURN_ERROR);
}
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
ctx->error(ctx, "%s: fwrite error", path);
fclose(f);
return (CMD_RETURN_ERROR);
}
fclose(f);
} }
flags = "wb";
if (args_has(self->args, 'a'))
flags = "ab";
file = server_client_get_path(c, path);
f = fopen(file, flags);
if (f == NULL) {
cmdq_error(item, "%s: %s", file, strerror(errno));
free(file);
return (CMD_RETURN_ERROR);
}
if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
cmdq_error(item, "%s: write error", file);
fclose(f);
return (CMD_RETURN_ERROR);
}
fclose(f);
free(file);
return (CMD_RETURN_NORMAL);
do_stdout:
evbuffer_add(c->stdout_data, bufdata, bufsize);
server_client_push_stdout(c);
return (CMD_RETURN_NORMAL);
do_print:
if (bufsize > (INT_MAX / 4) - 1) {
cmdq_error(item, "buffer too big");
return (CMD_RETURN_ERROR);
}
msg = NULL;
used = 0;
while (used != bufsize) {
start = bufdata + used;
end = memchr(start, '\n', bufsize - used);
if (end != NULL)
size = end - start;
else
size = bufsize - used;
msglen = size * 4 + 1;
msg = xrealloc(msg, msglen);
strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
cmdq_print(item, "%s", msg);
used += size + (end != NULL);
}
free(msg);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,144 +18,123 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include "tmux.h" #include "tmux.h"
/* /*
* Switch window to selected layout. * Switch window to selected layout.
*/ */
void cmd_select_layout_key_binding(struct cmd *, int); static enum cmd_retval cmd_select_layout_exec(struct cmd *,
enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_ctx *); struct cmdq_item *);
const struct cmd_entry cmd_select_layout_entry = { const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl", .name = "select-layout",
"nprut:", 0, 1, .alias = "selectl",
"[-npUu] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
0, .args = { "nopt:", 0, 1 },
cmd_select_layout_key_binding, .usage = "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
NULL,
cmd_select_layout_exec .tflag = CMD_WINDOW,
.flags = CMD_AFTERHOOK,
.exec = cmd_select_layout_exec
}; };
const struct cmd_entry cmd_next_layout_entry = { const struct cmd_entry cmd_next_layout_entry = {
"next-layout", "nextl", .name = "next-layout",
"t:", 0, 0, .alias = "nextl",
CMD_TARGET_WINDOW_USAGE,
0, .args = { "t:", 0, 0 },
NULL, .usage = CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_select_layout_exec .tflag = CMD_WINDOW,
.flags = CMD_AFTERHOOK,
.exec = cmd_select_layout_exec
}; };
const struct cmd_entry cmd_previous_layout_entry = { const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl", .name = "previous-layout",
"t:", 0, 0, .alias = "prevl",
CMD_TARGET_WINDOW_USAGE,
0, .args = { "t:", 0, 0 },
NULL, .usage = CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_select_layout_exec .tflag = CMD_WINDOW,
.flags = CMD_AFTERHOOK,
.exec = cmd_select_layout_exec
}; };
void static enum cmd_retval
cmd_select_layout_key_binding(struct cmd *self, int key) cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
{
switch (key) {
case '1' | KEYC_ESCAPE:
self->args = args_create(1, "even-horizontal");
break;
case '2' | KEYC_ESCAPE:
self->args = args_create(1, "even-vertical");
break;
case '3' | KEYC_ESCAPE:
self->args = args_create(1, "main-horizontal");
break;
case '4' | KEYC_ESCAPE:
self->args = args_create(1, "main-vertical");
break;
case '5' | KEYC_ESCAPE:
self->args = args_create(1, "tiled");
break;
case 'u':
self->args = args_create(0);
args_set(self->args, 'u', NULL);
break;
case 'U':
self->args = args_create(0);
args_set(self->args, 'U', NULL);
break;
default:
self->args = args_create(0);
break;
}
}
enum cmd_retval
cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl; struct winlink *wl = item->state.tflag.wl;
struct window *w; struct window *w;
const char *layoutname; const char *layoutname;
char *oldlayout;
int next, previous, layout; int next, previous, layout;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window; w = wl->window;
server_unzoom_window(w);
next = self->entry == &cmd_next_layout_entry; next = self->entry == &cmd_next_layout_entry;
if (args_has(self->args, 'n')) if (args_has(args, 'n'))
next = 1; next = 1;
previous = self->entry == &cmd_previous_layout_entry; previous = self->entry == &cmd_previous_layout_entry;
if (args_has(self->args, 'p')) if (args_has(args, 'p'))
previous = 1; previous = 1;
layout_list_add(w); oldlayout = w->old_layout;
if (args_has(self->args, 'U')) { w->old_layout = layout_dump(w->layout_root);
if ((layoutname = layout_list_redo(w)) == NULL) {
ctx->info(ctx, "no more layout history");
return (CMD_RETURN_ERROR);
}
goto set_layout;
} else if (args_has(self->args, 'u')) {
if ((layoutname = layout_list_undo(w)) == NULL) {
ctx->info(ctx, "no more layout history");
return (CMD_RETURN_ERROR);
}
goto set_layout;
}
if (next || previous) { if (next || previous) {
if (next) if (next)
layout = layout_set_next(wl->window); layout_set_next(w);
else else
layout = layout_set_previous(wl->window); layout_set_previous(w);
server_redraw_window(wl->window); goto changed;
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
return (CMD_RETURN_NORMAL);
} }
if (args->argc == 0) if (!args_has(args, 'o')) {
layout = wl->window->lastlayout; if (args->argc == 0)
layout = w->lastlayout;
else
layout = layout_set_lookup(args->argv[0]);
if (layout != -1) {
layout_set_select(w, layout);
goto changed;
}
}
if (args->argc != 0)
layoutname = args->argv[0];
else if (args_has(args, 'o'))
layoutname = oldlayout;
else else
layout = layout_set_lookup(args->argv[0]); layoutname = NULL;
if (layout != -1) {
layout = layout_set_select(wl->window, layout); if (layoutname != NULL) {
server_redraw_window(wl->window); if (layout_parse(w, layoutname) == -1) {
ctx->info(ctx, "arranging in: %s", layout_set_name(layout)); cmdq_error(item, "can't set layout: %s", layoutname);
return (CMD_RETURN_NORMAL); goto error;
}
goto changed;
} }
if (args->argc == 0) free(oldlayout);
return (CMD_RETURN_NORMAL);
layoutname = args->argv[0];
set_layout:
if (layout_parse(wl->window, layoutname) == -1) {
ctx->error(ctx, "can't set layout: %s", layoutname);
return (CMD_RETURN_ERROR);
}
server_redraw_window(wl->window);
ctx->info(ctx, "arranging in: %s", layoutname);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
changed:
free(oldlayout);
server_redraw_window(w);
return (CMD_RETURN_NORMAL);
error:
free(w->old_layout);
w->old_layout = oldlayout;
return (CMD_RETURN_ERROR);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,93 +24,140 @@
* Select pane. * Select pane.
*/ */
void cmd_select_pane_key_binding(struct cmd *, int); static enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = { const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp", .name = "select-pane",
"lDLRt:U", 0, 0, .alias = "selectp",
"[-lDLRU] " CMD_TARGET_PANE_USAGE,
0, .args = { "DdegLlMmP:Rt:U", 0, 0 },
cmd_select_pane_key_binding, .usage = "[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE,
NULL,
cmd_select_pane_exec .tflag = CMD_PANE,
.flags = 0,
.exec = cmd_select_pane_exec
}; };
const struct cmd_entry cmd_last_pane_entry = { const struct cmd_entry cmd_last_pane_entry = {
"last-pane", "lastp", .name = "last-pane",
"t:", 0, 0, .alias = "lastp",
CMD_TARGET_WINDOW_USAGE,
0, .args = { "det:", 0, 0 },
NULL, .usage = "[-de] " CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_select_pane_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_select_pane_exec
}; };
void static enum cmd_retval
cmd_select_pane_key_binding(struct cmd *self, int key) cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
{
self->args = args_create(0);
if (key == KEYC_UP)
args_set(self->args, 'U', NULL);
if (key == KEYC_DOWN)
args_set(self->args, 'D', NULL);
if (key == KEYC_LEFT)
args_set(self->args, 'L', NULL);
if (key == KEYC_RIGHT)
args_set(self->args, 'R', NULL);
if (key == 'o')
args_set(self->args, 't', ":.+");
}
enum cmd_retval
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct winlink *wl; struct winlink *wl = item->state.tflag.wl;
struct window_pane *wp; struct window *w = wl->window;
struct session *s = item->state.tflag.s;
struct window_pane *wp = item->state.tflag.wp, *lastwp, *markedwp;
const char *style;
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) { if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
wl = cmd_find_window(ctx, args_get(args, 't'), NULL);
if (wl == NULL)
return (CMD_RETURN_ERROR);
if (wl->window->last == NULL) { if (wl->window->last == NULL) {
ctx->error(ctx, "no last pane"); cmdq_error(item, "no last pane");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
window_set_active_pane(wl->window, wl->window->last); if (args_has(self->args, 'e'))
server_status_window(wl->window); w->last->flags &= ~PANE_INPUTOFF;
server_redraw_window_borders(wl->window); else if (args_has(self->args, 'd'))
w->last->flags |= PANE_INPUTOFF;
else {
server_unzoom_window(w);
window_redraw_active_switch(w, w->last);
if (window_set_active_pane(w, w->last)) {
server_status_window(w);
server_redraw_window_borders(w);
}
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL) if (args_has(args, 'm') || args_has(args, 'M')) {
return (CMD_RETURN_ERROR); if (args_has(args, 'm') && !window_pane_visible(wp))
return (CMD_RETURN_NORMAL);
lastwp = marked_pane.wp;
if (!window_pane_visible(wp)) { if (args_has(args, 'M') || server_is_marked(s, wl, wp))
ctx->error(ctx, "pane not visible"); server_clear_marked();
return (CMD_RETURN_ERROR); else
server_set_marked(s, wl, wp);
markedwp = marked_pane.wp;
if (lastwp != NULL) {
server_redraw_window_borders(lastwp->window);
server_status_window(lastwp->window);
}
if (markedwp != NULL) {
server_redraw_window_borders(markedwp->window);
server_status_window(markedwp->window);
}
return (CMD_RETURN_NORMAL);
} }
if (args_has(self->args, 'L')) if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
if (args_has(args, 'P')) {
style = args_get(args, 'P');
if (style_parse(&grid_default_cell, &wp->colgc,
style) == -1) {
cmdq_error(item, "bad style: %s", style);
return (CMD_RETURN_ERROR);
}
wp->flags |= PANE_REDRAW;
}
if (args_has(self->args, 'g'))
cmdq_print(item, "%s", style_tostring(&wp->colgc));
return (CMD_RETURN_NORMAL);
}
if (args_has(self->args, 'L')) {
server_unzoom_window(wp->window);
wp = window_pane_find_left(wp); wp = window_pane_find_left(wp);
else if (args_has(self->args, 'R')) } else if (args_has(self->args, 'R')) {
server_unzoom_window(wp->window);
wp = window_pane_find_right(wp); wp = window_pane_find_right(wp);
else if (args_has(self->args, 'U')) } else if (args_has(self->args, 'U')) {
server_unzoom_window(wp->window);
wp = window_pane_find_up(wp); wp = window_pane_find_up(wp);
else if (args_has(self->args, 'D')) } else if (args_has(self->args, 'D')) {
server_unzoom_window(wp->window);
wp = window_pane_find_down(wp); wp = window_pane_find_down(wp);
if (wp == NULL) { }
ctx->error(ctx, "pane not found"); if (wp == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_NORMAL);
if (args_has(self->args, 'e')) {
wp->flags &= ~PANE_INPUTOFF;
return (CMD_RETURN_NORMAL);
}
if (args_has(self->args, 'd')) {
wp->flags |= PANE_INPUTOFF;
return (CMD_RETURN_NORMAL);
} }
window_set_active_pane(wl->window, wp); if (wp == w->active)
server_status_window(wl->window); return (CMD_RETURN_NORMAL);
server_redraw_window_borders(wl->window); server_unzoom_window(wp->window);
if (!window_pane_visible(wp)) {
cmdq_error(item, "pane not visible");
return (CMD_RETURN_ERROR);
}
window_redraw_active_switch(w, wp);
if (window_set_active_pane(w, wp)) {
server_status_window(w);
server_redraw_window_borders(w);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,69 +26,66 @@
* Select window by index. * Select window by index.
*/ */
void cmd_select_window_key_binding(struct cmd *, int); static enum cmd_retval cmd_select_window_exec(struct cmd *,
enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_ctx *); struct cmdq_item *);
const struct cmd_entry cmd_select_window_entry = { const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw", .name = "select-window",
"lnpt:", 0, 0, .alias = "selectw",
"[-lnp] " CMD_TARGET_WINDOW_USAGE,
0, .args = { "lnpTt:", 0, 0 },
cmd_select_window_key_binding, .usage = "[-lnpT] " CMD_TARGET_WINDOW_USAGE,
NULL,
cmd_select_window_exec .tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_select_window_exec
}; };
const struct cmd_entry cmd_next_window_entry = { const struct cmd_entry cmd_next_window_entry = {
"next-window", "next", .name = "next-window",
"at:", 0, 0, .alias = "next",
"[-a] " CMD_TARGET_SESSION_USAGE,
0, .args = { "at:", 0, 0 },
cmd_select_window_key_binding, .usage = "[-a] " CMD_TARGET_SESSION_USAGE,
NULL,
cmd_select_window_exec .tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_select_window_exec
}; };
const struct cmd_entry cmd_previous_window_entry = { const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev", .name = "previous-window",
"at:", 0, 0, .alias = "prev",
"[-a] " CMD_TARGET_SESSION_USAGE,
0, .args = { "at:", 0, 0 },
cmd_select_window_key_binding, .usage = "[-a] " CMD_TARGET_SESSION_USAGE,
NULL,
cmd_select_window_exec .tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_select_window_exec
}; };
const struct cmd_entry cmd_last_window_entry = { const struct cmd_entry cmd_last_window_entry = {
"last-window", "last", .name = "last-window",
"t:", 0, 0, .alias = "last",
CMD_TARGET_SESSION_USAGE,
0, .args = { "t:", 0, 0 },
NULL, .usage = CMD_TARGET_SESSION_USAGE,
NULL,
cmd_select_window_exec .tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_select_window_exec
}; };
void static enum cmd_retval
cmd_select_window_key_binding(struct cmd *self, int key) cmd_select_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
char tmp[16]; struct winlink *wl = item->state.tflag.wl;
struct session *s = item->state.tflag.s;
self->args = args_create(0);
if (key >= '0' && key <= '9') {
xsnprintf(tmp, sizeof tmp, ":%d", key - '0');
args_set(self->args, 't', tmp);
}
if (key == ('n' | KEYC_ESCAPE) || key == ('p' | KEYC_ESCAPE))
args_set(self->args, 'a', NULL);
}
enum cmd_retval
cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct winlink *wl;
struct session *s;
int next, previous, last, activity; int next, previous, last, activity;
next = self->entry == &cmd_next_window_entry; next = self->entry == &cmd_next_window_entry;
@@ -102,35 +99,37 @@ cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx)
last = 1; last = 1;
if (next || previous || last) { if (next || previous || last) {
s = cmd_find_session(ctx, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
activity = args_has(self->args, 'a'); activity = args_has(self->args, 'a');
if (next) { if (next) {
if (session_next(s, activity) != 0) { if (session_next(s, activity) != 0) {
ctx->error(ctx, "no next window"); cmdq_error(item, "no next window");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else if (previous) { } else if (previous) {
if (session_previous(s, activity) != 0) { if (session_previous(s, activity) != 0) {
ctx->error(ctx, "no previous window"); cmdq_error(item, "no previous window");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else { } else {
if (session_last(s) != 0) { if (session_last(s) != 0) {
ctx->error(ctx, "no last window"); cmdq_error(item, "no last window");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} }
server_redraw_session(s); server_redraw_session(s);
} else { } else {
wl = cmd_find_window(ctx, args_get(args, 't'), &s); /*
if (wl == NULL) * If -T and select-window is invoked on same window as
return (CMD_RETURN_ERROR); * current, switch to previous window.
*/
if (session_select(s, wl->idx) == 0) if (args_has(self->args, 'T') && wl == s->curw) {
if (session_last(s) != 0) {
cmdq_error(item, "no last window");
return (-1);
}
server_redraw_session(s);
} else if (session_select(s, wl->idx) == 0)
server_redraw_session(s); server_redraw_session(s);
} }
recalculate_sizes(); recalculate_sizes();

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,57 +27,117 @@
* Send keys to client. * Send keys to client.
*/ */
enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_send_keys_entry = { const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send", .name = "send-keys",
"lRt:", 0, -1, .alias = "send",
"[-lR] [-t target-pane] key ...",
0, .args = { "lXRMN:t:", 0, -1 },
NULL, .usage = "[-lXRM] [-N repeat-count] " CMD_TARGET_PANE_USAGE " key ...",
NULL,
cmd_send_keys_exec .tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_send_keys_exec
}; };
enum cmd_retval const struct cmd_entry cmd_send_prefix_entry = {
cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "send-prefix",
.alias = NULL,
.args = { "2t:", 0, 0 },
.usage = "[-2] " CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = CMD_AFTERHOOK,
.exec = cmd_send_keys_exec
};
static enum cmd_retval
cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct window_pane *wp; struct client *c = item->state.c;
struct session *s; struct window_pane *wp = item->state.tflag.wp;
struct input_ctx *ictx; struct session *s = item->state.tflag.s;
const char *str; struct mouse_event *m = &item->mouse;
int i, key; struct utf8_data *ud, *uc;
wchar_t wc;
int i, literal;
key_code key;
u_int np = 1;
char *cause = NULL;
if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL) if (args_has(args, 'N')) {
return (CMD_RETURN_ERROR); np = args_strtonum(args, 'N', 1, UINT_MAX, &cause);
if (cause != NULL) {
if (args_has(args, 'R')) { cmdq_error(item, "repeat count %s", cause);
ictx = &wp->ictx; free(cause);
return (CMD_RETURN_ERROR);
memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell); }
memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); if (args_has(args, 'X') || args->argc == 0)
ictx->old_cx = 0; wp->modeprefix = np;
ictx->old_cy = 0;
if (wp->mode == NULL)
screen_write_start(&ictx->ctx, wp, &wp->base);
else
screen_write_start(&ictx->ctx, NULL, &wp->base);
screen_write_reset(&ictx->ctx);
screen_write_stop(&ictx->ctx);
} }
for (i = 0; i < args->argc; i++) { if (args_has(args, 'X')) {
str = args->argv[i]; if (wp->mode == NULL || wp->mode->command == NULL) {
cmdq_error(item, "not in a mode");
if (!args_has(args, 'l') && return (CMD_RETURN_ERROR);
(key = key_string_lookup_string(str)) != KEYC_NONE) {
window_pane_key(wp, s, key);
} else {
for (; *str != '\0'; str++)
window_pane_key(wp, s, *str);
} }
if (!m->valid)
wp->mode->command(wp, c, s, args, NULL);
else
wp->mode->command(wp, c, s, args, m);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'M')) {
wp = cmd_mouse_pane(m, &s, NULL);
if (wp == NULL) {
cmdq_error(item, "no mouse target");
return (CMD_RETURN_ERROR);
}
window_pane_key(wp, NULL, s, m->key, m);
return (CMD_RETURN_NORMAL);
}
if (self->entry == &cmd_send_prefix_entry) {
if (args_has(args, '2'))
key = options_get_number(s->options, "prefix2");
else
key = options_get_number(s->options, "prefix");
window_pane_key(wp, NULL, s, key, NULL);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'R')) {
window_pane_reset_palette(wp);
input_reset(wp, 1);
}
for (; np != 0; np--) {
for (i = 0; i < args->argc; i++) {
literal = args_has(args, 'l');
if (!literal) {
key = key_string_lookup_string(args->argv[i]);
if (key != KEYC_NONE && key != KEYC_UNKNOWN)
window_pane_key(wp, NULL, s, key, NULL);
else
literal = 1;
}
if (literal) {
ud = utf8_fromcstr(args->argv[i]);
for (uc = ud; uc->size != 0; uc++) {
if (utf8_combine(uc, &wc) != UTF8_DONE)
continue;
window_pane_key(wp, NULL, s, wc, NULL);
}
free(ud);
}
}
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,57 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
/*
* Send prefix key as a key.
*/
enum cmd_retval cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
"2t:", 0, 0,
"[-2] " CMD_TARGET_PANE_USAGE,
0,
NULL,
NULL,
cmd_send_prefix_exec
};
enum cmd_retval
cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct session *s;
struct window_pane *wp;
int key;
if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, '2'))
key = options_get_number(&s->options, "prefix2");
else
key = options_get_number(&s->options, "prefix");
window_pane_key(wp, s, key);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,183 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/utsname.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "tmux.h"
/*
* Show various information about server.
*/
enum cmd_retval cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
"", 0, 0,
"",
0,
NULL,
NULL,
cmd_server_info_exec
};
/* ARGSUSED */
enum cmd_retval
cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
struct tty_term *term;
struct client *c;
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct tty_code *code;
const struct tty_term_code_entry *ent;
struct utsname un;
struct job *job;
struct grid *gd;
struct grid_line *gl;
u_int i, j, k;
char out[80];
char *tim;
time_t t;
u_int lines, ulines;
size_t size, usize;
tim = ctime(&start_time);
*strchr(tim, '\n') = '\0';
ctx->print(ctx,
"tmux " VERSION ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(
ctx, "socket path %s, debug level %d", socket_path, debug_level);
if (uname(&un) >= 0) {
ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine);
}
if (cfg_file != NULL)
ctx->print(ctx, "configuration file is %s", cfg_file);
else
ctx->print(ctx, "configuration file not specified");
ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION);
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Clients:");
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
ctx->print(ctx,"%2d: %s (%d, %d): %s [%ux%u %s bs=%hho "
"xterm=%u] [flags=0x%x/0x%x, references=%u]", i,
c->tty.path, c->ibuf.fd, c->tty.fd, c->session->name,
c->tty.sx, c->tty.sy, c->tty.termname,
c->tty.tio.c_cc[VERASE], c->tty.xterm_version,
c->flags, c->tty.flags, c->references);
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8));
RB_FOREACH(s, sessions, &sessions) {
t = s->creation_time.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x]", s->idx, s->name,
winlink_count(&s->windows), tim, s->sx, s->sy, s->flags);
RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, "
"references=%u, last layout=%d]", wl->idx, w->name,
w->sx, w->sy, w->flags, w->references,
w->lastlayout);
j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0;
gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) {
gl = &gd->linedata[k];
if (gl->celldata != NULL) {
lines++;
size += gl->cellsize *
sizeof *gl->celldata;
}
if (gl->utf8data != NULL) {
ulines++;
usize += gl->utf8size *
sizeof *gl->utf8data;
}
}
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
"bytes; UTF-8 %u/%u, %zu bytes", j,
wp->tty, (u_long) wp->pid, wp->fd, lines,
gd->hsize + gd->sy, size, ulines,
gd->hsize + gd->sy, usize);
j++;
}
}
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Terminals:");
LIST_FOREACH(term, &tty_terms, entry) {
ctx->print(ctx, "%s [references=%u, flags=0x%x]:",
term->name, term->references, term->flags);
for (i = 0; i < NTTYCODE; i++) {
ent = &tty_term_codes[i];
code = &term->codes[ent->code];
switch (code->type) {
case TTYCODE_NONE:
ctx->print(ctx, "%2u: %s: [missing]",
ent->code, ent->name);
break;
case TTYCODE_STRING:
strnvis(out, code->value.string, sizeof out,
VIS_OCTAL|VIS_TAB|VIS_NL);
ctx->print(ctx, "%2u: %s: (string) %s",
ent->code, ent->name, out);
break;
case TTYCODE_NUMBER:
ctx->print(ctx, "%2u: %s: (number) %d",
ent->code, ent->name, code->value.number);
break;
case TTYCODE_FLAG:
ctx->print(ctx, "%2u: %s: (flag) %s",
ent->code, ent->name,
code->value.flag ? "true" : "false");
break;
}
}
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Jobs:");
LIST_FOREACH(job, &all_jobs, lentry) {
ctx->print(ctx, "%s [fd=%d, pid=%d, status=%d]",
job->cmd, job->fd, job->pid, job->status);
}
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,51 +24,98 @@
#include "tmux.h" #include "tmux.h"
/* /*
* Add or set a paste buffer. * Add, set, append to or delete a paste buffer.
*/ */
enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_set_buffer_entry = { const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb", .name = "set-buffer",
"b:", 1, 1, .alias = "setb",
CMD_BUFFER_USAGE " data",
0, .args = { "ab:n:", 0, 1 },
NULL, .usage = "[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
NULL,
cmd_set_buffer_exec .flags = CMD_AFTERHOOK,
.exec = cmd_set_buffer_exec
}; };
enum cmd_retval const struct cmd_entry cmd_delete_buffer_entry = {
cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) .name = "delete-buffer",
.alias = "deleteb",
.args = { "b:", 0, 0 },
.usage = CMD_BUFFER_USAGE,
.flags = CMD_AFTERHOOK,
.exec = cmd_set_buffer_exec
};
static enum cmd_retval
cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
u_int limit; struct paste_buffer *pb;
char *pdata, *cause; char *bufdata, *cause;
size_t psize; const char *bufname, *olddata;
int buffer; size_t bufsize, newsize;
limit = options_get_number(&global_options, "buffer-limit"); bufname = args_get(args, 'b');
if (bufname == NULL)
pb = NULL;
else
pb = paste_get_name(bufname);
pdata = xstrdup(args->argv[0]); if (self->entry == &cmd_delete_buffer_entry) {
psize = strlen(pdata); if (pb == NULL)
pb = paste_get_top(&bufname);
if (!args_has(args, 'b')) { if (pb == NULL) {
paste_add(&global_buffers, pdata, psize, limit); cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR);
}
paste_free(pb);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (args_has(args, 'n')) {
if (cause != NULL) { if (pb == NULL)
ctx->error(ctx, "buffer %s", cause); pb = paste_get_top(&bufname);
free(cause); if (pb == NULL) {
free(pdata); cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
}
if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) {
cmdq_error(item, "%s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
} }
if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) { if (args->argc != 1) {
ctx->error(ctx, "no buffer %d", buffer); cmdq_error(item, "no data specified");
free(pdata); return (CMD_RETURN_ERROR);
}
if ((newsize = strlen(args->argv[0])) == 0)
return (CMD_RETURN_NORMAL);
bufsize = 0;
bufdata = NULL;
if (args_has(args, 'a') && pb != NULL) {
olddata = paste_buffer_data(pb, &bufsize);
bufdata = xmalloc(bufsize);
memcpy(bufdata, olddata, bufsize);
}
bufdata = xrealloc(bufdata, bufsize + newsize);
memcpy(bufdata + bufsize, args->argv[0], newsize);
bufsize += newsize;
if (paste_set(bufdata, bufsize, bufname, &cause) != 0) {
cmdq_error(item, "%s", cause);
free(bufdata);
free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,67 +27,76 @@
* Set an environment variable. * Set an environment variable.
*/ */
enum cmd_retval cmd_set_environment_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_set_environment_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_set_environment_entry = { const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv", .name = "set-environment",
"grt:u", 1, 2, .alias = "setenv",
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
0, .args = { "grt:u", 1, 2 },
NULL, .usage = "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
NULL,
cmd_set_environment_exec .tflag = CMD_SESSION_CANFAIL,
.flags = CMD_AFTERHOOK,
.exec = cmd_set_environment_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s;
struct environ *env; struct environ *env;
const char *name, *value; const char *name, *value, *target;
name = args->argv[0]; name = args->argv[0];
if (*name == '\0') { if (*name == '\0') {
ctx->error(ctx, "empty variable name"); cmdq_error(item, "empty variable name");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (strchr(name, '=') != NULL) { if (strchr(name, '=') != NULL) {
ctx->error(ctx, "variable name contains ="); cmdq_error(item, "variable name contains =");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (args->argc < 1) if (args->argc < 2)
value = NULL; value = NULL;
else else
value = args->argv[1]; value = args->argv[1];
if (args_has(self->args, 'g')) if (args_has(self->args, 'g'))
env = &global_environ; env = global_environ;
else { else {
if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) if (item->state.tflag.s == NULL) {
target = args_get(args, 't');
if (target != NULL)
cmdq_error(item, "no such session: %s", target);
else
cmdq_error(item, "no current session");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
env = &s->environ; }
env = item->state.tflag.s->environ;
} }
if (args_has(self->args, 'u')) { if (args_has(self->args, 'u')) {
if (value != NULL) { if (value != NULL) {
ctx->error(ctx, "can't specify a value with -u"); cmdq_error(item, "can't specify a value with -u");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
environ_unset(env, name); environ_unset(env, name);
} else if (args_has(self->args, 'r')) { } else if (args_has(self->args, 'r')) {
if (value != NULL) { if (value != NULL) {
ctx->error(ctx, "can't specify a value with -r"); cmdq_error(item, "can't specify a value with -r");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
environ_set(env, name, NULL); environ_clear(env, name);
} else { } else {
if (value == NULL) { if (value == NULL) {
ctx->error(ctx, "no value specified"); cmdq_error(item, "no value specified");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
environ_set(env, name, value); environ_set(env, name, "%s", value);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

130
cmd-set-hook.c Normal file
View File

@@ -0,0 +1,130 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Set or show global or session hooks.
*/
static enum cmd_retval cmd_set_hook_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_set_hook_entry = {
.name = "set-hook",
.alias = NULL,
.args = { "gt:u", 1, 2 },
.usage = "[-gu] " CMD_TARGET_SESSION_USAGE " hook-name [command]",
.tflag = CMD_SESSION_CANFAIL,
.flags = CMD_AFTERHOOK,
.exec = cmd_set_hook_exec
};
const struct cmd_entry cmd_show_hooks_entry = {
.name = "show-hooks",
.alias = NULL,
.args = { "gt:", 0, 1 },
.usage = "[-g] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = CMD_AFTERHOOK,
.exec = cmd_set_hook_exec
};
static enum cmd_retval
cmd_set_hook_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
struct cmd_list *cmdlist;
struct hooks *hooks;
struct hook *hook;
char *cause, *tmp;
const char *name, *cmd, *target;
if (args_has(args, 'g'))
hooks = global_hooks;
else {
if (item->state.tflag.s == NULL) {
target = args_get(args, 't');
if (target != NULL)
cmdq_error(item, "no such session: %s", target);
else
cmdq_error(item, "no current session");
return (CMD_RETURN_ERROR);
}
hooks = item->state.tflag.s->hooks;
}
if (self->entry == &cmd_show_hooks_entry) {
hook = hooks_first(hooks);
while (hook != NULL) {
tmp = cmd_list_print(hook->cmdlist);
cmdq_print(item, "%s -> %s", hook->name, tmp);
free(tmp);
hook = hooks_next(hook);
}
return (CMD_RETURN_NORMAL);
}
name = args->argv[0];
if (*name == '\0') {
cmdq_error(item, "invalid hook name");
return (CMD_RETURN_ERROR);
}
if (args->argc < 2)
cmd = NULL;
else
cmd = args->argv[1];
if (args_has(args, 'u')) {
if (cmd != NULL) {
cmdq_error(item, "command passed to unset hook: %s",
name);
return (CMD_RETURN_ERROR);
}
hooks_remove(hooks, name);
return (CMD_RETURN_NORMAL);
}
if (cmd == NULL) {
cmdq_error(item, "no command to set hook: %s", name);
return (CMD_RETURN_ERROR);
}
cmdlist = cmd_string_parse(cmd, NULL, 0, &cause);
if (cmdlist == NULL) {
if (cause != NULL) {
cmdq_error(item, "%s", cause);
free(cause);
}
return (CMD_RETURN_ERROR);
}
hooks_add(hooks, name, cmdlist);
cmd_list_free(cmdlist);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,353 +27,366 @@
* Set an option. * Set an option.
*/ */
enum cmd_retval cmd_set_option_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_set_option_exec(struct cmd *, struct cmdq_item *);
int cmd_set_option_unset(struct cmd *, struct cmd_ctx *, static int cmd_set_option_set(struct cmd *, struct cmdq_item *,
const struct options_table_entry *, struct options *, struct options *, struct options_entry *, const char *);
const char *); static int cmd_set_option_flag(struct cmdq_item *,
int cmd_set_option_set(struct cmd *, struct cmd_ctx *, const struct options_table_entry *, struct options *,
const struct options_table_entry *, struct options *, const char *);
const char *); static int cmd_set_option_choice(struct cmdq_item *,
const struct options_table_entry *, struct options *,
struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_ctx *, const char *);
const struct options_table_entry *, struct options *,
const char *);
struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *,
const char *);
struct options_entry *cmd_set_option_key(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *,
const char *);
struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *,
const char *);
struct options_entry *cmd_set_option_attributes(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *,
const char *);
struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *,
const char *);
struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_ctx *,
const struct options_table_entry *, struct options *,
const char *);
const struct cmd_entry cmd_set_option_entry = { const struct cmd_entry cmd_set_option_entry = {
"set-option", "set", .name = "set-option",
"agqst:uw", 1, 2, .alias = "set",
"[-agsquw] [-t target-session|target-window] option [value]",
0, .args = { "agoqst:uw", 1, 2 },
NULL, .usage = "[-agosquw] [-t target-window] option [value]",
NULL,
cmd_set_option_exec .tflag = CMD_WINDOW_CANFAIL,
.flags = CMD_AFTERHOOK,
.exec = cmd_set_option_exec
}; };
const struct cmd_entry cmd_set_window_option_entry = { const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw", .name = "set-window-option",
"agqt:u", 1, 2, .alias = "setw",
"[-agqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
0, .args = { "agoqt:u", 1, 2 },
NULL, .usage = "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
NULL,
cmd_set_option_exec .tflag = CMD_WINDOW_CANFAIL,
.flags = CMD_AFTERHOOK,
.exec = cmd_set_option_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
const struct options_table_entry *table, *oe; int append = args_has(args, 'a');
struct session *s; struct cmd_find_state *fs = &item->state.tflag;
struct winlink *wl; struct session *s = fs->s;
struct client *c; struct winlink *wl = fs->wl;
struct options *oo; struct window *w;
struct window *w; struct client *c;
const char *optstr, *valstr; enum options_table_scope scope;
u_int i; struct options *oo;
struct options_entry *parent, *o;
const char *name, *value, *target;
int window, idx, already, error, ambiguous;
char *cause;
/* Get the option name and value. */ /* Parse option name and index. */
optstr = args->argv[0]; name = options_match(args->argv[0], &idx, &ambiguous);
if (*optstr == '\0') { if (name == NULL) {
ctx->error(ctx, "invalid option"); if (args_has(args, 'q'))
return (CMD_RETURN_NORMAL);
if (ambiguous)
cmdq_error(item, "ambiguous option: %s", args->argv[0]);
else
cmdq_error(item, "invalid option: %s", args->argv[0]);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (args->argc < 2) if (args->argc < 2)
valstr = NULL; value = NULL;
else else
valstr = args->argv[1]; value = args->argv[1];
/* Find the option entry, try each table. */ /*
table = oe = NULL; * Figure out the scope: for user options it comes from the arguments,
if (options_table_find(optstr, &table, &oe) != 0) { * otherwise from the option name.
ctx->error(ctx, "ambiguous option: %s", optstr); */
return (CMD_RETURN_ERROR); if (*name == '@') {
} window = (self->entry == &cmd_set_window_option_entry);
if (oe == NULL) { scope = options_scope_from_flags(args, window, fs, &oo, &cause);
ctx->error(ctx, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
}
/* Work out the tree from the table. */
if (table == server_options_table)
oo = &global_options;
else if (table == window_options_table) {
if (args_has(self->args, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, args_get(args, 't'), NULL);
if (wl == NULL)
return (CMD_RETURN_ERROR);
oo = &wl->window->options;
}
} else if (table == session_options_table) {
if (args_has(self->args, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
oo = &s->options;
}
} else { } else {
ctx->error(ctx, "unknown table"); if (options_get_only(global_options, name) != NULL)
scope = OPTIONS_TABLE_SERVER;
else if (options_get_only(global_s_options, name) != NULL)
scope = OPTIONS_TABLE_SESSION;
else if (options_get_only(global_w_options, name) != NULL)
scope = OPTIONS_TABLE_WINDOW;
else {
scope = OPTIONS_TABLE_NONE;
xasprintf(&cause, "unknown option: %s", args->argv[0]);
}
}
if (scope == OPTIONS_TABLE_NONE) {
if (args_has(args, 'q'))
return (CMD_RETURN_NORMAL);
cmdq_error(item, "%s", cause);
free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
/* Unset or set the option. */ /* Which table should this option go into? */
if (scope == OPTIONS_TABLE_SERVER)
oo = global_options;
else if (scope == OPTIONS_TABLE_SESSION) {
if (args_has(self->args, 'g'))
oo = global_s_options;
else if (s == NULL) {
target = args_get(args, 't');
if (target != NULL)
cmdq_error(item, "no such session: %s", target);
else
cmdq_error(item, "no current session");
return (CMD_RETURN_ERROR);
} else
oo = s->options;
} else if (scope == OPTIONS_TABLE_WINDOW) {
if (args_has(self->args, 'g'))
oo = global_w_options;
else if (wl == NULL) {
target = args_get(args, 't');
if (target != NULL)
cmdq_error(item, "no such window: %s", target);
else
cmdq_error(item, "no current window");
return (CMD_RETURN_ERROR);
} else
oo = wl->window->options;
}
o = options_get_only(oo, name);
parent = options_get(oo, name);
/* Check that array options and indexes match up. */
if (idx != -1) {
if (*name == '@' || options_array_size(parent, NULL) == -1) {
cmdq_error(item, "not an array: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
}
/* With -o, check this option is not already set. */
if (!args_has(args, 'u') && args_has(args, 'o')) {
if (idx == -1)
already = (o != NULL);
else {
if (o == NULL)
already = 0;
else
already = (options_array_get(o, idx) != NULL);
}
if (already) {
if (args_has(args, 'q'))
return (CMD_RETURN_NORMAL);
cmdq_error(item, "already set: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
}
/* Change the option. */
if (args_has(args, 'u')) { if (args_has(args, 'u')) {
if (cmd_set_option_unset(self, ctx, oe, oo, valstr) != 0) if (o == NULL)
return (CMD_RETURN_NORMAL);
if (idx == -1) {
if (oo == global_options ||
oo == global_s_options ||
oo == global_w_options)
options_default(oo, options_table_entry(o));
else
options_remove(o);
} else
options_array_set(o, idx, NULL, 0);
} else if (*name == '@') {
if (value == NULL) {
cmdq_error(item, "empty value");
return (CMD_RETURN_ERROR);
}
options_set_string(oo, name, append, "%s", value);
} else if (idx == -1 && options_array_size(parent, NULL) == -1) {
error = cmd_set_option_set(self, item, oo, parent, value);
if (error != 0)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} else { } else {
if (cmd_set_option_set(self, ctx, oe, oo, valstr) != 0) if (value == NULL) {
cmdq_error(item, "empty value");
return (CMD_RETURN_ERROR);
}
if (o == NULL)
o = options_empty(oo, options_table_entry(parent));
if (idx == -1) {
if (!append)
options_array_clear(o);
options_array_assign(o, value);
} else if (options_array_set(o, idx, value, append) != 0) {
cmdq_error(item, "invalid index: %s", args->argv[0]);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
}
/* Start or stop timers when automatic-rename changed. */
if (strcmp (oe->name, "automatic-rename") == 0) {
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) == NULL)
continue;
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
else if (event_initialized(&w->name_timer))
evtimer_del(&w->name_timer);
} }
} }
/* Update sizes and redraw. May not need it but meh. */ /* Update timers and so on for various options. */
if (strcmp(name, "automatic-rename") == 0) {
RB_FOREACH(w, windows, &windows) {
if (w->active == NULL)
continue;
if (options_get_number(w->options, "automatic-rename"))
w->active->flags |= PANE_CHANGED;
}
}
if (strcmp(name, "key-table") == 0) {
TAILQ_FOREACH(c, &clients, entry)
server_client_set_key_table(c, NULL);
}
if (strcmp(name, "status") == 0 ||
strcmp(name, "status-interval") == 0)
status_timer_start_all();
if (strcmp(name, "monitor-silence") == 0)
alerts_reset_all();
if (strcmp(name, "window-style") == 0 ||
strcmp(name, "window-active-style") == 0) {
RB_FOREACH(w, windows, &windows)
w->flags |= WINDOW_STYLECHANGED;
}
if (strcmp(name, "pane-border-status") == 0) {
RB_FOREACH(w, windows, &windows)
layout_fix_panes(w, w->sx, w->sy);
}
RB_FOREACH (s, sessions, &sessions)
status_update_saved(s);
/*
* Update sizes and redraw. May not always be necessary but do it
* anyway.
*/
recalculate_sizes(); recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { TAILQ_FOREACH(c, &clients, entry) {
c = ARRAY_ITEM(&clients, i); if (c->session != NULL)
if (c != NULL && c->session != NULL)
server_redraw_client(c); server_redraw_client(c);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
/* Unset an option. */ static int
int cmd_set_option_set(struct cmd *self, struct cmdq_item *item, struct options *oo,
cmd_set_option_unset(struct cmd *self, struct cmd_ctx *ctx, struct options_entry *parent, const char *value)
const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
struct args *args = self->args; const struct options_table_entry *oe;
struct args *args = self->args;
int append = args_has(args, 'a');
struct options_entry *o;
long long number;
const char *errstr;
key_code key;
if (args_has(args, 'g')) { oe = options_table_entry(parent);
ctx->error(ctx, "can't unset global option: %s", oe->name); if (value == NULL &&
return (-1); oe->type != OPTIONS_TABLE_FLAG &&
} oe->type != OPTIONS_TABLE_CHOICE) {
if (value != NULL) { cmdq_error(item, "empty value");
ctx->error(ctx, "value passed to unset option: %s", oe->name);
return (-1); return (-1);
} }
options_remove(oo, oe->name);
if (!args_has(args, 'q'))
ctx->info(ctx, "unset option: %s", oe->name);
return (0);
}
/* Set an option. */
int
cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo, const char *value)
{
struct args *args = self->args;
struct options_entry *o;
const char *s;
if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
ctx->error(ctx, "empty value");
return (-1);
}
o = NULL;
switch (oe->type) { switch (oe->type) {
case OPTIONS_TABLE_STRING: case OPTIONS_TABLE_STRING:
o = cmd_set_option_string(self, ctx, oe, oo, value); options_set_string(oo, oe->name, append, "%s", value);
break; return (0);
case OPTIONS_TABLE_NUMBER: case OPTIONS_TABLE_NUMBER:
o = cmd_set_option_number(self, ctx, oe, oo, value); number = strtonum(value, oe->minimum, oe->maximum, &errstr);
break; if (errstr != NULL) {
cmdq_error(item, "value is %s: %s", errstr, value);
return (-1);
}
options_set_number(oo, oe->name, number);
return (0);
case OPTIONS_TABLE_KEY: case OPTIONS_TABLE_KEY:
o = cmd_set_option_key(self, ctx, oe, oo, value); key = key_string_lookup_string(value);
break; if (key == KEYC_UNKNOWN) {
cmdq_error(item, "bad key: %s", value);
return (-1);
}
options_set_number(oo, oe->name, key);
return (0);
case OPTIONS_TABLE_COLOUR: case OPTIONS_TABLE_COLOUR:
o = cmd_set_option_colour(self, ctx, oe, oo, value); if ((number = colour_fromstring(value)) == -1) {
break; cmdq_error(item, "bad colour: %s", value);
return (-1);
}
o = options_set_number(oo, oe->name, number);
options_style_update_new(oo, o);
return (0);
case OPTIONS_TABLE_ATTRIBUTES: case OPTIONS_TABLE_ATTRIBUTES:
o = cmd_set_option_attributes(self, ctx, oe, oo, value); if ((number = attributes_fromstring(value)) == -1) {
break; cmdq_error(item, "bad attributes: %s", value);
return (-1);
}
o = options_set_number(oo, oe->name, number);
options_style_update_new(oo, o);
return (0);
case OPTIONS_TABLE_FLAG: case OPTIONS_TABLE_FLAG:
o = cmd_set_option_flag(self, ctx, oe, oo, value); return (cmd_set_option_flag(item, oe, oo, value));
break;
case OPTIONS_TABLE_CHOICE: case OPTIONS_TABLE_CHOICE:
o = cmd_set_option_choice(self, ctx, oe, oo, value); return (cmd_set_option_choice(item, oe, oo, value));
case OPTIONS_TABLE_STYLE:
o = options_set_style(oo, oe->name, append, value);
if (o == NULL) {
cmdq_error(item, "bad style: %s", value);
return (-1);
}
options_style_update_old(oo, o);
return (0);
case OPTIONS_TABLE_ARRAY:
break; break;
} }
if (o == NULL) return (-1);
return (-1);
s = options_table_print_entry(oe, o);
if (!args_has(args, 'q'))
ctx->info(ctx, "set option: %s -> %s", oe->name, s);
return (0);
} }
/* Set a string option. */ static int
struct options_entry * cmd_set_option_flag(struct cmdq_item *item,
cmd_set_option_string(struct cmd *self, unused struct cmd_ctx *ctx, const struct options_table_entry *oe, struct options *oo,
const struct options_table_entry *oe, struct options *oo, const char *value) const char *value)
{
struct args *args = self->args;
struct options_entry *o;
char *oldval, *newval;
if (args_has(args, 'a')) {
oldval = options_get_string(oo, oe->name);
xasprintf(&newval, "%s%s", oldval, value);
} else
newval = xstrdup(value);
o = options_set_string(oo, oe->name, "%s", newval);
free(newval);
return (o);
}
/* Set a number option. */
struct options_entry *
cmd_set_option_number(unused struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo, const char *value)
{
long long ll;
const char *errstr;
ll = strtonum(value, oe->minimum, oe->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
return (NULL);
}
return (options_set_number(oo, oe->name, ll));
}
/* Set a key option. */
struct options_entry *
cmd_set_option_key(unused struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo, const char *value)
{
int key;
if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
ctx->error(ctx, "bad key: %s", value);
return (NULL);
}
return (options_set_number(oo, oe->name, key));
}
/* Set a colour option. */
struct options_entry *
cmd_set_option_colour(unused struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo, const char *value)
{
int colour;
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
return (NULL);
}
return (options_set_number(oo, oe->name, colour));
}
/* Set an attributes option. */
struct options_entry *
cmd_set_option_attributes(unused struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo, const char *value)
{
int attr;
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
return (NULL);
}
return (options_set_number(oo, oe->name, attr));
}
/* Set a flag option. */
struct options_entry *
cmd_set_option_flag(unused struct cmd *self, struct cmd_ctx *ctx,
const struct options_table_entry *oe, struct options *oo, const char *value)
{ {
int flag; int flag;
if (value == NULL || *value == '\0') if (value == NULL || *value == '\0')
flag = !options_get_number(oo, oe->name); flag = !options_get_number(oo, oe->name);
else if (strcmp(value, "1") == 0 ||
strcasecmp(value, "on") == 0 ||
strcasecmp(value, "yes") == 0)
flag = 1;
else if (strcmp(value, "0") == 0 ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
flag = 0;
else { else {
if ((value[0] == '1' && value[1] == '\0') || cmdq_error(item, "bad value: %s", value);
strcasecmp(value, "on") == 0 || return (-1);
strcasecmp(value, "yes") == 0)
flag = 1;
else if ((value[0] == '0' && value[1] == '\0') ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
return (NULL);
}
} }
options_set_number(oo, oe->name, flag);
return (options_set_number(oo, oe->name, flag)); return (0);
} }
/* Set a choice option. */ static int
struct options_entry * cmd_set_option_choice(struct cmdq_item *item,
cmd_set_option_choice(unused struct cmd *self, struct cmd_ctx *ctx, const struct options_table_entry *oe, struct options *oo,
const struct options_table_entry *oe, struct options *oo, const char *value) const char *value)
{ {
const char **choicep; const char **cp;
int n, choice = -1; int n, choice = -1;
n = 0; if (value == NULL) {
for (choicep = oe->choices; *choicep != NULL; choicep++) { choice = options_get_number(oo, oe->name);
n++; if (choice < 2)
if (strncmp(*choicep, value, strlen(value)) != 0) choice = !choice;
continue; } else {
n = 0;
if (choice != -1) { for (cp = oe->choices; *cp != NULL; cp++) {
ctx->error(ctx, "ambiguous value: %s", value); if (strcmp(*cp, value) == 0)
return (NULL); choice = n;
n++;
}
if (choice == -1) {
cmdq_error(item, "unknown value: %s", value);
return (-1);
} }
choice = n - 1;
} }
if (choice == -1) { options_set_number(oo, oe->name, choice);
ctx->error(ctx, "unknown value: %s", value); return (0);
return (NULL);
}
return (options_set_number(oo, oe->name, choice));
} }

View File

@@ -1,111 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Show a paste buffer.
*/
enum cmd_retval cmd_show_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_buffer_entry = {
"show-buffer", "showb",
"b:", 0, 0,
CMD_BUFFER_USAGE,
0,
NULL,
NULL,
cmd_show_buffer_exec
};
enum cmd_retval
cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct session *s;
struct paste_buffer *pb;
int buffer;
char *in, *buf, *ptr, *cause;
size_t size, len;
u_int width;
if ((s = cmd_find_session(ctx, NULL, 0)) == NULL)
return (CMD_RETURN_ERROR);
if (!args_has(args, 'b')) {
if ((pb = paste_get_top(&global_buffers)) == NULL) {
ctx->error(ctx, "no buffers");
return (CMD_RETURN_ERROR);
}
} else {
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
ctx->error(ctx, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
pb = paste_get_index(&global_buffers, buffer);
if (pb == NULL) {
ctx->error(ctx, "no buffer %d", buffer);
return (CMD_RETURN_ERROR);
}
}
size = pb->size;
if (size > SIZE_MAX / 4 - 1)
size = SIZE_MAX / 4 - 1;
in = xmalloc(size * 4 + 1);
strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB);
width = s->sx;
if (ctx->cmdclient != NULL)
width = ctx->cmdclient->tty.sx;
buf = xmalloc(width + 1);
len = 0;
ptr = in;
do {
buf[len++] = *ptr++;
if (len == width || buf[len - 1] == '\n') {
if (buf[len - 1] == '\n')
len--;
buf[len] = '\0';
ctx->print(ctx, "%s", buf);
len = 0;
}
} while (*ptr != '\0');
if (len != 0) {
buf[len] = '\0';
ctx->print(ctx, "%s", buf);
}
free(buf);
free(in);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,53 +27,110 @@
* Show environment. * Show environment.
*/ */
enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_show_environment_exec(struct cmd *,
struct cmdq_item *);
static char *cmd_show_environment_escape(struct environ_entry *);
static void cmd_show_environment_print(struct cmd *, struct cmdq_item *,
struct environ_entry *);
const struct cmd_entry cmd_show_environment_entry = { const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv", .name = "show-environment",
"gt:", 0, 1, .alias = "showenv",
"[-g] " CMD_TARGET_SESSION_USAGE " [name]",
0, .args = { "gst:", 0, 1 },
NULL, .usage = "[-gs] " CMD_TARGET_SESSION_USAGE " [name]",
NULL,
cmd_show_environment_exec .tflag = CMD_SESSION_CANFAIL,
.flags = CMD_AFTERHOOK,
.exec = cmd_show_environment_exec
}; };
enum cmd_retval static char *
cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_show_environment_escape(struct environ_entry *envent)
{
const char *value = envent->value;
char c, *out, *ret;
out = ret = xmalloc(strlen(value) * 2 + 1); /* at most twice the size */
while ((c = *value++) != '\0') {
/* POSIX interprets $ ` " and \ in double quotes. */
if (c == '$' || c == '`' || c == '"' || c == '\\')
*out++ = '\\';
*out++ = c;
}
*out = '\0';
return (ret);
}
static void
cmd_show_environment_print(struct cmd *self, struct cmdq_item *item,
struct environ_entry *envent)
{
char *escaped;
if (!args_has(self->args, 's')) {
if (envent->value != NULL)
cmdq_print(item, "%s=%s", envent->name, envent->value);
else
cmdq_print(item, "-%s", envent->name);
return;
}
if (envent->value != NULL) {
escaped = cmd_show_environment_escape(envent);
cmdq_print(item, "%s=\"%s\"; export %s;", envent->name, escaped,
envent->name);
free(escaped);
} else
cmdq_print(item, "unset %s;", envent->name);
}
static enum cmd_retval
cmd_show_environment_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s;
struct environ *env; struct environ *env;
struct environ_entry *envent; struct environ_entry *envent;
const char *target;
if ((target = args_get(args, 't')) != NULL) {
if (item->state.tflag.s == NULL) {
cmdq_error(item, "no such session: %s", target);
return (CMD_RETURN_ERROR);
}
}
if (args_has(self->args, 'g')) if (args_has(self->args, 'g'))
env = &global_environ; env = global_environ;
else { else {
if ((s = cmd_find_session(ctx, args_get(args, 't'), 0)) == NULL) if (item->state.tflag.s == NULL) {
target = args_get(args, 't');
if (target != NULL)
cmdq_error(item, "no such session: %s", target);
else
cmdq_error(item, "no current session");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
env = &s->environ; }
env = item->state.tflag.s->environ;
} }
if (args->argc != 0) { if (args->argc != 0) {
envent = environ_find(env, args->argv[0]); envent = environ_find(env, args->argv[0]);
if (envent == NULL) { if (envent == NULL) {
ctx->error(ctx, "unknown variable: %s", args->argv[0]); cmdq_error(item, "unknown variable: %s", args->argv[0]);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (envent->value != NULL) cmd_show_environment_print(self, item, envent);
ctx->print(ctx, "%s=%s", envent->name, envent->value);
else
ctx->print(ctx, "-%s", envent->name);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
RB_FOREACH(envent, environ, env) { envent = environ_first(env);
if (envent->value != NULL) while (envent != NULL) {
ctx->print(ctx, "%s=%s", envent->name, envent->value); cmd_show_environment_print(self, item, envent);
else envent = environ_next(envent);
ctx->print(ctx, "-%s", envent->name);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -20,6 +20,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -27,37 +28,91 @@
* Show client message log. * Show client message log.
*/ */
enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_show_messages_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_show_messages_entry = { const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs", .name = "show-messages",
"t:", 0, 0, .alias = "showmsgs",
CMD_TARGET_CLIENT_USAGE,
0, .args = { "JTt:", 0, 0 },
NULL, .usage = "[-JT] " CMD_TARGET_CLIENT_USAGE,
NULL,
cmd_show_messages_exec .tflag = CMD_CLIENT,
.flags = CMD_AFTERHOOK,
.exec = cmd_show_messages_exec
}; };
enum cmd_retval static int cmd_show_messages_terminals(struct cmdq_item *, int);
cmd_show_messages_exec(struct cmd *self, struct cmd_ctx *ctx) static int cmd_show_messages_jobs(struct cmdq_item *, int);
static int
cmd_show_messages_terminals(struct cmdq_item *item, int blank)
{
struct tty_term *term;
u_int i, n;
n = 0;
LIST_FOREACH(term, &tty_terms, entry) {
if (blank) {
cmdq_print(item, "%s", "");
blank = 0;
}
cmdq_print(item, "Terminal %u: %s [references=%u, flags=0x%x]:",
n, term->name, term->references, term->flags);
n++;
for (i = 0; i < tty_term_ncodes(); i++)
cmdq_print(item, "%s", tty_term_describe(term, i));
}
return (n != 0);
}
static int
cmd_show_messages_jobs(struct cmdq_item *item, int blank)
{
struct job *job;
u_int n;
n = 0;
LIST_FOREACH(job, &all_jobs, lentry) {
if (blank) {
cmdq_print(item, "%s", "");
blank = 0;
}
cmdq_print(item, "Job %u: %s [fd=%d, pid=%ld, status=%d]",
n, job->cmd, job->fd, (long)job->pid, job->status);
n++;
}
return (n != 0);
}
static enum cmd_retval
cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct client *c; struct client *c = item->state.c;
struct message_entry *msg; struct message_entry *msg;
char *tim; char *tim;
u_int i; int done, blank;
if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL) done = blank = 0;
return (CMD_RETURN_ERROR); if (args_has(args, 'T')) {
blank = cmd_show_messages_terminals(item, blank);
for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) { done = 1;
msg = &ARRAY_ITEM(&c->message_log, i); }
if (args_has(args, 'J')) {
cmd_show_messages_jobs(item, blank);
done = 1;
}
if (done)
return (CMD_RETURN_NORMAL);
TAILQ_FOREACH(msg, &c->message_log, entry) {
tim = ctime(&msg->msg_time); tim = ctime(&msg->msg_time);
*strchr(tim, '\n') = '\0'; *strchr(tim, '\n') = '\0';
ctx->print(ctx, "%s %s", tim, msg->msg); cmdq_print(item, "%s %s", tim, msg->msg);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,87 +27,153 @@
* Show options. * Show options.
*/ */
enum cmd_retval cmd_show_options_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_show_options_exec(struct cmd *, struct cmdq_item *);
static enum cmd_retval cmd_show_options_one(struct cmd *, struct cmdq_item *,
struct options *);
static enum cmd_retval cmd_show_options_all(struct cmd *, struct cmdq_item *,
struct options *);
const struct cmd_entry cmd_show_options_entry = { const struct cmd_entry cmd_show_options_entry = {
"show-options", "show", .name = "show-options",
"gst:w", 0, 1, .alias = "show",
"[-gsw] [-t target-session|target-window] [option]",
0, .args = { "gqst:vw", 0, 1 },
NULL, .usage = "[-gqsvw] [-t target-session|target-window] [option]",
NULL,
cmd_show_options_exec .tflag = CMD_WINDOW_CANFAIL,
.flags = CMD_AFTERHOOK,
.exec = cmd_show_options_exec
}; };
const struct cmd_entry cmd_show_window_options_entry = { const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw", .name = "show-window-options",
"gt:", 0, 1, .alias = "showw",
"[-g] " CMD_TARGET_WINDOW_USAGE " [option]",
0, .args = { "gvt:", 0, 1 },
NULL, .usage = "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
NULL,
cmd_show_options_exec .tflag = CMD_WINDOW_CANFAIL,
.flags = CMD_AFTERHOOK,
.exec = cmd_show_options_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_show_options_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
const struct options_table_entry *table, *oe; struct cmd_find_state *fs = &item->state.tflag;
struct session *s; struct options *oo;
struct winlink *wl; enum options_table_scope scope;
struct options *oo; char *cause;
struct options_entry *o; int window;
const char *optval;
if (args_has(self->args, 's')) { window = (self->entry == &cmd_show_window_options_entry);
oo = &global_options; scope = options_scope_from_flags(args, window, fs, &oo, &cause);
table = server_options_table; if (scope == OPTIONS_TABLE_NONE) {
} else if (args_has(self->args, 'w') || cmdq_error(item, "%s", cause);
self->entry == &cmd_show_window_options_entry) { free(cause);
table = window_options_table; return (CMD_RETURN_ERROR);
if (args_has(self->args, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, args_get(args, 't'), NULL);
if (wl == NULL)
return (CMD_RETURN_ERROR);
oo = &wl->window->options;
}
} else {
table = session_options_table;
if (args_has(self->args, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
oo = &s->options;
}
} }
if (args->argc != 0) { if (args->argc == 0)
table = oe = NULL; return (cmd_show_options_all(self, item, oo));
if (options_table_find(args->argv[0], &table, &oe) != 0) { else
ctx->error(ctx, "ambiguous option: %s", args->argv[0]); return (cmd_show_options_one(self, item, oo));
return (CMD_RETURN_ERROR); }
static void
cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
struct options_entry *o, int idx)
{
const char *name;
const char *value;
char *tmp, *escaped;
u_int size, i;
if (idx != -1) {
xasprintf(&tmp, "%s[%d]", options_name(o), idx);
name = tmp;
} else {
if (options_array_size(o, &size) != -1) {
for (i = 0; i < size; i++) {
if (options_array_get(o, i) == NULL)
continue;
cmd_show_options_print(self, item, o, i);
}
return;
} }
if (oe == NULL) { tmp = NULL;
ctx->error(ctx, "unknown option: %s", args->argv[0]); name = options_name(o);
return (CMD_RETURN_ERROR); }
}
if ((o = options_find1(oo, oe->name)) == NULL) value = options_tostring(o, idx, 0);
if (args_has(self->args, 'v'))
cmdq_print(item, "%s", value);
else if (options_isstring(o)) {
utf8_stravis(&escaped, value, VIS_OCTAL|VIS_TAB|VIS_NL|VIS_DQ);
cmdq_print(item, "%s \"%s\"", name, escaped);
free(escaped);
} else
cmdq_print(item, "%s %s", name, value);
free(tmp);
}
static enum cmd_retval
cmd_show_options_one(struct cmd *self, struct cmdq_item *item,
struct options *oo)
{
struct args *args = self->args;
struct options_entry *o;
int idx, ambiguous;
const char *name = args->argv[0];
o = options_match_get(oo, name, &idx, 1, &ambiguous);
if (o == NULL) {
if (args_has(args, 'q'))
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
optval = options_table_print_entry(oe, o); if (ambiguous) {
ctx->print(ctx, "%s %s", oe->name, optval); cmdq_error(item, "ambiguous option: %s", name);
} else { return (CMD_RETURN_ERROR);
for (oe = table; oe->name != NULL; oe++) {
if ((o = options_find1(oo, oe->name)) == NULL)
continue;
optval = options_table_print_entry(oe, o);
ctx->print(ctx, "%s %s", oe->name, optval);
} }
if (*name != '@' &&
options_match_get(oo, name, &idx, 0, &ambiguous) != NULL)
return (CMD_RETURN_NORMAL);
cmdq_error(item, "unknown option: %s", name);
return (CMD_RETURN_ERROR);
}
cmd_show_options_print(self, item, o, idx);
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_show_options_all(struct cmd *self, struct cmdq_item *item,
struct options *oo)
{
struct options_entry *o;
const struct options_table_entry *oe;
u_int size, idx;
o = options_first(oo);
while (o != NULL) {
oe = options_table_entry(o);
if (oe != NULL && oe->style != NULL) {
o = options_next(o);
continue;
}
if (options_array_size(o, &size) == -1)
cmd_show_options_print(self, item, o, -1);
else {
for (idx = 0; idx < size; idx++) {
if (options_array_get(o, idx) == NULL)
continue;
cmd_show_options_print(self, item, o, idx);
}
}
o = options_next(o);
} }
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,4 +1,4 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -18,7 +18,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#include <glob.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
@@ -26,51 +29,70 @@
* Sources a configuration file. * Sources a configuration file.
*/ */
enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmdq_item *);
static enum cmd_retval cmd_source_file_done(struct cmdq_item *, void *);
const struct cmd_entry cmd_source_file_entry = { const struct cmd_entry cmd_source_file_entry = {
"source-file", "source", .name = "source-file",
"", 1, 1, .alias = "source",
"path",
0, .args = { "q", 1, 1 },
NULL, .usage = "[-q] path",
NULL,
cmd_source_file_exec .flags = 0,
.exec = cmd_source_file_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_source_file_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args; struct args *args = self->args;
struct causelist causes; int quiet = args_has(args, 'q');
char *cause; struct client *c = item->client;
struct window_pane *wp; struct cmdq_item *new_item;
int retval; enum cmd_retval retval;
char *pattern, *tmp;
const char *path = args->argv[0];
glob_t g;
u_int i; u_int i;
ARRAY_INIT(&causes); if (*path == '/')
pattern = xstrdup(path);
retval = load_cfg(args->argv[0], ctx, &causes); else {
if (ARRAY_EMPTY(&causes)) utf8_stravis(&tmp, server_client_get_cwd(c), VIS_GLOB);
return (retval); xasprintf(&pattern, "%s/%s", tmp, path);
free(tmp);
if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) {
wp = RB_MIN(sessions, &sessions)->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
window_copy_add(wp, "%s", cause);
free(cause);
}
} else {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
free(cause);
}
} }
ARRAY_FREE(&causes); log_debug("%s: %s", __func__, pattern);
retval = CMD_RETURN_NORMAL;
if (glob(pattern, 0, NULL, &g) != 0) {
if (!quiet || errno != ENOENT) {
cmdq_error(item, "%s: %s", path, strerror(errno));
retval = CMD_RETURN_ERROR;
}
free(pattern);
return (retval);
}
free(pattern);
for (i = 0; i < (u_int)g.gl_pathc; i++) {
if (load_cfg(g.gl_pathv[i], c, item, quiet) < 0)
retval = CMD_RETURN_ERROR;
}
if (cfg_finished) {
new_item = cmdq_get_callback(cmd_source_file_done, NULL);
cmdq_insert_after(item, new_item);
}
globfree(&g);
return (retval); return (retval);
} }
static enum cmd_retval
cmd_source_file_done(struct cmdq_item *item, __unused void *data)
{
cfg_print_causes(item);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +18,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -27,62 +30,68 @@
* Split a window (add a new pane). * Split a window (add a new pane).
*/ */
void cmd_split_window_key_binding(struct cmd *, int); #define SPLIT_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
enum cmd_retval cmd_split_window_exec(struct cmd *, struct cmd_ctx *);
static enum cmd_retval cmd_split_window_exec(struct cmd *,
struct cmdq_item *);
const struct cmd_entry cmd_split_window_entry = { const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw", .name = "split-window",
"c:dF:l:hp:Pt:v", 0, 1, .alias = "splitw",
"[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
"[-t target-pane] [command]", .args = { "bc:dfF:l:hp:Pt:v", 0, -1 },
0, .usage = "[-bdfhvP] [-c start-directory] [-F format] "
cmd_split_window_key_binding, "[-p percentage|-l size] " CMD_TARGET_PANE_USAGE " [command]",
NULL,
cmd_split_window_exec .tflag = CMD_PANE,
.flags = 0,
.exec = cmd_split_window_exec
}; };
void static enum cmd_retval
cmd_split_window_key_binding(struct cmd *self, int key) cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
{
self->args = args_create(0);
if (key == '%')
args_set(self->args, 'h', NULL);
}
enum cmd_retval
cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct args *args = self->args; struct args *args = self->args;
struct session *s; struct client *c = item->state.c;
struct winlink *wl; struct session *s = item->state.tflag.s;
struct window *w; struct winlink *wl = item->state.tflag.wl;
struct window_pane *wp, *new_wp = NULL; struct window *w = wl->window;
struct environ env; struct window_pane *wp = item->state.tflag.wp, *new_wp = NULL;
const char *cmd, *cwd, *shell; struct environ *env;
char *cause, *new_cause; const char *cmd, *path, *shell, *template, *cwd, *to_free;
char **argv, *cause, *new_cause, *cp;
u_int hlimit; u_int hlimit;
int size, percentage; int argc, size, percentage;
enum layout_type type; enum layout_type type;
struct layout_cell *lc; struct layout_cell *lc;
const char *template; struct environ_entry *envent;
struct client *c; struct cmd_find_state fs;
struct format_tree *ft;
char *cp;
if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL) server_unzoom_window(w);
return (CMD_RETURN_ERROR);
w = wl->window;
environ_init(&env); if (args->argc == 0) {
environ_copy(&global_environ, &env); cmd = options_get_string(s->options, "default-command");
environ_copy(&s->environ, &env); if (cmd != NULL && *cmd != '\0') {
server_fill_environ(s, &env); argc = 1;
argv = (char **)&cmd;
} else {
argc = 0;
argv = NULL;
}
} else {
argc = args->argc;
argv = args->argv;
}
if (args->argc == 0) to_free = NULL;
cmd = options_get_string(&s->options, "default-command"); if (args_has(args, 'c')) {
cwd = args_get(args, 'c');
to_free = cwd = format_single(item, cwd, c, s, NULL, NULL);
} else if (item->client != NULL && item->client->session == NULL)
cwd = item->client->cwd;
else else
cmd = args->argv[0]; cwd = s->cwd;
cwd = cmd_get_default_path(ctx, args_get(args, 'c'));
type = LAYOUT_TOPBOTTOM; type = LAYOUT_TOPBOTTOM;
if (args_has(args, 'h')) if (args_has(args, 'h'))
@@ -110,22 +119,37 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
else else
size = (wp->sx * percentage) / 100; size = (wp->sx * percentage) / 100;
} }
hlimit = options_get_number(&s->options, "history-limit"); hlimit = options_get_number(s->options, "history-limit");
shell = options_get_string(&s->options, "default-shell"); shell = options_get_string(s->options, "default-shell");
if (*shell == '\0' || areshell(shell)) if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL; shell = _PATH_BSHELL;
if ((lc = layout_split_pane(wp, type, size, 0)) == NULL) { lc = layout_split_pane(wp, type, size, args_has(args, 'b'),
args_has(args, 'f'));
if (lc == NULL) {
cause = xstrdup("pane too small"); cause = xstrdup("pane too small");
goto error; goto error;
} }
new_wp = window_add_pane(w, hlimit); new_wp = window_add_pane(w, wp, args_has(args, 'b'), hlimit);
if (window_pane_spawn(
new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
layout_assign_pane(lc, new_wp); layout_assign_pane(lc, new_wp);
path = NULL;
if (item->client != NULL && item->client->session == NULL)
envent = environ_find(item->client->environ, "PATH");
else
envent = environ_find(s->environ, "PATH");
if (envent != NULL)
path = envent->value;
env = environ_for_session(s);
if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, env,
s->tio, &cause) != 0) {
environ_free(env);
goto error;
}
environ_free(env);
server_redraw_window(w); server_redraw_window(w);
if (!args_has(args, 'd')) { if (!args_has(args, 'd')) {
@@ -135,33 +159,37 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
} else } else
server_status_session(s); server_status_session(s);
environ_free(&env);
if (args_has(args, 'P')) { if (args_has(args, 'P')) {
if ((template = args_get(args, 'F')) == NULL) if ((template = args_get(args, 'F')) == NULL)
template = SPLIT_WINDOW_TEMPLATE; template = SPLIT_WINDOW_TEMPLATE;
cp = format_single(item, template, c, s, wl, new_wp);
ft = format_create(); cmdq_print(item, "%s", cp);
if ((c = cmd_find_client(ctx, NULL)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, new_wp);
cp = format_expand(ft, template);
ctx->print(ctx, "%s", cp);
free(cp); free(cp);
format_free(ft);
} }
notify_window_layout_changed(w); notify_window("window-layout-changed", w);
if (to_free != NULL)
free((void *)to_free);
cmd_find_clear_state(&fs, NULL, 0);
fs.s = s;
fs.wl = wl;
fs.w = w;
fs.wp = new_wp;
cmd_find_log_state(__func__, &fs);
hooks_insert(s->hooks, item, &fs, "after-split-window");
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
error: error:
environ_free(&env); if (new_wp != NULL) {
if (new_wp != NULL) layout_close_pane(new_wp);
window_remove_pane(w, new_wp); window_remove_pane(w, new_wp);
ctx->error(ctx, "create pane failed: %s", cause); }
cmdq_error(item, "create pane failed: %s", cause);
free(cause); free(cause);
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -31,13 +31,14 @@
* Parse a command from a string. * Parse a command from a string.
*/ */
int cmd_string_getc(const char *, size_t *); static int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(size_t *); static void cmd_string_ungetc(size_t *);
char *cmd_string_string(const char *, size_t *, char, int); static void cmd_string_copy(char **, char *, size_t *);
char *cmd_string_variable(const char *, size_t *); static char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_expand_tilde(const char *, size_t *); static char *cmd_string_variable(const char *, size_t *);
static char *cmd_string_expand_tilde(const char *, size_t *);
int static int
cmd_string_getc(const char *s, size_t *p) cmd_string_getc(const char *s, size_t *p)
{ {
const u_char *ucs = s; const u_char *ucs = s;
@@ -47,63 +48,38 @@ cmd_string_getc(const char *s, size_t *p)
return (ucs[(*p)++]); return (ucs[(*p)++]);
} }
void static void
cmd_string_ungetc(size_t *p) cmd_string_ungetc(size_t *p)
{ {
(*p)--; (*p)--;
} }
/*
* Parse command string. Returns -1 on error. If returning -1, cause is error
* string, or NULL for empty command.
*/
int int
cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause) cmd_string_split(const char *s, int *rargc, char ***rargv)
{ {
size_t p; size_t p = 0;
int ch, i, argc, rval; int ch, argc = 0, append = 0;
char **argv, *buf, *t; char **argv = NULL, *buf = NULL, *t;
const char *whitespace, *equals; const char *whitespace, *equals;
size_t len; size_t len = 0;
argv = NULL;
argc = 0;
buf = NULL;
len = 0;
*cause = NULL;
*cmdlist = NULL;
rval = -1;
p = 0;
for (;;) { for (;;) {
ch = cmd_string_getc(s, &p); ch = cmd_string_getc(s, &p);
switch (ch) { switch (ch) {
case '\'': case '\'':
if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL) if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL)
goto error; goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1); cmd_string_copy(&buf, t, &len);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
break; break;
case '"': case '"':
if ((t = cmd_string_string(s, &p, '"', 1)) == NULL) if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
goto error; goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1); cmd_string_copy(&buf, t, &len);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
break; break;
case '$': case '$':
if ((t = cmd_string_variable(s, &p)) == NULL) if ((t = cmd_string_variable(s, &p)) == NULL)
goto error; goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1); cmd_string_copy(&buf, t, &len);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
break; break;
case '#': case '#':
/* Comment: discard rest of line. */ /* Comment: discard rest of line. */
@@ -114,10 +90,11 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
case ' ': case ' ':
case '\t': case '\t':
if (buf != NULL) { if (buf != NULL) {
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, len + 1);
buf[len] = '\0'; buf[len] = '\0';
argv = xrealloc(argv, argc + 1, sizeof *argv); argv = xreallocarray(argv, argc + 1,
sizeof *argv);
argv[argc++] = buf; argv[argc++] = buf;
buf = NULL; buf = NULL;
@@ -132,56 +109,88 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
whitespace = argv[0] + strcspn(argv[0], " \t"); whitespace = argv[0] + strcspn(argv[0], " \t");
if (equals == NULL || equals > whitespace) if (equals == NULL || equals > whitespace)
break; break;
environ_put(&global_environ, argv[0]); environ_put(global_environ, argv[0]);
argc--; argc--;
memmove(argv, argv + 1, argc * (sizeof *argv)); memmove(argv, argv + 1, argc * (sizeof *argv));
} }
if (argc == 0) goto done;
goto out;
*cmdlist = cmd_list_parse(argc, argv, cause);
if (*cmdlist == NULL)
goto out;
rval = 0;
goto out;
case '~': case '~':
if (buf == NULL) { if (buf != NULL) {
if ((t = cmd_string_expand_tilde(s, &p)) == NULL) append = 1;
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
break; break;
} }
/* FALLTHROUGH */ t = cmd_string_expand_tilde(s, &p);
default: if (t == NULL)
if (len >= SIZE_MAX - 2)
goto error; goto error;
cmd_string_copy(&buf, t, &len);
buf = xrealloc(buf, 1, len + 1); break;
buf[len++] = ch; default:
append = 1;
break; break;
} }
if (append) {
if (len >= SIZE_MAX - 2)
goto error;
buf = xrealloc(buf, len + 1);
buf[len++] = ch;
}
append = 0;
} }
done:
*rargc = argc;
*rargv = argv;
free(buf);
return (0);
error:
if (argv != NULL)
cmd_free_argv(argc, argv);
free(buf);
return (-1);
}
struct cmd_list *
cmd_string_parse(const char *s, const char *file, u_int line, char **cause)
{
struct cmd_list *cmdlist = NULL;
int argc;
char **argv;
*cause = NULL;
if (cmd_string_split(s, &argc, &argv) != 0)
goto error;
if (argc != 0) {
cmdlist = cmd_list_parse(argc, argv, file, line, cause);
if (cmdlist == NULL) {
cmd_free_argv(argc, argv);
goto error;
}
}
cmd_free_argv(argc, argv);
return (cmdlist);
error: error:
xasprintf(cause, "invalid or unknown command: %s", s); xasprintf(cause, "invalid or unknown command: %s", s);
return (NULL);
out:
free(buf);
if (argv != NULL) {
for (i = 0; i < argc; i++)
free(argv[i]);
free(argv);
}
return (rval);
} }
char * static void
cmd_string_copy(char **dst, char *src, size_t *len)
{
size_t srclen;
srclen = strlen(src);
*dst = xrealloc(*dst, *len + srclen + 1);
strlcpy(*dst + *len, src, srclen + 1);
*len += srclen;
free(src);
}
static char *
cmd_string_string(const char *s, size_t *p, char endch, int esc) cmd_string_string(const char *s, size_t *p, char endch, int esc)
{ {
int ch; int ch;
@@ -220,20 +229,17 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
break; break;
if ((t = cmd_string_variable(s, p)) == NULL) if ((t = cmd_string_variable(s, p)) == NULL)
goto error; goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1); cmd_string_copy(&buf, t, &len);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
continue; continue;
} }
if (len >= SIZE_MAX - 2) if (len >= SIZE_MAX - 2)
goto error; goto error;
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, len + 1);
buf[len++] = ch; buf[len++] = ch;
} }
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, len + 1);
buf[len] = '\0'; buf[len] = '\0';
return (buf); return (buf);
@@ -242,7 +248,7 @@ error:
return (NULL); return (NULL);
} }
char * static char *
cmd_string_variable(const char *s, size_t *p) cmd_string_variable(const char *s, size_t *p)
{ {
int ch, fch; int ch, fch;
@@ -276,7 +282,7 @@ cmd_string_variable(const char *s, size_t *p)
return (t); return (t);
} }
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, len + 1);
buf[len++] = ch; buf[len++] = ch;
for (;;) { for (;;) {
@@ -286,7 +292,7 @@ cmd_string_variable(const char *s, size_t *p)
else { else {
if (len >= SIZE_MAX - 3) if (len >= SIZE_MAX - 3)
goto error; goto error;
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, len + 1);
buf[len++] = ch; buf[len++] = ch;
} }
} }
@@ -297,10 +303,10 @@ cmd_string_variable(const char *s, size_t *p)
if (ch != EOF && fch != '{') if (ch != EOF && fch != '{')
cmd_string_ungetc(p); /* ch */ cmd_string_ungetc(p); /* ch */
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, len + 1);
buf[len] = '\0'; buf[len] = '\0';
envent = environ_find(&global_environ, buf); envent = environ_find(global_environ, buf);
free(buf); free(buf);
if (envent == NULL) if (envent == NULL)
return (xstrdup("")); return (xstrdup(""));
@@ -311,31 +317,49 @@ error:
return (NULL); return (NULL);
} }
char * static char *
cmd_string_expand_tilde(const char *s, size_t *p) cmd_string_expand_tilde(const char *s, size_t *p)
{ {
struct passwd *pw; struct passwd *pw;
struct environ_entry *envent; struct environ_entry *envent;
char *home, *path, *username; char *home, *path, *user, *cp;
int last;
home = NULL; home = NULL;
if (cmd_string_getc(s, p) == '/') {
envent = environ_find(&global_environ, "HOME"); last = cmd_string_getc(s, p);
if (last == EOF || last == '/' || last == ' '|| last == '\t') {
envent = environ_find(global_environ, "HOME");
if (envent != NULL && *envent->value != '\0') if (envent != NULL && *envent->value != '\0')
home = envent->value; home = envent->value;
else if ((pw = getpwuid(getuid())) != NULL) else if ((pw = getpwuid(getuid())) != NULL)
home = pw->pw_dir; home = pw->pw_dir;
} else { } else {
cmd_string_ungetc(p); cmd_string_ungetc(p);
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
return (NULL); cp = user = xmalloc(strlen(s));
if ((pw = getpwnam(username)) != NULL) for (;;) {
last = cmd_string_getc(s, p);
if (last == EOF ||
last == '/' ||
last == ' '||
last == '\t')
break;
*cp++ = last;
}
*cp = '\0';
if ((pw = getpwnam(user)) != NULL)
home = pw->pw_dir; home = pw->pw_dir;
free(username); free(user);
} }
if (home == NULL) if (home == NULL)
return (NULL); return (NULL);
xasprintf(&path, "%s/", home); if (last != EOF)
xasprintf(&path, "%s%c", home, last);
else
xasprintf(&path, "%s", home);
return (path); return (path);
} }

View File

@@ -1,56 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Suspend client with SIGTSTP.
*/
enum cmd_retval cmd_suspend_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
NULL,
NULL,
cmd_suspend_client_exec
};
enum cmd_retval
cmd_suspend_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct client *c;
if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (CMD_RETURN_ERROR);
tty_stop_tty(&c->tty);
c->flags |= CLIENT_SUSPENDED;
server_write_client(c, MSG_SUSPEND, NULL, 0);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,62 +26,48 @@
* Swap two panes. * Swap two panes.
*/ */
void cmd_swap_pane_key_binding(struct cmd *, int); static enum cmd_retval cmd_swap_pane_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_pane_entry = { const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp", .name = "swap-pane",
"dDs:t:U", 0, 0, .alias = "swapp",
"[-dDU] " CMD_SRCDST_PANE_USAGE,
0, .args = { "dDs:t:U", 0, 0 },
cmd_swap_pane_key_binding, .usage = "[-dDU] " CMD_SRCDST_PANE_USAGE,
NULL,
cmd_swap_pane_exec .sflag = CMD_PANE_MARKED,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_swap_pane_exec
}; };
void static enum cmd_retval
cmd_swap_pane_key_binding(struct cmd *self, int key) cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
{ {
self->args = args_create(0);
if (key == '{')
args_set(self->args, 'U', NULL);
else if (key == '}')
args_set(self->args, 'D', NULL);
}
enum cmd_retval
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w; struct window *src_w, *dst_w;
struct window_pane *tmp_wp, *src_wp, *dst_wp; struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *src_lc, *dst_lc; struct layout_cell *src_lc, *dst_lc;
u_int sx, sy, xoff, yoff; u_int sx, sy, xoff, yoff;
dst_wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &dst_wp); dst_w = item->state.tflag.wl->window;
if (dst_wl == NULL) dst_wp = item->state.tflag.wp;
return (CMD_RETURN_ERROR); src_w = item->state.sflag.wl->window;
dst_w = dst_wl->window; src_wp = item->state.sflag.wp;
server_unzoom_window(dst_w);
if (!args_has(args, 's')) { if (args_has(self->args, 'D')) {
src_w = dst_w; src_w = dst_w;
if (args_has(self->args, 'D')) { src_wp = TAILQ_NEXT(dst_wp, entry);
src_wp = TAILQ_NEXT(dst_wp, entry); if (src_wp == NULL)
if (src_wp == NULL) src_wp = TAILQ_FIRST(&dst_w->panes);
src_wp = TAILQ_FIRST(&dst_w->panes); } else if (args_has(self->args, 'U')) {
} else if (args_has(self->args, 'U')) { src_w = dst_w;
src_wp = TAILQ_PREV(dst_wp, window_panes, entry); src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL) if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes); src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
} else
return (CMD_RETURN_NORMAL);
} else {
src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp);
if (src_wl == NULL)
return (CMD_RETURN_ERROR);
src_w = src_wl->window;
} }
server_unzoom_window(src_w);
if (src_wp == dst_wp) if (src_wp == dst_wp)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,49 +26,56 @@
* Swap one window with another. * Swap one window with another.
*/ */
int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *); static enum cmd_retval cmd_swap_window_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_swap_window_entry = { const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw", .name = "swap-window",
"ds:t:", 0, 0, .alias = "swapw",
"[-d] " CMD_SRCDST_WINDOW_USAGE,
0, .args = { "ds:t:", 0, 0 },
NULL, .usage = "[-d] " CMD_SRCDST_WINDOW_USAGE,
NULL,
cmd_swap_window_exec .sflag = CMD_WINDOW_MARKED,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_swap_window_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_swap_window_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = self->args;
const char *target_src, *target_dst;
struct session *src, *dst; struct session *src, *dst;
struct session_group *sg_src, *sg_dst; struct session_group *sg_src, *sg_dst;
struct winlink *wl_src, *wl_dst; struct winlink *wl_src, *wl_dst;
struct window *w; struct window *w_src, *w_dst;
target_src = args_get(args, 's'); wl_src = item->state.sflag.wl;
if ((wl_src = cmd_find_window(ctx, target_src, &src)) == NULL) src = item->state.sflag.s;
return (CMD_RETURN_ERROR); sg_src = session_group_contains(src);
target_dst = args_get(args, 't');
if ((wl_dst = cmd_find_window(ctx, target_dst, &dst)) == NULL)
return (CMD_RETURN_ERROR);
sg_src = session_group_find(src); wl_dst = item->state.tflag.wl;
sg_dst = session_group_find(dst); dst = item->state.tflag.s;
if (src != dst && sg_dst = session_group_contains(dst);
sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) {
ctx->error(ctx, "can't move window, sessions are grouped"); if (src != dst && sg_src != NULL && sg_dst != NULL &&
sg_src == sg_dst) {
cmdq_error(item, "can't move window, sessions are grouped");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (wl_dst->window == wl_src->window) if (wl_dst->window == wl_src->window)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
w = wl_dst->window; w_dst = wl_dst->window;
wl_dst->window = wl_src->window; TAILQ_REMOVE(&w_dst->winlinks, wl_dst, wentry);
wl_src->window = w; w_src = wl_src->window;
TAILQ_REMOVE(&w_src->winlinks, wl_src, wentry);
wl_dst->window = w_src;
TAILQ_INSERT_TAIL(&w_src->winlinks, wl_dst, wentry);
wl_src->window = w_dst;
TAILQ_INSERT_TAIL(&w_dst->winlinks, wl_src, wentry);
if (!args_has(self->args, 'd')) { if (!args_has(self->args, 'd')) {
session_select(dst, wl_dst->idx); session_select(dst, wl_dst->idx);

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -27,88 +27,98 @@
* Switch client to a different session. * Switch client to a different session.
*/ */
void cmd_switch_client_key_binding(struct cmd *, int); static enum cmd_retval cmd_switch_client_exec(struct cmd *,
enum cmd_retval cmd_switch_client_exec(struct cmd *, struct cmd_ctx *); struct cmdq_item *);
const struct cmd_entry cmd_switch_client_entry = { const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc", .name = "switch-client",
"lc:npt:r", 0, 0, .alias = "switchc",
"[-lnpr] [-c target-client] [-t target-session]",
CMD_READONLY, .args = { "lc:Enpt:rT:", 0, 0 },
cmd_switch_client_key_binding, .usage = "[-Elnpr] [-c target-client] [-t target-session] "
NULL, "[-T key-table]",
cmd_switch_client_exec
.cflag = CMD_CLIENT,
.tflag = CMD_SESSION_WITHPANE,
.flags = CMD_READONLY,
.exec = cmd_switch_client_exec
}; };
void static enum cmd_retval
cmd_switch_client_key_binding(struct cmd *self, int key) cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
{ {
self->args = args_create(0); struct args *args = self->args;
switch (key) { struct cmd_state *state = &item->state;
case '(': struct client *c = state->c;
args_set(self->args, 'p', NULL); struct session *s = item->state.tflag.s;
break; struct window_pane *wp;
case ')': const char *tablename;
args_set(self->args, 'n', NULL); struct key_table *table;
break;
case 'L':
args_set(self->args, 'l', NULL);
break;
}
}
enum cmd_retval if (args_has(args, 'r'))
cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) c->flags ^= CLIENT_READONLY;
{
struct args *args = self->args;
struct client *c;
struct session *s;
if ((c = cmd_find_client(ctx, args_get(args, 'c'))) == NULL) tablename = args_get(args, 'T');
return (CMD_RETURN_ERROR); if (tablename != NULL) {
table = key_bindings_get_table(tablename, 0);
if (args_has(args, 'r')) { if (table == NULL) {
if (c->flags & CLIENT_READONLY) { cmdq_error(item, "table %s doesn't exist", tablename);
c->flags &= ~CLIENT_READONLY; return (CMD_RETURN_ERROR);
ctx->info(ctx, "made client writable");
} else {
c->flags |= CLIENT_READONLY;
ctx->info(ctx, "made client read-only");
} }
table->references++;
key_bindings_unref_table(c->keytable);
c->keytable = table;
return (CMD_RETURN_NORMAL);
} }
s = NULL;
if (args_has(args, 'n')) { if (args_has(args, 'n')) {
if ((s = session_next_session(c->session)) == NULL) { if ((s = session_next_session(c->session)) == NULL) {
ctx->error(ctx, "can't find next session"); cmdq_error(item, "can't find next session");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else if (args_has(args, 'p')) { } else if (args_has(args, 'p')) {
if ((s = session_previous_session(c->session)) == NULL) { if ((s = session_previous_session(c->session)) == NULL) {
ctx->error(ctx, "can't find previous session"); cmdq_error(item, "can't find previous session");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else if (args_has(args, 'l')) { } else if (args_has(args, 'l')) {
if (c->last_session != NULL && session_alive(c->last_session)) if (c->last_session != NULL && session_alive(c->last_session))
s = c->last_session; s = c->last_session;
else
s = NULL;
if (s == NULL) { if (s == NULL) {
ctx->error(ctx, "can't find last session"); cmdq_error(item, "can't find last session");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else } else {
s = cmd_find_session(ctx, args_get(args, 't'), 0); if (item->client == NULL)
if (s == NULL) return (CMD_RETURN_NORMAL);
return (CMD_RETURN_ERROR); if (state->tflag.wl != NULL) {
wp = state->tflag.wp;
if (wp != NULL)
window_set_active_pane(wp->window, wp);
session_set_current(s, state->tflag.wl);
}
}
if (c->session != NULL) if (!args_has(args, 'E'))
environ_update(s->options, c->environ, s->environ);
if (c->session != NULL && c->session != s)
c->last_session = c->session; c->last_session = c->session;
c->session = s; c->session = s;
session_update_activity(s); if (!item->repeat)
server_client_set_key_table(c, NULL);
status_timer_start(c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
recalculate_sizes(); recalculate_sizes();
server_check_unattached(); server_check_unattached();
server_redraw_client(c); server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS; s->curw->flags &= ~WINLINK_ALERTFLAGS;
alerts_check_session(s);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,7 +1,7 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -26,91 +26,69 @@
* Unbind key from command. * Unbind key from command.
*/ */
enum cmd_retval cmd_unbind_key_check(struct args *); static enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmdq_item *);
enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *);
enum cmd_retval cmd_unbind_key_table(struct cmd *, struct cmd_ctx *, int);
const struct cmd_entry cmd_unbind_key_entry = { const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind", .name = "unbind-key",
"acnt:", 0, 1, .alias = "unbind",
"[-acn] [-t key-table] key",
0, .args = { "anT:", 0, 1 },
NULL, .usage = "[-an] [-T key-table] key",
cmd_unbind_key_check,
cmd_unbind_key_exec .flags = CMD_AFTERHOOK,
.exec = cmd_unbind_key_exec
}; };
enum cmd_retval static enum cmd_retval
cmd_unbind_key_check(struct args *args) cmd_unbind_key_exec(struct cmd *self, struct cmdq_item *item)
{ {
if (args_has(args, 'a') && args->argc != 0) struct args *args = self->args;
return (CMD_RETURN_ERROR); key_code key;
if (!args_has(args, 'a') && args->argc != 1) const char *tablename;
return (CMD_RETURN_ERROR);
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct key_binding *bd;
int key;
if (!args_has(args, 'a')) { if (!args_has(args, 'a')) {
key = key_string_lookup_string(args->argv[0]); if (args->argc != 1) {
if (key == KEYC_NONE) { cmdq_error(item, "missing key");
ctx->error(ctx, "unknown key: %s", args->argv[0]);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
} else key = key_string_lookup_string(args->argv[0]);
key = KEYC_NONE; if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
cmdq_error(item, "unknown key: %s", args->argv[0]);
if (args_has(args, 't')) return (CMD_RETURN_ERROR);
return (cmd_unbind_key_table(self, ctx, key));
if (key == KEYC_NONE) {
while (!RB_EMPTY(&key_bindings)) {
bd = RB_ROOT(&key_bindings);
key_bindings_remove(bd->key);
} }
} else {
if (args->argc != 0) {
cmdq_error(item, "key given with -a");
return (CMD_RETURN_ERROR);
}
key = KEYC_UNKNOWN;
}
if (key == KEYC_UNKNOWN) {
tablename = args_get(args, 'T');
if (tablename == NULL) {
key_bindings_remove_table("root");
key_bindings_remove_table("prefix");
return (CMD_RETURN_NORMAL);
}
if (key_bindings_get_table(tablename, 0) == NULL) {
cmdq_error(item, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
key_bindings_remove_table(tablename);
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }
if (!args_has(args, 'n')) if (args_has(args, 'T')) {
key |= KEYC_PREFIX; tablename = args_get(args, 'T');
key_bindings_remove(key); if (key_bindings_get_table(tablename, 0) == NULL) {
return (CMD_RETURN_NORMAL); cmdq_error(item, "table %s doesn't exist", tablename);
} return (CMD_RETURN_ERROR);
enum cmd_retval
cmd_unbind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
{
struct args *args = self->args;
const char *tablename;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
ctx->error(ctx, "unknown key table: %s", tablename);
return (CMD_RETURN_ERROR);
}
if (key == KEYC_NONE) {
while (!RB_EMPTY(mtab->tree)) {
mbind = RB_ROOT(mtab->tree);
RB_REMOVE(mode_key_tree, mtab->tree, mbind);
free(mbind);
} }
return (CMD_RETURN_NORMAL); } else if (args_has(args, 'n'))
} tablename = "root";
else
mtmp.key = key; tablename = "prefix";
mtmp.mode = !!args_has(args, 'c'); key_bindings_remove(tablename, key);
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
RB_REMOVE(mode_key_tree, mtab->tree, mbind);
free(mbind);
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@@ -1,70 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
/*
* Unlink a window, unless it would be destroyed by doing so (only one link).
*/
enum cmd_retval cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
"kt:", 0, 0,
"[-k] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
NULL,
cmd_unlink_window_exec
};
enum cmd_retval
cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct session *s, *s2;
struct session_group *sg;
u_int references;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
sg = session_group_find(s);
if (sg != NULL) {
references = 0;
TAILQ_FOREACH(s2, &sg->sessions, gentry)
references++;
} else
references = 1;
if (!args_has(self->args, 'k') && w->references == references) {
ctx->error(ctx, "window is only linked to one session");
return (CMD_RETURN_ERROR);
}
server_unlink_window(s, wl);
recalculate_sizes();
return (CMD_RETURN_NORMAL);
}

264
cmd-wait-for.c Normal file
View File

@@ -0,0 +1,264 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
* Copyright (c) 2013 Thiago de Arruda <tpadilha84@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Block or wake a client on a named wait channel.
*/
static enum cmd_retval cmd_wait_for_exec(struct cmd *, struct cmdq_item *);
const struct cmd_entry cmd_wait_for_entry = {
.name = "wait-for",
.alias = "wait",
.args = { "LSU", 1, 1 },
.usage = "[-L|-S|-U] channel",
.flags = 0,
.exec = cmd_wait_for_exec
};
struct wait_item {
struct cmdq_item *item;
TAILQ_ENTRY(wait_item) entry;
};
struct wait_channel {
const char *name;
int locked;
int woken;
TAILQ_HEAD(, wait_item) waiters;
TAILQ_HEAD(, wait_item) lockers;
RB_ENTRY(wait_channel) entry;
};
RB_HEAD(wait_channels, wait_channel);
static struct wait_channels wait_channels = RB_INITIALIZER(wait_channels);
static int wait_channel_cmp(struct wait_channel *, struct wait_channel *);
RB_GENERATE_STATIC(wait_channels, wait_channel, entry, wait_channel_cmp);
static int
wait_channel_cmp(struct wait_channel *wc1, struct wait_channel *wc2)
{
return (strcmp(wc1->name, wc2->name));
}
static enum cmd_retval cmd_wait_for_signal(struct cmdq_item *, const char *,
struct wait_channel *);
static enum cmd_retval cmd_wait_for_wait(struct cmdq_item *, const char *,
struct wait_channel *);
static enum cmd_retval cmd_wait_for_lock(struct cmdq_item *, const char *,
struct wait_channel *);
static enum cmd_retval cmd_wait_for_unlock(struct cmdq_item *, const char *,
struct wait_channel *);
static struct wait_channel *cmd_wait_for_add(const char *);
static void cmd_wait_for_remove(struct wait_channel *);
static struct wait_channel *
cmd_wait_for_add(const char *name)
{
struct wait_channel *wc;
wc = xmalloc(sizeof *wc);
wc->name = xstrdup(name);
wc->locked = 0;
wc->woken = 0;
TAILQ_INIT(&wc->waiters);
TAILQ_INIT(&wc->lockers);
RB_INSERT(wait_channels, &wait_channels, wc);
log_debug("add wait channel %s", wc->name);
return (wc);
}
static void
cmd_wait_for_remove(struct wait_channel *wc)
{
if (wc->locked)
return;
if (!TAILQ_EMPTY(&wc->waiters) || !wc->woken)
return;
log_debug("remove wait channel %s", wc->name);
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void *)wc->name);
free(wc);
}
static enum cmd_retval
cmd_wait_for_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
const char *name = args->argv[0];
struct wait_channel *wc, wc0;
wc0.name = name;
wc = RB_FIND(wait_channels, &wait_channels, &wc0);
if (args_has(args, 'S'))
return (cmd_wait_for_signal(item, name, wc));
if (args_has(args, 'L'))
return (cmd_wait_for_lock(item, name, wc));
if (args_has(args, 'U'))
return (cmd_wait_for_unlock(item, name, wc));
return (cmd_wait_for_wait(item, name, wc));
}
static enum cmd_retval
cmd_wait_for_signal(__unused struct cmdq_item *item, const char *name,
struct wait_channel *wc)
{
struct wait_item *wi, *wi1;
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (TAILQ_EMPTY(&wc->waiters) && !wc->woken) {
log_debug("signal wait channel %s, no waiters", wc->name);
wc->woken = 1;
return (CMD_RETURN_NORMAL);
}
log_debug("signal wait channel %s, with waiters", wc->name);
TAILQ_FOREACH_SAFE(wi, &wc->waiters, entry, wi1) {
wi->item->flags &= ~CMDQ_WAITING;
TAILQ_REMOVE(&wc->waiters, wi, entry);
free(wi);
}
cmd_wait_for_remove(wc);
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_wait_for_wait(struct cmdq_item *item, const char *name,
struct wait_channel *wc)
{
struct client *c = item->client;
struct wait_item *wi;
if (c == NULL || c->session != NULL) {
cmdq_error(item, "not able to wait");
return (CMD_RETURN_ERROR);
}
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (wc->woken) {
log_debug("wait channel %s already woken (%p)", wc->name, c);
cmd_wait_for_remove(wc);
return (CMD_RETURN_NORMAL);
}
log_debug("wait channel %s not woken (%p)", wc->name, c);
wi = xcalloc(1, sizeof *wi);
wi->item = item;
TAILQ_INSERT_TAIL(&wc->waiters, wi, entry);
return (CMD_RETURN_WAIT);
}
static enum cmd_retval
cmd_wait_for_lock(struct cmdq_item *item, const char *name,
struct wait_channel *wc)
{
struct wait_item *wi;
if (item->client == NULL || item->client->session != NULL) {
cmdq_error(item, "not able to lock");
return (CMD_RETURN_ERROR);
}
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (wc->locked) {
wi = xcalloc(1, sizeof *wi);
wi->item = item;
TAILQ_INSERT_TAIL(&wc->lockers, wi, entry);
return (CMD_RETURN_WAIT);
}
wc->locked = 1;
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_wait_for_unlock(struct cmdq_item *item, const char *name,
struct wait_channel *wc)
{
struct wait_item *wi;
if (wc == NULL || !wc->locked) {
cmdq_error(item, "channel %s not locked", name);
return (CMD_RETURN_ERROR);
}
if ((wi = TAILQ_FIRST(&wc->lockers)) != NULL) {
wi->item->flags &= ~CMDQ_WAITING;
TAILQ_REMOVE(&wc->lockers, wi, entry);
free(wi);
} else {
wc->locked = 0;
cmd_wait_for_remove(wc);
}
return (CMD_RETURN_NORMAL);
}
void
cmd_wait_for_flush(void)
{
struct wait_channel *wc, *wc1;
struct wait_item *wi, *wi1;
RB_FOREACH_SAFE(wc, wait_channels, &wait_channels, wc1) {
TAILQ_FOREACH_SAFE(wi, &wc->waiters, entry, wi1) {
wi->item->flags &= ~CMDQ_WAITING;
TAILQ_REMOVE(&wc->waiters, wi, entry);
free(wi);
}
wc->woken = 1;
TAILQ_FOREACH_SAFE(wi, &wc->lockers, entry, wi1) {
wi->item->flags &= ~CMDQ_WAITING;
TAILQ_REMOVE(&wc->lockers, wi, entry);
free(wi);
}
wc->locked = 0;
cmd_wait_for_remove(wc);
}
}

1493
cmd.c

File diff suppressed because it is too large Load Diff

263
colour.c
View File

@@ -1,7 +1,8 @@
/* $Id$ */ /* $OpenBSD$ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* Copyright (c) 2016 Avi Halachmi <avihpit@yahoo.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -24,120 +25,83 @@
#include "tmux.h" #include "tmux.h"
static int
colour_dist_sq(int R, int G, int B, int r, int g, int b)
{
return ((R - r) * (R - r) + (G - g) * (G - g) + (B - b) * (B - b));
}
static int
colour_to_6cube(int v)
{
if (v < 48)
return (0);
if (v < 114)
return (1);
return ((v - 35) / 40);
}
/* /*
* Colour to string conversion functions. Bit 8 of the colour means it is one * Convert an RGB triplet to the xterm(1) 256 colour palette.
* of the 256 colour palette. *
* xterm provides a 6x6x6 colour cube (16 - 231) and 24 greys (232 - 255). We
* map our RGB colour to the closest in the cube, also work out the closest
* grey, and use the nearest of the two.
*
* Note that the xterm has much lower resolution for darker colours (they are
* not evenly spread out), so our 6 levels are not evenly spread: 0x0, 0x5f
* (95), 0x87 (135), 0xaf (175), 0xd7 (215) and 0xff (255). Greys are more
* evenly spread (8, 18, 28 ... 238).
*/ */
/* An RGB colour. */
struct colour_rgb {
u_char r;
u_char g;
u_char b;
};
/* 256 colour RGB table, generated on first use. */
struct colour_rgb *colour_rgb_256;
void colour_rgb_generate256(void);
u_int colour_rgb_distance(struct colour_rgb *, struct colour_rgb *);
int colour_rgb_find(struct colour_rgb *);
/* Generate 256 colour RGB table. */
void
colour_rgb_generate256(void)
{
struct colour_rgb *rgb;
u_int i, r, g, b;
/*
* Allocate the table. The first 16 colours are often changed by users
* and terminals so don't include them.
*/
colour_rgb_256 = xcalloc(240, sizeof *colour_rgb_256);
/* Add the colours first. */
r = g = b = 0;
for (i = 240; i > 24; i--) {
rgb = &colour_rgb_256[240 - i];
if (r != 0)
rgb->r = (r * 40) + 55;
if (g != 0)
rgb->g = (g * 40) + 55;
if (b != 0)
rgb->b = (b * 40) + 55;
b++;
if (b > 5) {
b = 0;
g++;
}
if (g > 5) {
g = 0;
r++;
}
}
/* Then add the greys. */
for (i = 24; i > 0; i--) {
rgb = &colour_rgb_256[240 - i];
rgb->r = 8 + (24 - i) * 10;
rgb->g = 8 + (24 - i) * 10;
rgb->b = 8 + (24 - i) * 10;
}
}
/* Get colour RGB distance. */
u_int
colour_rgb_distance(struct colour_rgb *rgb1, struct colour_rgb *rgb2)
{
int r, g, b;
r = rgb1->r - rgb2->r;
g = rgb1->g - rgb2->g;
b = rgb1->b - rgb2->b;
return (r * r + g * g + b * b);
}
/* Work out the nearest colour from the 256 colour set. */
int int
colour_rgb_find(struct colour_rgb *rgb) colour_find_rgb(u_char r, u_char g, u_char b)
{ {
u_int distance, lowest, colour, i; static const int q2c[6] = { 0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff };
int qr, qg, qb, cr, cg, cb, d, idx;
int grey_avg, grey_idx, grey;
if (colour_rgb_256 == NULL) /* Map RGB to 6x6x6 cube. */
colour_rgb_generate256(); qr = colour_to_6cube(r); cr = q2c[qr];
qg = colour_to_6cube(g); cg = q2c[qg];
qb = colour_to_6cube(b); cb = q2c[qb];
colour = 16; /* If we have hit the colour exactly, return early. */
lowest = UINT_MAX; if (cr == r && cg == g && cb == b)
for (i = 0; i < 240; i++) { return ((16 + (36 * qr) + (6 * qg) + qb) | COLOUR_FLAG_256);
distance = colour_rgb_distance(&colour_rgb_256[i], rgb);
if (distance < lowest) { /* Work out the closest grey (average of RGB). */
lowest = distance; grey_avg = (r + g + b) / 3;
colour = 16 + i; if (grey_avg > 238)
} grey_idx = 23;
} else
return (colour); grey_idx = (grey_avg - 3) / 10;
grey = 8 + (10 * grey_idx);
/* Is grey or 6x6x6 colour closest? */
d = colour_dist_sq(cr, cg, cb, r, g, b);
if (colour_dist_sq(grey, grey, grey, r, g, b) < d)
idx = 232 + grey_idx;
else
idx = 16 + (36 * qr) + (6 * qg) + qb;
return (idx | COLOUR_FLAG_256);
} }
/* Set grid cell foreground colour. */ /* Join RGB into a colour. */
void int
colour_set_fg(struct grid_cell *gc, int c) colour_join_rgb(u_char r, u_char g, u_char b)
{ {
if (c & 0x100) return ((((int)((r) & 0xff)) << 16) |
gc->flags |= GRID_FLAG_FG256; (((int)((g) & 0xff)) << 8) |
gc->fg = c; (((int)((b) & 0xff))) | COLOUR_FLAG_RGB);
} }
/* Set grid cell background colour. */ /* Split colour into RGB. */
void void
colour_set_bg(struct grid_cell *gc, int c) colour_split_rgb(int c, u_char *r, u_char *g, u_char *b)
{ {
if (c & 0x100) *r = (c >> 16) & 0xff;
gc->flags |= GRID_FLAG_BG256; *g = (c >> 8) & 0xff;
gc->bg = c; *b = c & 0xff;
} }
/* Convert colour to a string. */ /* Convert colour to a string. */
@@ -145,9 +109,16 @@ const char *
colour_tostring(int c) colour_tostring(int c)
{ {
static char s[32]; static char s[32];
u_char r, g, b;
if (c & 0x100) { if (c & COLOUR_FLAG_RGB) {
xsnprintf(s, sizeof s, "colour%u", c & ~0x100); colour_split_rgb(c, &r, &g, &b);
xsnprintf(s, sizeof s, "#%02x%02x%02x", r, g, b);
return (s);
}
if (c & COLOUR_FLAG_256) {
xsnprintf(s, sizeof s, "colour%u", c & 0xff);
return (s); return (s);
} }
@@ -194,70 +165,62 @@ colour_tostring(int c)
int int
colour_fromstring(const char *s) colour_fromstring(const char *s)
{ {
const char *errstr; const char *errstr;
const char *cp; const char *cp;
struct colour_rgb rgb; int n;
int n; u_char r, g, b;
if (*s == '#' && strlen(s) == 7) { if (*s == '#' && strlen(s) == 7) {
for (cp = s + 1; isxdigit((u_char) *cp); cp++) for (cp = s + 1; isxdigit((u_char) *cp); cp++)
; ;
if (*cp != '\0') if (*cp != '\0')
return (-1); return (-1);
n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b); n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
if (n != 3) if (n != 3)
return (-1); return (-1);
return (colour_rgb_find(&rgb) | 0x100); return (colour_join_rgb(r, g, b));
} }
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) { if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr); n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
if (errstr != NULL) if (errstr != NULL)
return (-1); return (-1);
return (n | 0x100); return (n | COLOUR_FLAG_256);
} }
if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0')) if (strcasecmp(s, "black") == 0 || strcmp(s, "0") == 0)
return (0); return (0);
if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0')) if (strcasecmp(s, "red") == 0 || strcmp(s, "1") == 0)
return (1); return (1);
if (strcasecmp(s, "green") == 0 || (s[0] == '2' && s[1] == '\0')) if (strcasecmp(s, "green") == 0 || strcmp(s, "2") == 0)
return (2); return (2);
if (strcasecmp(s, "yellow") == 0 || (s[0] == '3' && s[1] == '\0')) if (strcasecmp(s, "yellow") == 0 || strcmp(s, "3") == 0)
return (3); return (3);
if (strcasecmp(s, "blue") == 0 || (s[0] == '4' && s[1] == '\0')) if (strcasecmp(s, "blue") == 0 || strcmp(s, "4") == 0)
return (4); return (4);
if (strcasecmp(s, "magenta") == 0 || (s[0] == '5' && s[1] == '\0')) if (strcasecmp(s, "magenta") == 0 || strcmp(s, "5") == 0)
return (5); return (5);
if (strcasecmp(s, "cyan") == 0 || (s[0] == '6' && s[1] == '\0')) if (strcasecmp(s, "cyan") == 0 || strcmp(s, "6") == 0)
return (6); return (6);
if (strcasecmp(s, "white") == 0 || (s[0] == '7' && s[1] == '\0')) if (strcasecmp(s, "white") == 0 || strcmp(s, "7") == 0)
return (7); return (7);
if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0')) if (strcasecmp(s, "default") == 0 || strcmp(s, "8") == 0)
return (8); return (8);
if (strcasecmp(s, "brightblack") == 0 || if (strcasecmp(s, "brightblack") == 0 || strcmp(s, "90") == 0)
(s[0] == '9' && s[1] == '0' && s[1] == '\0'))
return (90); return (90);
if (strcasecmp(s, "brightred") == 0 || if (strcasecmp(s, "brightred") == 0 || strcmp(s, "91") == 0)
(s[0] == '9' && s[1] == '1' && s[1] == '\0'))
return (91); return (91);
if (strcasecmp(s, "brightgreen") == 0 || if (strcasecmp(s, "brightgreen") == 0 || strcmp(s, "92") == 0)
(s[0] == '9' && s[1] == '2' && s[1] == '\0'))
return (92); return (92);
if (strcasecmp(s, "brightyellow") == 0 || if (strcasecmp(s, "brightyellow") == 0 || strcmp(s, "93") == 0)
(s[0] == '9' && s[1] == '3' && s[1] == '\0'))
return (93); return (93);
if (strcasecmp(s, "brightblue") == 0 || if (strcasecmp(s, "brightblue") == 0 || strcmp(s, "94") == 0)
(s[0] == '9' && s[1] == '4' && s[1] == '\0'))
return (94); return (94);
if (strcasecmp(s, "brightmagenta") == 0 || if (strcasecmp(s, "brightmagenta") == 0 || strcmp(s, "95") == 0)
(s[0] == '9' && s[1] == '5' && s[1] == '\0'))
return (95); return (95);
if (strcasecmp(s, "brightcyan") == 0 || if (strcasecmp(s, "brightcyan") == 0 || strcmp(s, "96") == 0)
(s[0] == '9' && s[1] == '6' && s[1] == '\0'))
return (96); return (96);
if (strcasecmp(s, "brightwhite") == 0 || if (strcasecmp(s, "brightwhite") == 0 || strcmp(s, "97") == 0)
(s[0] == '9' && s[1] == '7' && s[1] == '\0'))
return (97); return (97);
return (-1); return (-1);
} }
@@ -287,29 +250,3 @@ colour_256to16(u_char c)
return (table[c]); return (table[c]);
} }
/* Convert 256 colour palette to 88. */
u_char
colour_256to88(u_char c)
{
static const u_char table[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 17, 18, 18, 19, 20, 21, 21, 22, 22, 23, 20, 21, 21, 22,
22, 23, 24, 25, 25, 26, 26, 27, 24, 25, 25, 26, 26, 27, 28, 29,
29, 30, 30, 31, 32, 33, 33, 34, 34, 35, 36, 37, 37, 38, 38, 39,
36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43, 40, 41, 41, 42,
42, 43, 44, 45, 45, 46, 46, 47, 32, 33, 33, 34, 34, 35, 36, 37,
37, 38, 38, 39, 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43,
40, 41, 41, 42, 42, 43, 44, 45, 45, 46, 46, 47, 48, 49, 49, 50,
50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54, 54, 55, 56, 57,
57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61, 61, 62, 62, 63,
48, 49, 49, 50, 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54,
54, 55, 56, 57, 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61,
61, 62, 62, 63, 64, 65, 65, 66, 66, 67, 68, 69, 69, 70, 70, 71,
68, 69, 69, 70, 70, 71, 72, 73, 73, 74, 74, 75, 72, 73, 73, 74,
74, 75, 76, 77, 77, 78, 78, 79, 0, 0, 80, 80, 80, 81, 81, 81,
82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87
};
return (table[c]);
}

151
compat.h
View File

@@ -1,7 +1,5 @@
/* $Id$ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -19,10 +17,21 @@
#ifndef COMPAT_H #ifndef COMPAT_H
#define COMPAT_H #define COMPAT_H
#include <sys/types.h>
#include <sys/uio.h>
#include <limits.h>
#include <stdio.h>
#include <termios.h>
#include <wchar.h>
#ifndef __GNUC__ #ifndef __GNUC__
#define __attribute__(a) #define __attribute__(a)
#endif #endif
#ifndef __unused
#define __unused __attribute__ ((__unused__))
#endif
#ifndef __dead #ifndef __dead
#define __dead __attribute__ ((__noreturn__)) #define __dead __attribute__ ((__noreturn__))
#endif #endif
@@ -30,11 +39,25 @@
#define __packed __attribute__ ((__packed__)) #define __packed __attribute__ ((__packed__))
#endif #endif
#ifndef HAVE_BSD_TYPES #ifndef ECHOPRT
typedef uint8_t u_int8_t; #define ECHOPRT 0
typedef uint16_t u_int16_t; #endif
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t; #ifndef ACCESSPERMS
#define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO)
#endif
#if !defined(FIONREAD) && defined(__sun)
#include <sys/filio.h>
#endif
#ifdef HAVE_ERR_H
#include <err.h>
#else
void err(int, const char *, ...);
void errx(int, const char *, ...);
void warn(const char *, ...);
void warnx(const char *, ...);
#endif #endif
#ifndef HAVE_PATHS_H #ifndef HAVE_PATHS_H
@@ -45,6 +68,16 @@ typedef uint64_t u_int64_t;
#define _PATH_DEV "/dev/" #define _PATH_DEV "/dev/"
#endif #endif
#ifndef __OpenBSD__
#define pledge(s, p) (0)
#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#include <inttypes.h>
#endif
#ifdef HAVE_QUEUE_H #ifdef HAVE_QUEUE_H
#include <sys/queue.h> #include <sys/queue.h>
#else #else
@@ -91,12 +124,6 @@ typedef uint64_t u_int64_t;
#include "compat/imsg.h" #include "compat/imsg.h"
#endif #endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#include <inttypes.h>
#endif
#ifdef BROKEN_CMSG_FIRSTHDR #ifdef BROKEN_CMSG_FIRSTHDR
#undef CMSG_FIRSTHDR #undef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(mhdr) \ #define CMSG_FIRSTHDR(mhdr) \
@@ -121,6 +148,10 @@ typedef uint64_t u_int64_t;
#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) #define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
#endif #endif
#ifndef O_DIRECTORY
#define O_DIRECTORY 0
#endif
#ifndef INFTIM #ifndef INFTIM
#define INFTIM -1 #define INFTIM -1
#endif #endif
@@ -152,18 +183,46 @@ typedef uint64_t u_int64_t;
} while (0) } while (0)
#endif #endif
#ifndef timersub
#define timersub(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((vvp)->tv_usec < 0) { \
(vvp)->tv_sec--; \
(vvp)->tv_usec += 1000000; \
} \
} while (0)
#endif
#ifndef TTY_NAME_MAX #ifndef TTY_NAME_MAX
#define TTY_NAME_MAX 32 #define TTY_NAME_MAX 32
#endif #endif
#ifndef HAVE_BZERO #ifndef HOST_NAME_MAX
#undef bzero #define HOST_NAME_MAX 255
#define bzero(buf, len) memset(buf, 0, len); #endif
#ifndef HAVE_FLOCK
#define LOCK_SH 0
#define LOCK_EX 0
#define LOCK_NB 0
#define flock(fd, op) (0)
#endif
#ifndef HAVE_EXPLICIT_BZERO
/* explicit_bzero.c */
void explicit_bzero(void *, size_t);
#endif
#ifndef HAVE_GETDTABLECOUNT
/* getdtablecount.c */
int getdtablecount(void);
#endif #endif
#ifndef HAVE_CLOSEFROM #ifndef HAVE_CLOSEFROM
/* closefrom.c */ /* closefrom.c */
void closefrom(int); void closefrom(int);
#endif #endif
#ifndef HAVE_STRCASESTR #ifndef HAVE_STRCASESTR
@@ -191,14 +250,37 @@ size_t strlcpy(char *, const char *, size_t);
size_t strlcat(char *, const char *, size_t); size_t strlcat(char *, const char *, size_t);
#endif #endif
#ifndef HAVE_STRNLEN
/* strnlen.c */
size_t strnlen(const char *, size_t);
#endif
#ifndef HAVE_STRNDUP
/* strndup.c */
char *strndup(const char *, size_t);
#endif
#ifndef HAVE_DAEMON #ifndef HAVE_DAEMON
/* daemon.c */ /* daemon.c */
int daemon(int, int); int daemon(int, int);
#endif #endif
#ifndef HAVE_GETPROGNAME
/* getprogname.c */
const char *getprogname(void);
#endif
#ifndef HAVE_SETPROCTITLE
/* setproctitle.c */
void setproctitle(const char *, ...);
#endif
#ifndef HAVE_B64_NTOP #ifndef HAVE_B64_NTOP
/* b64_ntop.c */ /* base64.c */
#undef b64_ntop
#undef b64_pton
int b64_ntop(const char *, size_t, char *, size_t); int b64_ntop(const char *, size_t, char *, size_t);
int b64_pton(const char *, u_char *, size_t);
#endif #endif
#ifndef HAVE_FORKPTY #ifndef HAVE_FORKPTY
@@ -218,12 +300,43 @@ int vasprintf(char **, const char *, va_list);
char *fgetln(FILE *, size_t *); char *fgetln(FILE *, size_t *);
#endif #endif
#ifndef HAVE_FPARSELN
char *fparseln(FILE *, size_t *, size_t *, const char *, int);
#endif
#ifndef HAVE_SETENV #ifndef HAVE_SETENV
/* setenv.c */ /* setenv.c */
int setenv(const char *, const char *, int); int setenv(const char *, const char *, int);
int unsetenv(const char *); int unsetenv(const char *);
#endif #endif
#ifndef HAVE_CFMAKERAW
/* cfmakeraw.c */
void cfmakeraw(struct termios *);
#endif
#ifndef HAVE_FREEZERO
/* freezero.c */
void freezero(void *, size_t);
#endif
#ifndef HAVE_REALLOCARRAY
/* reallocarray.c */
void *reallocarray(void *, size_t, size_t);
#endif
#ifndef HAVE_RECALLOCARRAY
/* recallocarray.c */
void *recallocarray(void *, size_t, size_t, size_t);
#endif
#ifdef HAVE_UTF8PROC
/* utf8proc.c */
int utf8proc_wcwidth(wchar_t);
int utf8proc_mbtowc(wchar_t *, const char *, size_t);
int utf8proc_wctomb(char *, wchar_t);
#endif
#ifdef HAVE_GETOPT #ifdef HAVE_GETOPT
#include <getopt.h> #include <getopt.h>
#else #else

View File

@@ -1,7 +1,5 @@
/* $Id$ */
/* /*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2006 Nicholas Marriott <nicholas.marriott@gmail.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -16,16 +14,13 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <sys/types.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#include <inttypes.h>
#endif
#include <string.h> #include <string.h>
#include "tmux.h" #include "compat.h"
int int
asprintf(char **ret, const char *fmt, ...) asprintf(char **ret, const char *fmt, ...)
@@ -56,10 +51,12 @@ vasprintf(char **ret, const char *fmt, va_list ap)
free(*ret); free(*ret);
goto error; goto error;
} }
va_end(ap2);
return (n); return (n);
error: error:
va_end(ap2);
*ret = NULL; *ret = NULL;
return (-1); return (-1);
} }

View File

@@ -1,5 +1,7 @@
/* $OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $ */
/* /*
* Copyright (c) 1996, 1998 by Internet Software Consortium. * Copyright (c) 1996 by Internet Software Consortium.
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -41,19 +43,18 @@
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h> #include <ctype.h>
#include <resolv.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define Assert(Cond) if (!(Cond)) abort()
static const char Base64[] = static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '='; static const char Pad64 = '=';
@@ -122,11 +123,16 @@ static const char Pad64 = '=';
*/ */
int int
b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) { b64_ntop(src, srclength, target, targsize)
u_char const *src;
size_t srclength;
char *target;
size_t targsize;
{
size_t datalength = 0; size_t datalength = 0;
uint8_t input[3]; u_char input[3];
uint8_t output[4]; u_char output[4];
size_t i; int i;
while (2 < srclength) { while (2 < srclength) {
input[0] = *src++; input[0] = *src++;
@@ -138,10 +144,6 @@ b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f; output[3] = input[2] & 0x3f;
Assert(output[0] < 64);
Assert(output[1] < 64);
Assert(output[2] < 64);
Assert(output[3] < 64);
if (datalength + 4 > targsize) if (datalength + 4 > targsize)
return (-1); return (-1);
@@ -161,9 +163,6 @@ b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
output[0] = input[0] >> 2; output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
Assert(output[0] < 64);
Assert(output[1] < 64);
Assert(output[2] < 64);
if (datalength + 4 > targsize) if (datalength + 4 > targsize)
return (-1); return (-1);
@@ -180,3 +179,137 @@ b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
target[datalength] = '\0'; /* Returned value doesn't count \0. */ target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (datalength); return (datalength);
} }
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
int
b64_pton(src, target, targsize)
char const *src;
u_char *target;
size_t targsize;
{
int tarindex, state, ch;
u_char nextbyte;
char *pos;
state = 0;
tarindex = 0;
while ((ch = (unsigned char)*src++) != '\0') {
if (isspace(ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad64)
break;
pos = strchr(Base64, ch);
if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state) {
case 0:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] = (pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
nextbyte = ((pos - Base64) & 0x0f) << 4;
if (tarindex + 1 < targsize)
target[tarindex+1] = nextbyte;
else if (nextbyte)
return (-1);
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
nextbyte = ((pos - Base64) & 0x03) << 6;
if (tarindex + 1 < targsize)
target[tarindex+1] = nextbyte;
else if (nextbyte)
return (-1);
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = (unsigned char)*src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for (; ch != '\0'; ch = (unsigned char)*src++)
if (!isspace(ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = (unsigned char)*src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for (; ch != '\0'; ch = (unsigned char)*src++)
if (!isspace(ch))
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target && tarindex < targsize &&
target[tarindex] != 0)
return (-1);
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}

View File

@@ -1,4 +1,3 @@
/* $Id$ */
/* $OpenBSD: bitstring.h,v 1.5 2003/06/02 19:34:12 millert Exp $ */ /* $OpenBSD: bitstring.h,v 1.5 2003/06/02 19:34:12 millert Exp $ */
/* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */ /* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */

Some files were not shown because too many files have changed in this diff Show More