643 Commits
1.9a ... 2.1

Author SHA1 Message Date
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
203 changed files with 14054 additions and 8479 deletions

View File

@@ -1,24 +1,34 @@
Bob Beck <beck@openbsd.org> beck <beck>
Igor Sobrado <sobrado@openbsd.org> sobrado <sobrado>
Jacek Masiulaniec <jacekm@openbsd.org> jacekm <jacekm>
Jason McIntyre <jmc@openbsd.org> jcm <jcm>
Bob Beck <beck@openbsd.org> beck <beck>
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>
Jason McIntyre <jmc@openbsd.org> jcm <jcm>
Joel Sing <jsing@openbsd.org> jsing <jsing>
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>
Miod Vallat <miod@openbsd.org> miod <miod>
Nicholas Marriott <nicm@openbsd.org> nicm <nicm>
Nicholas Marriott <nicm@openbsd.org> no_author <no_author@example.org>
<nicm@openbsd.org> <nicholas.marriott@gmail.com>
Okan Demirmen <okan@openbsd.org> okan <okan>
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>
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>
Pierre-Yves Ritschard <pyr@openbsd.org> pyr <pyr>
Ray Lai <ray@openbsd.org> ray <ray>
Ryan McBride <mcbride@openbsd.org> mcbride <mcbride>
Stefan Sperling <stsp@openbsd.org> stsp <stsp>
Stuart Henderson <sthen@openbsd.org> sthen <sthen>
Ted Unangst <tedu@openbsd.org> tedu <tedu>
Theo Deraadt <deraadt@openbsd.org> deraadt <deraadt>
Sebastian Benoit <benno@openbsd.org> benno <benno>
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> deraadt <deraadt>
Theo de Raadt <deraadt@openbsd.org> Theo Deraadt <deraadt@openbsd.org>
Thomas Adam <thomas@xteddy.org> Thomas <thomas@xteddy.org>
William Yodlowsky <william@openbsd.org> william <william>
Thomas Adam <thomas@xteddy.org> n6tadam <n6tadam@xteddy.org>
Thomas Adam <thomas@xteddy.org> Thomas Adam <thomas.adam@smoothwall.net>
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

117
CHANGES
View File

@@ -1,3 +1,113 @@
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
@@ -1865,10 +1975,3 @@ The list of older changes is below.
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
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

68
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
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.
- 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?
Please send bug reports by email to nicm@users.sourceforge.net or
tmux-users@lists.sourceforge.net. Please include as much of the following
Check the latest version of tmux from Git to see if the problem is still
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:
- the version of tmux you are running;
@@ -122,7 +123,7 @@ information as possible:
* 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.
@@ -351,42 +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'
* vim displays reverse video instead of italics, while less displays italics
(or just regular text) instead of reverse. What's wrong?
* I don't see italics! Or less and vim show italics and reverse the wrong way round!
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:
GNU screen does not support italics and the "screen" terminfo description uses
the italics escape sequence incorrectly.
$ 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
As of tmux 2.1, if default-terminal is set to "screen" or matches "screen-*",
tmux will behave like screen and italics will be disabled.
To enable italics, create a new terminfo entry called "tmux" (some platforms
may already have this, you can check with "infocmp tmux"):
$ cat <<EOF|tic -x -
tmux|tmux terminal multiplexer,
ritm=\E[23m, rmso=\E[27m, sitm=\E[3m, smso=\E[7m, Ms@,
use=xterm+tmux, use=screen,
tmux-256color|tmux with 256 colors,
use=xterm+256setaf, use=tmux,
EOF
$
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:
$ 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:
If using urxvt, make sure you have an italics capable font enabled. for
example, add to ~/.Xdefaults:
urxvt.italicFont: xft:Bitstream Vera Sans Mono:italic:autohint=true
@@ -402,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
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.
@@ -460,5 +452,3 @@ Or from inside tmux by detaching individual clients with C-b D or all
using:
C-b : attach -d
$Id$

View File

@@ -1,4 +1,4 @@
# $Id$
# Makefile.am
# Obvious program stuff.
bin_PROGRAMS = tmux
@@ -6,12 +6,11 @@ CLEANFILES = tmux.1.mdoc tmux.1.man
# Distribution tarball options.
EXTRA_DIST = \
CHANGES FAQ README TODO COPYING examples compat \
CHANGES FAQ README TODO COPYING examples compat/*.[ch] \
array.h compat.h tmux.h osdep-*.c mdoc2man.awk tmux.1
dist-hook:
make clean
grep "^#found_debug=" configure
find $(distdir) -name .svn -type d|xargs rm -Rf
# Preprocessor flags.
CPPFLAGS += @XOPEN_DEFINES@ -DTMUX_CONF="\"$(sysconfdir)/tmux.conf\""
@@ -22,29 +21,23 @@ if IS_GLIBC
CFLAGS += -D_GNU_SOURCE
endif
# Set flags for gcc. gcc4 whines abouts silly stuff so it needs slightly
# different flags.
# Set flags for gcc.
if IS_GCC
CFLAGS += -std=gnu99
CFLAGS += -std=gnu99 -O2
if IS_DEBUG
CFLAGS += -O0 -g
CFLAGS += -g
CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align
CFLAGS += -Wdeclaration-after-statement
CFLAGS += -Wdeclaration-after-statement -Wno-pointer-sign
CPPFLAGS += -DDEBUG
else
CFLAGS += -O2
endif
if IS_GCC4
CPPFLAGS += -iquote. -I/usr/local/include
if IS_DEBUG
CFLAGS += -Wno-pointer-sign
endif
else
CPPFLAGS += -I. -I- -I/usr/local/include
if IS_COVERAGE
CFLAGS += -g -O0 --coverage
LDFLAGS += --coverage
endif
CPPFLAGS += -iquote.
endif
# Set flags for Solaris.
@@ -61,42 +54,42 @@ if IS_SUNCC
CFLAGS += -erroff=E_EMPTY_DECLARATION
endif
# Set _LINUX_SOURCE_COMPAT for AIX for mallocing 0 bytes
if IS_AIX
DEFS += -D_LINUX_SOURCE_COMPAT=1
endif
# List of sources.
dist_tmux_SOURCES = \
alerts.c \
arguments.c \
attributes.c \
cfg.c \
client.c \
clock.c \
cmd-attach-session.c \
cmd-bind-key.c \
cmd-break-pane.c \
cmd-capture-pane.c \
cmd-choose-buffer.c \
cmd-choose-client.c \
cmd-choose-list.c \
cmd-choose-tree.c \
cmd-clear-history.c \
cmd-clock-mode.c \
cmd-command-prompt.c \
cmd-confirm-before.c \
cmd-copy-mode.c \
cmd-delete-buffer.c \
cmd-detach-client.c \
cmd-display-message.c \
cmd-display-panes.c \
cmd-find.c \
cmd-find-window.c \
cmd-has-session.c \
cmd-if-shell.c \
cmd-join-pane.c \
cmd-kill-pane.c \
cmd-kill-server.c \
cmd-kill-session.c \
cmd-kill-window.c \
cmd-link-window.c \
cmd-list-buffers.c \
cmd-list-clients.c \
cmd-list-commands.c \
cmd-list-keys.c \
cmd-list-panes.c \
cmd-list-sessions.c \
@@ -132,12 +125,10 @@ dist_tmux_SOURCES = \
cmd-source-file.c \
cmd-split-window.c \
cmd-string.c \
cmd-suspend-client.c \
cmd-swap-pane.c \
cmd-swap-window.c \
cmd-switch-client.c \
cmd-unbind-key.c \
cmd-unlink-window.c \
cmd-wait-for.c \
cmd.c \
colour.c \
@@ -169,7 +160,6 @@ dist_tmux_SOURCES = \
screen.c \
server-client.c \
server-fn.c \
server-window.c \
server.c \
session.c \
signal.c \
@@ -217,6 +207,9 @@ endif
if NO_FGETLN
nodist_tmux_SOURCES += compat/fgetln.c
endif
if NO_FPARSELN
nodist_tmux_SOURCES += compat/fparseln.c
endif
if NO_GETOPT
nodist_tmux_SOURCES += compat/getopt.c
endif
@@ -249,23 +242,8 @@ install-exec-hook:
>$(srcdir)/tmux.1.mdoc; \
else \
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1| \
$(AWK) -fmdoc2man.awk >$(srcdir)/tmux.1.man; \
$(AWK) -f$(srcdir)/mdoc2man.awk >$(srcdir)/tmux.1.man; \
fi
$(MKDIR_P) $(DESTDIR)$(mandir)/man1
$(mkdir_p) $(DESTDIR)$(mandir)/man1
$(INSTALL_DATA) $(srcdir)/tmux.1.@MANFORMAT@ \
$(DESTDIR)$(mandir)/man1/tmux.1
# Update SF web site.
upload-index.html: update-index.html
scp www/index.html www/main.css www/images/*.png \
${USER},tmux@web.sf.net:/home/groups/t/tm/tmux/htdocs
rm -f www/index.html www/images/small-*
update-index.html:
(cd www/images && \
rm -f small-* && \
for i in *.png; do \
convert "$$i" -resize 200x150 "small-$$i"; \
done \
)
sed "s/%%VERSION%%/${VERSION}/g" www/index.html.in >www/index.html

33
README
View File

@@ -4,8 +4,7 @@ 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).
This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris.
tmux depends on libevent 2.x. Download it from:
@@ -18,14 +17,13 @@ To build tmux from a release tarball, do:
To get and build the latest from version control:
$ git clone git://git.code.sf.net/p/tmux/tmux-code tmux
$ git clone https://github.com/tmux/tmux.git
$ 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. Patches should be sent by email to the mailing list at
tmux-users@lists.sourceforge.net.
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:
@@ -41,20 +39,23 @@ directory.
For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory.
tmux mailing lists are available. Visit:
tmux mailing lists are available. For general discussion and bug reports:
https://sourceforge.net/mail/?group_id=200378
https://groups.google.com/forum/#!forum/tmux-users
And for Git commit emails:
https://groups.google.com/forum/#!forum/tmux-git
Bug reports, feature suggestions and especially code contributions are most
welcome. Please send by email to:
tmux-users@lists.sourceforge.net
tmux-users@googlegroups.com
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.
This file and the CHANGES, FAQ, SYNCING 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$
-- Nicholas Marriott <nicholas.marriott@gmail.com>

82
SYNCING
View File

@@ -1,10 +1,10 @@
Preamble
========
Tmux on SourceForge has two git repositories [1] "tmux-code" and "tmux-openbsd".
Tmux portable relies on repositories "tmux" and "tmux-openbsd".
Here's a description of them:
* "tmux-code" is the portable version, the one which contains code for other
* "tmux" is the portable version, the one which contains code for other
operating systems, and autotools, etc., which isn't found or needed in the
OpenBSD base system.
@@ -17,9 +17,6 @@ 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
OpenBSD code).
It is assumed that the person doing the sync has read/write access to the
tmux-code repository on SourceForge already.
If you've never used git before, git tracks meta-data about the committer
and the author, as part of a commit, hence:
@@ -37,11 +34,11 @@ this information has ever been set before.
Cloning repositories
====================
This involves having both tmux-code and tmux-openbsd cloned, as in:
This involves having both tmux and tmux-openbsd cloned, as in:
% cd /some/where/useful
% git clone ssh://${USER}@git.code.sf.net/p/tmux/tmux
% git clone ssh://${USER}@git.code.sf.net/p/tmux/tmux-openbsd
% git clone https://github.com/tmux/tmux.git
% git clone https://github.com/ThomasAdam/tmux-openbsd.git
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
@@ -50,56 +47,56 @@ these checkouts existing, skip that.
Adding in git-remotes
=====================
Because the portable "tmux-code" git repository and the "tmux-openbsd"
Because the portable "tmux" git repository and the "tmux-openbsd"
repository do not inherently share any history between each other, the
history has been faked between them. This "faking of history" is something
which has to be told to git for the purposes of comparing the "tmux" and
"tmux-openbsd" repositories for syncing. To do this, we must reference the
clone of the "tmux-openbsd" repository from the "tmux-code" repository, as
clone of the "tmux-openbsd" repository from the "tmux" repository, as
shown by the following command:
% cd /path/to/tmux-code
% cd /path/to/tmux
% git remote add obsd-tmux file:///path/to/tmux-openbsd
So that now, the remote "obsd-tmux" can be used to reference branches and
commits from the "tmux-openbsd" repository, but from the context of the
portable "tmux-code" repository, which makes sense because it's the "tmux"
portable "tmux" repository, which makes sense because it's the "tmux"
repository which will have the updates applied to them.
Fetching updates
================
To ensure the latest commits from "tmux-openbsd" can be found from within
"tmux-code", we have to ensure the "master" branch from "tmux-openbsd" is
up-to-date first, and then reference that update in "tmux-code", as in:
"tmux", we have to ensure the "master" branch from "tmux-openbsd" is
up-to-date first, and then reference that update in "tmux", as in:
% cd /path/to/tmux-openbsd
% git checkout master
% git pull
Then back in "tmux-code":
Then back in "tmux":
% cd /path/to/tmux-code
% git fetch obsd-tmux-code
% cd /path/to/tmux
% git fetch obsd-tmux
Creating the necessary branches
===============================
Now that "tmux-code" can see commits and branches from "tmux-openbsd" by way
Now that "tmux" can see commits and branches from "tmux-openbsd" by way
of the remote name "obsd-tmux", we can now create the master branch from
"tmux-openbsd" in the "tmux-code" repository:
"tmux-openbsd" in the "tmux" repository:
% git checkout -b obsd-master obsd-tmux/master
Adding in the fake history points
=================================
To tie both the "master" branch from "tmux-code" and the "obsd-master"
To tie both the "master" branch from "tmux" and the "obsd-master"
branch from "tmux-openbsd" together, the fake history points added to the
"tmux-code" repository need to be added. To do this, we must add an
"tmux" repository need to be added. To do this, we must add an
additional refspec line, as in:
% cd /path/to/tmux-code
% cd /path/to/tmux
% git config --add remote.origin.fetch '+refs/replace/*:refs/replace/*'
% git fetch origin
@@ -110,7 +107,7 @@ Make sure the "master" branch is checked out:
% git checkout master
The following will show commits on OpenBSD not yet synched with "tmux-code":
The following will show commits on OpenBSD not yet synched with "tmux":
% git log master..obsd-master
@@ -131,6 +128,15 @@ And if happy:
% 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
=============================
@@ -145,30 +151,26 @@ Release tmux for next version
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:
% git push 1.X
% git push 2.X
4. Build the tarball with make dist. Now that it's using autoconf there
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.
4. Build the tarball with 'make dist'.
5. Split the release changes into a new file. This should be named
tmux-$VERSION-readme to make sourceforge show it automagically in specific
parts of the project page.
5. Check the tarball. If it's good, go here to select the tag just pushed:
6. Upload the tarball and the above file. Make the tarball the default
download by selecting all operating systems under the file details.
https://github.com/tmux/tmux/tags
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
a debug build by default.
7. Clone the tmux.github.io repository, and change the RELEASE version in
the Makefile. Commit it, and run 'make' to replace %%VERSION%%. Push
the result out.
9. Update freshmeat.
[1] https://sourceforge.net/p/tmux/_list/git
8. Bump version in tmu/tmux.git configure.ac and uncomment "found_debug=yes" to
create a debug build by default.

53
TODO
View File

@@ -1,15 +1,10 @@
- command bits and pieces:
* use "--" to mark start of command w/ neww etc to avoid quoting
* why doesn't command-prompt work if made read-only?
* allow multiple targets: fnmatch for -t/-c, for example detach all
clients with -t*
* add -c for new-session like new-window
* attach should take a pane and select it as well as attaching
* ' and " should be parsed the same (eg "\e" vs '\e') in config
and command prompt
* last-pane across sessions
* exact match operator for targets (or break the substring match
and require eg x* instead of just x)
- make command sequences more usable
* don't require space after ;
@@ -22,8 +17,7 @@
- format improvements:
* option to quote format (#{session_name:quoted})
* formats need conditions for >0 (for #P)
* some way to pad # stuff with spaces, #!2T maybe
* status stuff is redundant with formats
* some way to pad # stuff with spaces
* last window update time and format for it
* formats to show if a window is linked into multiple sessions, into
multiple attached sessions, and is the active window in multiple
@@ -33,8 +27,11 @@
* choose-pane command (augment choose-tree to do this?)
* choose-mode and copy-mode are very similar, make choose-mode a subset?
* flag to choose-* for sort order
* choose mode would be better per client than per window
* choose mode would be better per client than per window?
* 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
@@ -44,38 +41,33 @@
- improve mouse support:
* bind commands to mouse in different areas?
* more fine-grained options
* commands executed when clicking on a pattern (URL)
* send arrow key sequences for mouse scroll wheel in alternate screen
* 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)
- hooks!
- warts on current naming:
* display-time but message-fg/bg/attr
* list-* vs show-*
* split-window -> split-pane??
* split-window -> split-pane?
- better UTF-8 support:
* #22T can split in the middle of UTF-8 characters!
* window names and titles
* message display
* prompt input
* multibyte key input
* buffer_sample and the choose-* could show UTF-8 properly
* searching in copy mode
- copy/paste improvements:
* incremental searching
* append to buffer
* paste w/o trailing whitespace
* named buffers and allow gaps in the stack
* command to toggle selection not to move it in copy-mode
* regex searching
* copy-pipe should have -x as well
- layout stuff
* way to tag a layout as a number/name
* maybe keep last layout + size around and if size reverts just put it
back
back
* revamp layouts: they are too complicated, should be more closely
integrated, should support hints, layout sets should just be a
special case of custom layouts, and we should support panes that are
@@ -83,14 +75,15 @@
panelink to replace layout_cell
* way to set hints/limits about pane size for resizing
* 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)
* general key to space cells out evenly (horiz or vert) within their
parent cell (could replace even-vert/even-horiz layouts)
* separate active panes for different clients
- terminfo bits
* use a better termcap internally instead of screen, perhaps xterm
* use screen-256color when started on 256 colour terminal?
* need a tmux terminfo entry to document the extensions we are using in
upstream terminfo
* support title stack, both internally and externally (restore on
detach) http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
- code cleanup
* instead of separate window and session options, just one master
@@ -109,7 +102,7 @@
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)
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
@@ -123,11 +116,11 @@
* 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
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?
* 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
* customizable command aliases
* automatic pane logging
* BCE? We are halfway there (output side is done for pane backgrounds),
just need to change how screen/grid handles erase

263
alerts.c Normal file
View File

@@ -0,0 +1,263 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2015 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 <event.h>
#include "tmux.h"
int alerts_fired;
void alerts_timer(int, short, void *);
int alerts_enabled(struct window *, int);
void alerts_callback(int, short, void *);
void alerts_reset(struct window *);
int alerts_check_bell(struct session *, struct winlink *);
int alerts_check_activity(struct session *, struct winlink *);
int alerts_check_silence(struct session *, struct winlink *);
void alerts_ring_bell(struct session *);
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);
}
void
alerts_callback(unused int fd, unused short events, unused void *arg)
{
struct window *w;
struct session *s;
struct winlink *wl;
int flags, alerts;
RB_FOREACH(w, windows, &windows) {
RB_FOREACH(s, sessions, &sessions) {
RB_FOREACH(wl, winlinks, &s->windows) {
if (wl->window != w)
continue;
flags = w->flags;
alerts = alerts_check_bell(s, wl);
alerts |= alerts_check_activity(s, wl);
alerts |= alerts_check_silence(s, wl);
if (alerts != 0)
server_status_session(s);
log_debug("%s:%d @%u alerts check, alerts %#x, "
"flags %#x", s->name, wl->idx, w->id,
alerts, flags);
}
}
}
alerts_fired = 0;
}
int
alerts_enabled(struct window *w, int flags)
{
struct session *s;
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);
}
if (~flags & WINDOW_BELL)
return (0);
RB_FOREACH(s, sessions, &sessions) {
if (!session_has(s, w))
continue;
if (options_get_number(&s->options, "bell-action") != BELL_NONE)
return (1);
}
return (0);
}
void
alerts_reset_all(void)
{
struct window *w;
RB_FOREACH(w, windows, &windows)
alerts_reset(w);
}
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)
return;
w->flags |= flags;
log_debug("@%u alerts flags added %#x", w->id, flags);
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;
}
}
int
alerts_check_bell(struct session *s, struct winlink *wl)
{
struct client *c;
struct window *w = wl->window;
int action, visual;
if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL)
return (0);
if (s->curw != wl || s->flags & SESSION_UNATTACHED)
wl->flags |= WINLINK_BELL;
if (s->flags & SESSION_UNATTACHED)
return (0);
if (s->curw->window == w)
w->flags &= ~WINDOW_BELL;
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;
if (!visual) {
if ((action == BELL_CURRENT &&
c->session->curw->window == w) ||
(action == BELL_OTHER &&
c->session->curw->window != w) ||
action == BELL_ANY)
tty_putcode(&c->tty, TTYC_BEL);
continue;
}
if (action == BELL_CURRENT && c->session->curw->window == w)
status_message_set(c, "Bell in current window");
else if (action == BELL_ANY || (action == BELL_OTHER &&
c->session->curw->window != w))
status_message_set(c, "Bell in window %d", wl->idx);
}
return (WINDOW_BELL);
}
int
alerts_check_activity(struct session *s, struct winlink *wl)
{
struct client *c;
struct window *w = wl->window;
if (s->curw->window == w)
w->flags &= ~WINDOW_ACTIVITY;
if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)
return (0);
if (s->curw == wl && !(s->flags & SESSION_UNATTACHED))
return (0);
if (!options_get_number(&w->options, "monitor-activity"))
return (0);
if (options_get_number(&s->options, "bell-on-alert"))
alerts_ring_bell(s);
wl->flags |= WINLINK_ACTIVITY;
if (options_get_number(&s->options, "visual-activity")) {
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
status_message_set(c, "Activity in window %d", wl->idx);
}
}
return (WINDOW_ACTIVITY);
}
int
alerts_check_silence(struct session *s, struct winlink *wl)
{
struct client *c;
struct window *w = wl->window;
if (s->curw->window == w)
w->flags &= ~WINDOW_SILENCE;
if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
return (0);
if (s->curw == wl && !(s->flags & SESSION_UNATTACHED))
return (0);
if (options_get_number(&w->options, "monitor-silence") == 0)
return (0);
if (options_get_number(&s->options, "bell-on-alert"))
alerts_ring_bell(s);
wl->flags |= WINLINK_SILENCE;
if (options_get_number(&s->options, "visual-silence")) {
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
status_message_set(c, "Silence in window %d", wl->idx);
}
}
return (WINDOW_SILENCE);
}
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,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,6 +28,12 @@
* Manipulate command arguments.
*/
struct args_entry {
u_char flag;
char *value;
RB_ENTRY(args_entry) entry;
};
struct args_entry *args_find(struct args *, u_char);
RB_GENERATE(args_tree, args_entry, entry, args_cmp);
@@ -125,7 +131,7 @@ args_free(struct args *args)
size_t
args_print(struct args *args, char *buf, size_t len)
{
size_t off;
size_t off, used;
int i;
const char *quotes;
struct args_entry *entry;
@@ -165,9 +171,12 @@ args_print(struct args *args, char *buf, size_t len)
quotes = "\"";
else
quotes = "";
off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
used = xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
off != 0 ? " " : "", entry->flag, quotes, entry->value,
quotes);
if (used > len - off)
used = len - off;
off += used;
}
/* And finally the argument vector. */
@@ -181,8 +190,11 @@ args_print(struct args *args, char *buf, size_t len)
quotes = "\"";
else
quotes = "";
off += xsnprintf(buf + off, len - off, "%s%s%s%s",
used = xsnprintf(buf + off, len - off, "%s%s%s%s",
off != 0 ? " " : "", quotes, args->argv[i], quotes);
if (used > len - off)
used = len - off;
off += used;
}
return (off);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -39,10 +39,10 @@
fatalx("size too big"); \
if ((a)->space == 0) { \
(a)->space = ARRAY_INITIALSPACE(a); \
(a)->list = xrealloc((a)->list, 1, (a)->space); \
(a)->list = xrealloc((a)->list, (a)->space); \
} \
while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \
(a)->list = xrealloc((a)->list, 2, (a)->space); \
(a)->list = xreallocarray((a)->list, 2, (a)->space); \
(a)->space *= 2; \
} \
} while (0)

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>

View File

@@ -1,5 +1,4 @@
#!/bin/sh
# $Id$
if [ "x$(uname)" = "xOpenBSD" ]; then
[ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.10

174
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -17,29 +17,77 @@
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
struct cmd_q *cfg_cmd_q;
int cfg_finished;
int cfg_references;
struct causelist cfg_causes;
struct client *cfg_client;
char *cfg_file;
struct cmd_q *cfg_cmd_q;
int cfg_finished;
int cfg_references;
char **cfg_causes;
u_int cfg_ncauses;
struct client *cfg_client;
void cfg_default_done(struct cmd_q *);
void
set_cfg_file(const char *path)
{
free(cfg_file);
cfg_file = xstrdup(path);
}
void
start_cfg(void)
{
char *cause = NULL;
const char *home;
cfg_cmd_q = cmdq_new(NULL);
cfg_cmd_q->emptyfn = cfg_default_done;
cfg_finished = 0;
cfg_references = 1;
cfg_client = TAILQ_FIRST(&clients);
if (cfg_client != NULL)
cfg_client->references++;
if (access(TMUX_CONF, R_OK) == 0) {
if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1)
cfg_add_cause("%s: %s", TMUX_CONF, cause);
} else if (errno != ENOENT)
cfg_add_cause("%s: %s", TMUX_CONF, strerror(errno));
if (cfg_file == NULL && (home = find_home()) != NULL) {
xasprintf(&cfg_file, "%s/.tmux.conf", home);
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
free(cfg_file);
cfg_file = NULL;
}
}
if (cfg_file != NULL && load_cfg(cfg_file, cfg_cmd_q, &cause) == -1)
cfg_add_cause("%s: %s", cfg_file, cause);
free(cause);
cmdq_continue(cfg_cmd_q);
}
int
load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
{
FILE *f;
u_int n, found;
char *buf, *copy, *line, *cause1, *msg;
size_t len, oldlen;
char delim[3] = { '\\', '\\', '\0' };
u_int found;
size_t line = 0;
char *buf, *cause1, *p;
struct cmd_list *cmdlist;
log_debug("loading %s", path);
@@ -48,69 +96,36 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
return (-1);
}
n = found = 0;
line = NULL;
while ((buf = fgetln(f, &len))) {
/* Trim \n. */
if (buf[len - 1] == '\n')
len--;
log_debug("%s: %.*s", path, (int)len, buf);
/* Current line is the continuation of the previous one. */
if (line != NULL) {
oldlen = strlen(line);
line = xrealloc(line, 1, oldlen + len + 1);
} else {
oldlen = 0;
line = xmalloc(len + 1);
}
/* Append current line to the previous. */
memcpy(line + oldlen, buf, len);
line[oldlen + len] = '\0';
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;
}
copy = line;
line = NULL;
found = 0;
while ((buf = fparseln(f, NULL, &line, delim, 0)) != NULL) {
log_debug("%s: %s", path, buf);
/* Skip empty lines. */
buf = copy;
while (isspace((u_char)*buf))
buf++;
if (*buf == '\0') {
free(copy);
p = buf;
while (isspace((u_char) *p))
p++;
if (*p == '\0') {
free(buf);
continue;
}
/* Parse and run the command. */
if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) {
free(copy);
if (cmd_string_parse(p, &cmdlist, path, line, &cause1) != 0) {
free(buf);
if (cause1 == NULL)
continue;
xasprintf(&msg, "%s:%u: %s", path, n, cause1);
ARRAY_ADD(&cfg_causes, msg);
cfg_add_cause("%s:%zu: %s", path, line, cause1);
free(cause1);
continue;
}
free(copy);
free(buf);
if (cmdlist == NULL)
continue;
cmdq_append(cmdq, cmdlist);
cmdq_append(cmdq, cmdlist, NULL);
cmd_list_free(cmdlist);
found++;
}
if (line != NULL)
free(line);
fclose(f);
return (found);
@@ -139,28 +154,59 @@ cfg_default_done(unused struct cmd_q *cmdq)
*/
if (!TAILQ_EMPTY(&cfg_client->cmdq->queue))
cmdq_continue(cfg_client->cmdq);
cfg_client->references--;
server_client_unref(cfg_client);
cfg_client = NULL;
}
}
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 cmd_q *cmdq)
{
u_int i;
for (i = 0; i < cfg_ncauses; i++) {
cmdq_print(cmdq, "%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;
char *cause;
u_int i;
if (s == NULL || ARRAY_EMPTY(&cfg_causes))
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 < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
window_copy_add(wp, "%s", cause);
free(cause);
for (i = 0; i < cfg_ncauses; i++) {
window_copy_add(wp, "%s", cfg_causes[i]);
free(cfg_causes[i]);
}
ARRAY_FREE(&cfg_causes);
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
}

253
client.c
View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,13 +26,14 @@
#include <errno.h>
#include <event.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
int client_flags;
struct imsgbuf client_ibuf;
struct event client_event;
struct event client_stdin;
@@ -51,9 +52,10 @@ enum msgtype client_exittype;
const char *client_exitsession;
int client_attached;
__dead void client_exec(const char *);
int client_get_lock(char *);
int client_connect(char *, int);
void client_send_identify(int);
int client_connect(struct event_base *, char *, int);
void client_send_identify(const char *, int);
int client_write_one(enum msgtype, int, const void *, size_t);
int client_write_server(enum msgtype, const void *, size_t);
void client_update_event(void);
@@ -62,7 +64,7 @@ void client_stdin_callback(int, short, void *);
void client_write(int, const char *, size_t);
void client_callback(int, short, void *);
int client_dispatch_attached(void);
int client_dispatch_wait(void *);
int client_dispatch_wait(void);
const char *client_exit_message(void);
/*
@@ -78,25 +80,30 @@ client_get_lock(char *lockfile)
if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1)
fatal("open failed");
log_debug("lock file is %s", lockfile);
if (lockf(lockfd, F_TLOCK, 0) == -1 && errno == EAGAIN) {
while (lockf(lockfd, F_LOCK, 0) == -1 && errno == EINTR)
if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) {
log_debug("flock failed: %s", strerror(errno));
if (errno != EAGAIN)
return (lockfd);
while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR)
/* nothing */;
close(lockfd);
return (-1);
}
log_debug("flock succeeded");
return (lockfd);
}
/* Connect client to server. */
int
client_connect(char *path, int start_server)
client_connect(struct event_base *base, char *path, int start_server)
{
struct sockaddr_un sa;
size_t size;
int fd, lockfd;
char *lockfile;
int fd, lockfd = -1, locked = 0;
char *lockfile = NULL;
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
@@ -105,37 +112,60 @@ client_connect(char *path, int start_server)
errno = ENAMETOOLONG;
return (-1);
}
log_debug("socket is %s", path);
retry:
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket failed");
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
log_debug("trying connect");
if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
log_debug("connect failed: %s", strerror(errno));
if (errno != ECONNREFUSED && errno != ENOENT)
goto failed;
if (!start_server)
goto failed;
close(fd);
xasprintf(&lockfile, "%s.lock", path);
if ((lockfd = client_get_lock(lockfile)) == -1) {
free(lockfile);
if (!locked) {
xasprintf(&lockfile, "%s.lock", path);
if ((lockfd = client_get_lock(lockfile)) == -1) {
log_debug("didn't get lock");
free(lockfile);
goto retry;
}
log_debug("got lock");
/*
* Always retry at least once, even if we got the lock,
* because another client could have taken the lock,
* started the server and released the lock between our
* connect() and flock().
*/
locked = 1;
goto retry;
}
if (unlink(path) != 0 && errno != ENOENT) {
free(lockfile);
close(lockfd);
return (-1);
}
fd = server_start(lockfd, lockfile);
fd = server_start(base, lockfd, lockfile);
}
if (locked) {
free(lockfile);
close(lockfd);
}
setblocking(fd, 0);
return (fd);
failed:
if (locked) {
free(lockfile);
close(lockfd);
}
close(fd);
return (-1);
}
@@ -179,18 +209,22 @@ client_exit_message(void)
/* Client main loop. */
int
client_main(int argc, char **argv, int flags)
client_main(struct event_base *base, int argc, char **argv, int flags)
{
struct cmd *cmd;
struct cmd_list *cmdlist;
struct msg_command_data *data;
int cmdflags, fd, i;
int cmdflags, fd, i, cwd;
const char* ttynam;
pid_t ppid;
enum msgtype msg;
char *cause;
struct termios tio, saved_tio;
size_t size;
/* Save the flags. */
client_flags = flags;
/* Set up the initial command. */
cmdflags = 0;
if (shell_cmd != NULL) {
@@ -198,7 +232,7 @@ client_main(int argc, char **argv, int flags)
cmdflags = CMD_STARTSERVER;
} else if (argc == 0) {
msg = MSG_COMMAND;
cmdflags = CMD_STARTSERVER|CMD_CANTNEST;
cmdflags = CMD_STARTSERVER;
} else {
msg = MSG_COMMAND;
@@ -216,31 +250,51 @@ client_main(int argc, char **argv, int flags)
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (cmd->entry->flags & CMD_STARTSERVER)
cmdflags |= CMD_STARTSERVER;
if (cmd->entry->flags & CMD_CANTNEST)
cmdflags |= CMD_CANTNEST;
}
cmd_list_free(cmdlist);
}
/*
* Check if this could be a nested session, if the command can't nest:
* if the socket path matches $TMUX, this is probably the same server.
*/
if (shell_cmd == NULL && environ_path != NULL &&
(cmdflags & CMD_CANTNEST) &&
strcmp(socket_path, environ_path) == 0) {
fprintf(stderr, "sessions should be nested with care, "
"unset $TMUX to force\n");
/* Establish signal handlers. */
set_signals(client_signal);
/* Initialize the client socket and start the server. */
fd = client_connect(base, socket_path, cmdflags & CMD_STARTSERVER);
if (fd == -1) {
if (errno == ECONNREFUSED) {
fprintf(stderr, "no server running on %s\n",
socket_path);
} else {
fprintf(stderr, "error connecting to %s (%s)\n",
socket_path, strerror(errno));
}
return (1);
}
/* Initialise the client socket and start the server. */
fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
if (fd == -1) {
fprintf(stderr, "failed to connect to server: %s\n",
strerror(errno));
return (1);
}
/* Save these before pledge(). */
if ((cwd = open(".", O_RDONLY)) == -1)
cwd = open("/", O_RDONLY);
if ((ttynam = ttyname(STDIN_FILENO)) == NULL)
ttynam = "";
#ifdef __OpenBSD__
/*
* Drop privileges for client. "proc exec" is needed for -c and for
* locking (which uses system(3)).
*
* "tty" is needed to restore termios(4) and also for some reason -CC
* does not work properly without it (input is not recognised).
*
* "sendfd" is dropped later in client_dispatch_wait().
*/
if (pledge("stdio unix sendfd proc exec tty", NULL) != 0)
fatal("pledge failed");
#endif
/* Free stuff that is not used in the client. */
options_free(&global_options);
options_free(&global_s_options);
options_free(&global_w_options);
environ_free(&global_environ);
/* Set process title, log and signals now this is the client. */
#ifdef HAVE_SETPROCTITLE
@@ -250,13 +304,13 @@ client_main(int argc, char **argv, int flags)
/* Create imsg. */
imsg_init(&client_ibuf, fd);
event_set(&client_event, fd, EV_READ, client_callback, shell_cmd);
event_set(&client_event, fd, EV_READ, client_callback, NULL);
/* Create stdin handler. */
setblocking(STDIN_FILENO, 0);
event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST,
client_stdin_callback, NULL);
if (flags & CLIENT_CONTROLCONTROL) {
if (client_flags & CLIENT_CONTROLCONTROL) {
if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
fprintf(stderr, "tcgetattr failed: %s\n",
strerror(errno));
@@ -276,11 +330,8 @@ client_main(int argc, char **argv, int flags)
tcsetattr(STDIN_FILENO, TCSANOW, &tio);
}
/* Establish signal handlers. */
set_signals(client_signal);
/* Send identify messages. */
client_send_identify(flags);
client_send_identify(ttynam, cwd); /* closes cwd */
/* Send first command. */
if (msg == MSG_COMMAND) {
@@ -292,7 +343,7 @@ client_main(int argc, char **argv, int flags)
/* Prepare command for server. */
data->argc = argc;
if (cmd_pack_argv(argc, argv, (char*)(data + 1), size) != 0) {
if (cmd_pack_argv(argc, argv, (char *)(data + 1), size) != 0) {
fprintf(stderr, "command too long\n");
free(data);
return (1);
@@ -315,13 +366,13 @@ client_main(int argc, char **argv, int flags)
/* Print the exit message, if any, and exit. */
if (client_attached) {
if (client_exitreason != CLIENT_EXIT_NONE && !login_shell)
if (client_exitreason != CLIENT_EXIT_NONE)
printf("[%s]\n", client_exit_message());
ppid = getppid();
if (client_exittype == MSG_DETACHKILL && ppid > 1)
kill(ppid, SIGHUP);
} else if (flags & CLIENT_CONTROLCONTROL) {
} else if (client_flags & CLIENT_CONTROLCONTROL) {
if (client_exitreason != CLIENT_EXIT_NONE)
printf("%%exit %s\n", client_exit_message());
else
@@ -335,11 +386,13 @@ client_main(int argc, char **argv, int flags)
/* Send identify messages to server. */
void
client_send_identify(int flags)
client_send_identify(const char *ttynam, int cwd)
{
const char *s;
const char *s;
char **ss;
int fd;
size_t sslen;
int fd, flags = client_flags;
pid_t pid;
client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
@@ -347,24 +400,23 @@ client_send_identify(int flags)
s = "";
client_write_one(MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
if ((s = ttyname(STDIN_FILENO)) == NULL)
s = "";
client_write_one(MSG_IDENTIFY_TTYNAME, -1, s, strlen(s) + 1);
if ((fd = open(".", O_RDONLY)) == -1)
fd = open("/", O_RDONLY);
client_write_one(MSG_IDENTIFY_CWD, fd, NULL, 0);
client_write_one(MSG_IDENTIFY_TTYNAME, -1, ttynam, strlen(ttynam) + 1);
client_write_one(MSG_IDENTIFY_CWD, cwd, NULL, 0);
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
client_write_one(MSG_IDENTIFY_STDIN, fd, NULL, 0);
for (ss = environ; *ss != NULL; ss++)
client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, strlen(*ss) + 1);
pid = getpid();
client_write_one(MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
for (ss = environ; *ss != NULL; ss++) {
sslen = strlen(*ss) + 1;
if (sslen <= MAX_IMSGSIZE - IMSG_HEADER_SIZE)
client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, sslen);
}
client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0);
client_update_event();
}
/* Helper to send one message. */
@@ -374,7 +426,7 @@ client_write_one(enum msgtype type, int fd, const void *buf, size_t len)
int retval;
retval = imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, fd,
(void*)buf, len);
(void *)buf, len);
if (retval != 1)
return (-1);
return (0);
@@ -402,27 +454,22 @@ client_update_event(void)
events = EV_READ;
if (client_ibuf.w.queued > 0)
events |= EV_WRITE;
event_set(
&client_event, client_ibuf.fd, events, client_callback, shell_cmd);
event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
event_add(&client_event, NULL);
}
/* Callback to handle signals in the client. */
void
client_signal(int sig, unused short events, unused void *data)
client_signal(int sig, unused short events, unused void *arg)
{
struct sigaction sigact;
int status;
if (!client_attached) {
switch (sig) {
case SIGCHLD:
waitpid(WAIT_ANY, &status, WNOHANG);
break;
case SIGTERM:
if (sig == SIGCHLD)
waitpid(WAIT_ANY, &status, WNOHANG);
else if (!client_attached) {
if (sig == SIGTERM)
event_loopexit(NULL);
break;
}
} else {
switch (sig) {
case SIGHUP:
@@ -455,7 +502,7 @@ client_signal(int sig, unused short events, unused void *data)
/* Callback for client imsg read events. */
void
client_callback(unused int fd, short events, void *data)
client_callback(unused int fd, short events, unused void *arg)
{
ssize_t n;
int retval;
@@ -466,7 +513,7 @@ client_callback(unused int fd, short events, void *data)
if (client_attached)
retval = client_dispatch_attached();
else
retval = client_dispatch_wait(data);
retval = client_dispatch_wait();
if (retval != 0) {
event_loopexit(NULL);
return;
@@ -474,7 +521,7 @@ client_callback(unused int fd, short events, void *data)
}
if (events & EV_WRITE) {
if (msgbuf_write(&client_ibuf.w) < 0 && errno != EAGAIN)
if (msgbuf_write(&client_ibuf.w) <= 0 && errno != EAGAIN)
goto lost_server;
}
@@ -489,7 +536,7 @@ lost_server:
/* Callback for client stdin read events. */
void
client_stdin_callback(unused int fd, unused short events, unused void *data1)
client_stdin_callback(unused int fd, unused short events, unused void *arg)
{
struct msg_stdin_data data;
@@ -521,9 +568,38 @@ client_write(int fd, const char *data, size_t size)
}
}
/* Run command in shell; used for -c. */
__dead void
client_exec(const char *shell)
{
const char *name, *ptr;
char *argv0;
log_debug("shell %s, command %s", shell, shell_cmd);
ptr = strrchr(shell, '/');
if (ptr != NULL && *(ptr + 1) != '\0')
name = ptr + 1;
else
name = shell;
if (client_flags & CLIENT_LOGIN)
xasprintf(&argv0, "-%s", name);
else
xasprintf(&argv0, "%s", name);
setenv("SHELL", shell, 1);
setblocking(STDIN_FILENO, 1);
setblocking(STDOUT_FILENO, 1);
setblocking(STDERR_FILENO, 1);
closefrom(STDERR_FILENO + 1);
execl(shell, argv0, "-c", shell_cmd, (char *) NULL);
fatal("execl failed");
}
/* Dispatch imsgs when in wait state (before MSG_READY). */
int
client_dispatch_wait(void *data0)
client_dispatch_wait(void)
{
struct imsg imsg;
char *data;
@@ -531,6 +607,21 @@ client_dispatch_wait(void *data0)
struct msg_stdout_data stdoutdata;
struct msg_stderr_data stderrdata;
int retval;
#ifdef __OpenBSD__
static int pledge_applied;
/*
* "sendfd" is no longer required once all of the identify messages
* have been sent. We know the server won't send us anything until that
* point (because we don't ask it to), so we can drop "sendfd" once we
* get the first message from the server.
*/
if (!pledge_applied) {
if (pledge("stdio unix proc exec tty", NULL) != 0)
fatal("pledge failed");
pledge_applied = 1;
};
#endif
for (;;) {
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
@@ -541,7 +632,7 @@ client_dispatch_wait(void *data0)
data = imsg.data;
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
log_debug("got %d from server", imsg.hdr.type);
log_debug("got %u from server", imsg.hdr.type);
switch (imsg.hdr.type) {
case MSG_EXIT:
case MSG_SHUTDOWN:
@@ -588,7 +679,7 @@ client_dispatch_wait(void *data0)
fatalx("bad MSG_VERSION size");
fprintf(stderr, "protocol version mismatch "
"(client %u, server %u)\n", PROTOCOL_VERSION,
"(client %d, server %u)\n", PROTOCOL_VERSION,
imsg.hdr.peerid);
client_exitval = 1;
@@ -599,7 +690,7 @@ client_dispatch_wait(void *data0)
fatalx("bad MSG_SHELL string");
clear_signals(0);
shell_exec(data, data0);
client_exec(data);
/* NOTREACHED */
case MSG_DETACH:
case MSG_DETACHKILL:
@@ -632,7 +723,7 @@ client_dispatch_attached(void)
data = imsg.data;
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
log_debug("got %d from server", imsg.hdr.type);
log_debug("got %u from server", imsg.hdr.type);
switch (imsg.hdr.type) {
case MSG_DETACH:
case MSG_DETACHKILL:

166
clock.c
View File

@@ -1,166 +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;
struct tm *tm;
u_int i, j, x, y, idx;
t = time(NULL);
tm = localtime(&t);
if (style == 0) {
strftime(tim, sizeof tim, "%l:%M ", localtime(&t));
if (tm->tm_hour >= 12)
strlcat(tim, "PM", sizeof tim);
else
strlcat(tim, "AM", sizeof tim);
} else
strftime(tim, sizeof tim, "%H:%M", tm);
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,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,25 +34,23 @@ enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach",
"c:drt:", 0, 0,
"[-dr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER,
NULL,
"c:dErt:", 0, 0,
"[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
CMD_STARTSERVER,
cmd_attach_session_exec
};
enum cmd_retval
cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
const char *cflag)
const char *cflag, int Eflag)
{
struct session *s;
struct client *c;
struct client *c = cmdq->client, *c_loop;
struct winlink *wl = NULL;
struct window *w = NULL;
struct window_pane *wp = NULL;
const char *update;
char *cause;
u_int i;
int fd;
struct format_tree *ft;
char *cp;
@@ -71,15 +69,23 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
} else {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
w = cmd_lookup_windowid(tflag);
if (w == NULL && (wp = cmd_lookup_paneid(tflag)) != NULL)
w = wp->window;
w = window_find_by_id_str(tflag);
if (w == NULL) {
wp = window_pane_find_by_id_str(tflag);
if (wp != NULL)
w = wp->window;
}
if (w != NULL)
wl = winlink_find_by_window(&s->windows, w);
}
if (cmdq->client == NULL)
if (c == NULL)
return (CMD_RETURN_NORMAL);
if (server_client_check_nested(c)) {
cmdq_error(cmdq, "sessions should be nested with care, "
"unset $TMUX to force");
return (CMD_RETURN_ERROR);
}
if (wl != NULL) {
if (wp != NULL)
@@ -87,96 +93,82 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
session_set_current(s, wl);
}
if (cmdq->client->session != NULL) {
if (cflag != NULL) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
NULL, NULL);
cp = format_expand(ft, cflag);
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
close(s->cwd);
s->cwd = fd;
}
if (c->session != NULL) {
if (dflag) {
/*
* Can't use server_write_session in case attaching to
* the same session as currently attached to.
*/
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (c == cmdq->client)
TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue;
server_write_client(c, MSG_DETACH,
c->session->name,
strlen(c->session->name) + 1);
c_loop->session->name,
strlen(c_loop->session->name) + 1);
}
}
if (cflag != NULL) {
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, s->curw);
format_window_pane(ft, s->curw->window->active);
cp = format_expand(ft, cflag);
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
close(s->cwd);
s->cwd = fd;
if (!Eflag) {
update = options_get_string(&s->options,
"update-environment");
environ_update(update, &c->environ, &s->environ);
}
cmdq->client->session = s;
notify_attached_session_changed(cmdq->client);
session_update_activity(s);
server_redraw_client(cmdq->client);
c->session = s;
status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
} else {
if (server_client_open(cmdq->client, s, &cause) != 0) {
if (server_client_open(c, &cause) != 0) {
cmdq_error(cmdq, "open terminal failed: %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
if (cflag != NULL) {
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, s->curw);
format_window_pane(ft, s->curw->window->active);
cp = format_expand(ft, cflag);
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
close(s->cwd);
s->cwd = fd;
}
if (rflag)
cmdq->client->flags |= CLIENT_READONLY;
c->flags |= CLIENT_READONLY;
if (dflag) {
server_write_session(s, MSG_DETACH, s->name,
strlen(s->name) + 1);
}
update = options_get_string(&s->options, "update-environment");
environ_update(update, &cmdq->client->environ, &s->environ);
if (!Eflag) {
update = options_get_string(&s->options,
"update-environment");
environ_update(update, &c->environ, &s->environ);
}
cmdq->client->session = s;
notify_attached_session_changed(cmdq->client);
session_update_activity(s);
server_redraw_client(cmdq->client);
c->session = s;
status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
server_write_ready(cmdq->client);
server_write_ready(c);
cmdq->client_exit = 0;
}
recalculate_sizes();
@@ -191,5 +183,6 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args;
return (cmd_attach_session(cmdq, args_get(args, 't'),
args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c')));
args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c'),
args_has(args, 'E')));
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,14 +29,13 @@
enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_q *, int);
enum cmd_retval cmd_bind_key_mode_table(struct cmd *, struct cmd_q *, int);
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
"cnrt:", 1, -1,
"[-cnr] [-t key-table] key command [arguments]",
"cnrt:T:", 1, -1,
"[-cnr] [-t mode-table] [-T key-table] key command [arguments]",
0,
NULL,
cmd_bind_key_exec
};
@@ -47,6 +46,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
char *cause;
struct cmd_list *cmdlist;
int key;
const char *tablename;
if (args_has(args, 't')) {
if (args->argc != 2 && args->argc != 3) {
@@ -67,7 +67,14 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
}
if (args_has(args, 't'))
return (cmd_bind_key_table(self, cmdq, key));
return (cmd_bind_key_mode_table(self, cmdq, key));
if (args_has(args, 'T'))
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, NULL, 0,
&cause);
@@ -77,14 +84,12 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
if (!args_has(args, 'n'))
key |= KEYC_PREFIX;
key_bindings_add(key, args_has(args, 'r'), cmdlist);
key_bindings_add(tablename, key, args_has(args, 'r'), cmdlist);
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_bind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
{
struct args *args = self->args;
const char *tablename;
@@ -105,18 +110,34 @@ cmd_bind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
return (CMD_RETURN_ERROR);
}
if (cmd != MODEKEYCOPY_COPYPIPE) {
if (args->argc != 2) {
cmdq_error(cmdq, "no argument allowed");
return (CMD_RETURN_ERROR);
switch (cmd) {
case MODEKEYCOPY_APPENDSELECTION:
case MODEKEYCOPY_COPYSELECTION:
case MODEKEYCOPY_STARTNAMEDBUFFER:
if (args->argc == 2)
arg = NULL;
else {
arg = args->argv[2];
if (strcmp(arg, "-x") != 0) {
cmdq_error(cmdq, "unknown argument");
return (CMD_RETURN_ERROR);
}
}
arg = NULL;
} else {
break;
case MODEKEYCOPY_COPYPIPE:
if (args->argc != 3) {
cmdq_error(cmdq, "no argument given");
return (CMD_RETURN_ERROR);
}
arg = args->argv[2];
break;
default:
if (args->argc != 2) {
cmdq_error(cmdq, "no argument allowed");
return (CMD_RETURN_ERROR);
}
arg = NULL;
break;
}
mtmp.key = key;

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,14 +26,15 @@
* Break pane off into a window.
*/
#define BREAK_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp",
"dPF:t:", 0, 0,
"[-dP] [-F format] " CMD_TARGET_PANE_USAGE,
"dPF:s:t:", 0, 0,
"[-dP] [-F format] " CMD_SRCDST_PANE_USAGE,
0,
NULL,
cmd_break_pane_exec
};
@@ -42,42 +43,39 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct session *s;
struct session *src_s;
struct session *dst_s;
struct window_pane *wp;
struct window *w;
char *name;
char *cause;
int base_idx;
struct client *c;
int idx;
struct format_tree *ft;
const char *template;
char *cp;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
wl = cmd_find_pane(cmdq, args_get(args, 's'), &src_s, &wp);
if (wl == NULL)
return (CMD_RETURN_ERROR);
if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst_s)) == -2)
return (CMD_RETURN_ERROR);
if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
cmdq_error(cmdq, "index %d already in use", idx);
return (CMD_RETURN_ERROR);
}
w = wl->window;
if (window_count_panes(wl->window) == 1) {
if (window_count_panes(w) == 1) {
cmdq_error(cmdq, "can't break with only one pane");
return (CMD_RETURN_ERROR);
}
w = wl->window;
server_unzoom_window(w);
TAILQ_REMOVE(&w->panes, wp, entry);
if (wp == w->active) {
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;
window_lost_pane(w, wp);
layout_close_pane(wp);
w = wp->window = window_create1(s->sx, s->sy);
w = wp->window = window_create1(dst_s->sx, dst_s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
name = default_window_name(w);
@@ -85,24 +83,26 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
free(name);
layout_init(w, wp);
base_idx = options_get_number(&s->options, "base-index");
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
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'))
session_select(s, wl->idx);
session_select(dst_s, wl->idx);
server_redraw_session(s);
server_status_session_group(s);
server_redraw_session(src_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 ((template = args_get(args, 'F')) == NULL)
template = BREAK_PANE_TEMPLATE;
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wp);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), dst_s, wl,
wp);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
@@ -38,17 +38,16 @@ char *cmd_capture_pane_history(struct args *, struct cmd_q *,
const struct cmd_entry cmd_capture_pane_entry = {
"capture-pane", "capturep",
"ab:CeE:JpPqS:t:", 0, 0,
"[-aCeJpPq] [-b buffer-index] [-E end-line] [-S start-line]"
"[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] [-S start-line]"
CMD_TARGET_PANE_USAGE,
0,
NULL,
cmd_capture_pane_exec
};
char *
cmd_capture_pane_append(char *buf, size_t *len, char *line, size_t linelen)
{
buf = xrealloc(buf, 1, *len + linelen + 1);
buf = xrealloc(buf, *len + linelen + 1);
memcpy(buf + *len, line, linelen);
*len += linelen;
return (buf);
@@ -58,15 +57,17 @@ char *
cmd_capture_pane_pending(struct args *args, struct window_pane *wp,
size_t *len)
{
char *buf, *line, tmp[5];
size_t linelen;
u_int i;
struct evbuffer *pending;
char *buf, *line, tmp[5];
size_t linelen;
u_int i;
if (wp->ictx.since_ground == NULL)
pending = input_pending(wp);
if (pending == NULL)
return (xstrdup(""));
line = EVBUFFER_DATA(wp->ictx.since_ground);
linelen = EVBUFFER_LENGTH(wp->ictx.since_ground);
line = EVBUFFER_DATA(pending);
linelen = EVBUFFER_LENGTH(pending);
buf = xstrdup("");
if (args_has(args, 'C')) {
@@ -75,7 +76,7 @@ cmd_capture_pane_pending(struct args *args, struct window_pane *wp,
tmp[0] = line[i];
tmp[1] = '\0';
} else
xsnprintf(tmp, sizeof tmp, "\\%03o", line[i]);
xsnprintf(tmp, sizeof tmp, "\\%03hho", line[i]);
buf = cmd_capture_pane_append(buf, len, tmp,
strlen(tmp));
}
@@ -94,6 +95,7 @@ cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq,
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;
sx = screen_size_x(&wp->base);
@@ -109,27 +111,37 @@ cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq,
} else
gd = wp->base.grid;
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)
Sflag = args_get(args, 'S');
if (Sflag != NULL && strcmp(Sflag, "-") == 0)
top = 0;
else
top = gd->hsize + n;
if (top > gd->hsize + gd->sy - 1)
top = gd->hsize + gd->sy - 1;
else {
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;
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);
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)
Eflag = args_get(args, 'E');
if (Eflag != NULL && strcmp(Eflag, "-") == 0)
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) {
tmp = bottom;
@@ -165,8 +177,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c;
struct window_pane *wp;
char *buf, *cause;
int buffer;
u_int limit;
const char *bufname;
size_t len;
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
@@ -185,29 +196,22 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
if (c == NULL ||
(c->session != NULL && !(c->flags & CLIENT_CONTROL))) {
cmdq_error(cmdq, "can't write to stdout");
free(buf);
return (CMD_RETURN_ERROR);
}
evbuffer_add(c->stdout_data, buf, len);
free(buf);
if (args_has(args, 'P') && len > 0)
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
} else {
limit = options_get_number(&global_options, "buffer-limit");
if (!args_has(args, 'b')) {
paste_add(&global_buffers, buf, len, limit);
return (CMD_RETURN_NORMAL);
}
bufname = NULL;
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
cmdq_error(cmdq, "buffer %s", cause);
free(buf);
if (paste_set(buf, len, bufname, &cause) != 0) {
cmdq_error(cmdq, "%s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
if (paste_replace(&global_buffers, buffer, buf, len) != 0) {
cmdq_error(cmdq, "no buffer %d", buffer);
free(buf);
return (CMD_RETURN_ERROR);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,6 +27,9 @@
* Enter choice mode to choose a buffer.
*/
#define CHOOSE_BUFFER_TEMPLATE \
"#{buffer_name}: #{buffer_size} bytes: #{buffer_sample}"
enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_choose_buffer_entry = {
@@ -34,7 +37,6 @@ const struct cmd_entry cmd_choose_buffer_entry = {
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0,
NULL,
cmd_choose_buffer_exec
};
@@ -49,8 +51,9 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
char *action, *action_data;
const char *template;
u_int idx;
int utf8flag;
if ((c = cmd_current_client(cmdq)) == NULL) {
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
@@ -60,8 +63,9 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
utf8flag = options_get_number(&wl->window->options, "utf8");
if (paste_get_top(&global_buffers) == NULL)
if (paste_get_top(NULL) == NULL)
return (CMD_RETURN_NORMAL);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
@@ -73,19 +77,20 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
action = xstrdup("paste-buffer -b '%%'");
idx = 0;
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
pb = NULL;
while ((pb = paste_walk(pb)) != NULL) {
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->idx = idx - 1;
cdata->idx = idx;
cdata->ft_template = xstrdup(template);
format_add(cdata->ft, "line", "%u", idx - 1);
format_paste_buffer(cdata->ft, pb);
format_defaults_paste_buffer(cdata->ft, pb, utf8flag);
xasprintf(&action_data, "%u", idx - 1);
xasprintf(&action_data, "%s", paste_buffer_name(pb));
cdata->command = cmd_template_replace(action, action_data, 1);
free(action_data);
window_choose_add(wl->window->active, cdata);
idx++;
}
free(action);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,6 +27,12 @@
* Enter choice mode to choose a client.
*/
#define CHOOSE_CLIENT_TEMPLATE \
"#{client_tty}: #{session_name} " \
"[#{client_width}x#{client_height} #{client_termname}]" \
"#{?client_utf8, (utf8),}#{?client_readonly, (ro),} " \
"(last used #{client_activity_string})"
enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_q *);
void cmd_choose_client_callback(struct window_choose_data *);
@@ -36,7 +42,6 @@ const struct cmd_entry cmd_choose_client_entry = {
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0,
NULL,
cmd_choose_client_exec
};
@@ -54,9 +59,9 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl;
const char *template;
char *action;
u_int i, idx, cur;
u_int idx, cur;
if ((c = cmd_current_client(cmdq)) == NULL) {
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
@@ -76,25 +81,24 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
action = xstrdup("detach-client -t '%%'");
cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c1 = ARRAY_ITEM(&clients, i);
if (c1 == NULL || c1->session == NULL || c1->tty.path == NULL)
TAILQ_FOREACH(c1, &clients, entry) {
if (c1->session == NULL || c1->tty.path == NULL)
continue;
if (c1 == cmdq->client)
cur = idx;
idx++;
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->idx = i;
cdata->idx = idx;
cdata->ft_template = xstrdup(template);
format_add(cdata->ft, "line", "%u", i);
format_session(cdata->ft, c1->session);
format_client(cdata->ft, c1);
format_add(cdata->ft, "line", "%u", idx);
format_defaults(cdata->ft, c1, NULL, NULL, NULL);
cdata->command = cmd_template_replace(action, c1->tty.path, 1);
window_choose_add(wl->window->active, cdata);
idx++;
}
free(action);
@@ -108,15 +112,19 @@ void
cmd_choose_client_callback(struct window_choose_data *cdata)
{
struct client *c;
u_int idx;
if (cdata == NULL)
return;
if (cdata->start_client->flags & CLIENT_DEAD)
return;
if (cdata->idx > ARRAY_LENGTH(&clients) - 1)
return;
c = ARRAY_ITEM(&clients, cdata->idx);
idx = 0;
TAILQ_FOREACH(c, &clients, entry) {
if (idx == cdata->idx)
break;
idx++;
}
if (c == NULL || c->session == NULL)
return;

View File

@@ -1,97 +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_q *);
const struct cmd_entry cmd_choose_list_entry = {
"choose-list", NULL,
"l:t:", 0, 1,
"[-l items] " CMD_TARGET_WINDOW_USAGE "[template]",
0,
NULL,
cmd_choose_list_exec
};
enum cmd_retval
cmd_choose_list_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct winlink *wl;
const char *list1;
char *template, *item, *copy, *list;
u_int idx;
if ((c = cmd_current_client(cmdq)) == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
if ((list1 = args_get(args, 'l')) == NULL)
return (CMD_RETURN_ERROR);
if ((wl = cmd_find_window(cmdq, 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, c, 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, NULL);
free(template);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
@@ -32,6 +32,15 @@
* Enter choice mode to choose a session and/or window.
*/
#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}\""
enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_choose_tree_entry = {
@@ -40,7 +49,6 @@ const struct cmd_entry cmd_choose_tree_entry = {
"[-suw] [-b session-template] [-c window template] [-S format] " \
"[-W format] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
cmd_choose_tree_exec
};
@@ -49,7 +57,6 @@ const struct cmd_entry cmd_choose_session_entry = {
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0,
NULL,
cmd_choose_tree_exec
};
@@ -58,7 +65,6 @@ const struct cmd_entry cmd_choose_window_entry = {
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
0,
NULL,
cmd_choose_tree_exec
};
@@ -81,7 +87,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq)
ses_template = win_template = NULL;
ses_action = win_action = NULL;
if ((c = cmd_current_client(cmdq)) == NULL) {
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,6 @@ const struct cmd_entry cmd_clear_history_entry = {
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
0,
NULL,
cmd_clear_history_exec
};
@@ -46,8 +45,9 @@ cmd_clear_history_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy);
gd->hsize = 0;
if (wp->mode == &window_copy_mode)
window_pane_reset_mode(wp);
grid_clear_history(gd);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,50 +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"
/*
* Enter clock mode.
*/
enum cmd_retval cmd_clock_mode_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
0,
NULL,
cmd_clock_mode_exec
};
enum cmd_retval
cmd_clock_mode_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct window_pane *wp;
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
window_pane_set_mode(wp, &window_clock_mode);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,6 @@
* Prompt for command in client.
*/
void cmd_command_prompt_key_binding(struct cmd *, int);
enum cmd_retval cmd_command_prompt_exec(struct cmd *, struct cmd_q *);
int cmd_command_prompt_callback(void *, const char *);
@@ -40,7 +39,6 @@ const struct cmd_entry cmd_command_prompt_entry = {
"I:p:t:", 0, 1,
"[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
0,
cmd_command_prompt_key_binding,
cmd_command_prompt_exec
};
@@ -54,34 +52,6 @@ struct cmd_command_prompt_cdata {
int idx;
};
void
cmd_command_prompt_key_binding(struct cmd *self, int key)
{
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_q *cmdq)
{
@@ -181,7 +151,7 @@ cmd_command_prompt_callback(void *data, const char *s)
return (0);
}
cmdq_run(c->cmdq, cmdlist);
cmdq_run(c->cmdq, cmdlist, NULL);
cmd_list_free(cmdlist);
if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* 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.
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
@@ -26,7 +28,6 @@
* Asks for confirmation before executing a command.
*/
void cmd_confirm_before_key_binding(struct cmd *, int);
enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmd_q *);
int cmd_confirm_before_callback(void *, const char *);
@@ -37,7 +38,6 @@ const struct cmd_entry cmd_confirm_before_entry = {
"p:t:", 1, 1,
"[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
0,
cmd_confirm_before_key_binding,
cmd_confirm_before_exec
};
@@ -46,24 +46,6 @@ struct cmd_confirm_before_data {
struct client *client;
};
void
cmd_confirm_before_key_binding(struct cmd *self, int key)
{
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_q *cmdq)
{
@@ -123,7 +105,7 @@ cmd_confirm_before_callback(void *data, const char *s)
return (0);
}
cmdq_run(c->cmdq, cmdlist);
cmdq_run(c->cmdq, cmdlist, NULL);
cmd_list_free(cmdlist);
return (0);
@@ -135,7 +117,7 @@ cmd_confirm_before_free(void *data)
struct cmd_confirm_before_data *cdata = data;
struct client *c = cdata->client;
c->references--;
server_client_unref(c);
free(cdata->cmd);
free(cdata);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -21,42 +21,57 @@
#include "tmux.h"
/*
* Enter copy mode.
* Enter copy or clock mode.
*/
void cmd_copy_mode_key_binding(struct cmd *, int);
enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
"t:u", 0, 0,
"[-u] " CMD_TARGET_PANE_USAGE,
"Met:u", 0, 0,
"[-Meu] " CMD_TARGET_PANE_USAGE,
0,
cmd_copy_mode_key_binding,
cmd_copy_mode_exec
};
void
cmd_copy_mode_key_binding(struct cmd *self, int key)
{
self->args = args_create(0);
if (key == KEYC_PPAGE)
args_set(self->args, 'u', NULL);
}
const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
0,
cmd_copy_mode_exec
};
enum cmd_retval
cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c = cmdq->client;
struct session *s;
struct window_pane *wp;
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
if (args_has(args, 'M')) {
if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL)
return (CMD_RETURN_NORMAL);
if (c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
} else if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
if (self->entry == &cmd_clock_mode_entry) {
window_pane_set_mode(wp, &window_clock_mode);
return (CMD_RETURN_NORMAL);
}
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);
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, &cmdq->item->mouse);
}
if (wp->mode == &window_copy_mode && args_has(self->args, 'u'))
window_copy_pageup(wp);

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"
/*
* Delete a paste buffer.
*/
enum cmd_retval cmd_delete_buffer_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb",
"b:", 0, 0,
CMD_BUFFER_USAGE,
0,
NULL,
cmd_delete_buffer_exec
};
enum cmd_retval
cmd_delete_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
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) {
cmdq_error(cmdq, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
if (paste_free_index(&global_buffers, buffer) != 0) {
cmdq_error(cmdq, "no buffer %d", buffer);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,14 @@ const struct cmd_entry cmd_detach_client_entry = {
"as:t:P", 0, 0,
"[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
CMD_READONLY,
NULL,
cmd_detach_client_exec
};
const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
cmd_detach_client_exec
};
@@ -41,10 +48,18 @@ enum cmd_retval
cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c, *c2;
struct client *c, *cloop;
struct session *s;
enum msgtype msgtype;
u_int i;
if (self->entry == &cmd_suspend_client_entry) {
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == 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);
}
if (args_has(args, 'P'))
msgtype = MSG_DETACHKILL;
@@ -56,33 +71,32 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
if (s == NULL)
return (CMD_RETURN_ERROR);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
TAILQ_FOREACH(cloop, &clients, entry) {
if (cloop->session != s)
continue;
server_write_client(c, msgtype, c->session->name,
strlen(c->session->name) + 1);
}
} else {
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
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 || c2->session == NULL ||
c2 == c)
continue;
server_write_client(c2, msgtype,
c2->session->name,
strlen(c2->session->name) + 1);
}
} else {
server_write_client(c, msgtype, c->session->name,
strlen(c->session->name) + 1);
server_write_client(cloop, msgtype,
cloop->session->name,
strlen(cloop->session->name) + 1);
}
return (CMD_RETURN_STOP);
}
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
if (c == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'a')) {
TAILQ_FOREACH(cloop, &clients, entry) {
if (cloop->session == NULL || cloop == c)
continue;
server_write_client(cloop, msgtype,
cloop->session->name,
strlen(cloop->session->name) + 1);
}
return (CMD_RETURN_NORMAL);
}
server_write_client(c, msgtype, c->session->name,
strlen(c->session->name) + 1);
return (CMD_RETURN_STOP);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -27,6 +27,11 @@
* Displays a message in the status line.
*/
#define DISPLAY_MESSAGE_TEMPLATE \
"[#{session_name}] #{window_index}:" \
"#{window_name}, current pane #{pane_index} " \
"- (%H:%M %d-%b-%y)"
enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_display_message_entry = {
@@ -35,7 +40,6 @@ const struct cmd_entry cmd_display_message_entry = {
"[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE
" [message]",
0,
NULL,
cmd_display_message_exec
};
@@ -74,7 +78,7 @@ cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq)
if (c == NULL)
return (CMD_RETURN_ERROR);
} else {
c = cmd_current_client(cmdq);
c = cmd_find_client(cmdq, NULL, 1);
if (c == NULL && !args_has(self->args, 'p')) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
@@ -88,11 +92,7 @@ cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq)
template = DISPLAY_MESSAGE_TEMPLATE;
ft = format_create();
if (c != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wp);
format_defaults(ft, c, s, wl, wp);
t = time(NULL);
len = strftime(out, sizeof out, template, localtime(&t));

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,6 @@ const struct cmd_entry cmd_display_panes_entry = {
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
NULL,
cmd_display_panes_exec
};

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,6 +28,11 @@
* Find window containing text.
*/
#define FIND_WINDOW_TEMPLATE \
"#{window_index}: #{window_name} " \
"[#{window_width}x#{window_height}] " \
"(#{window_panes} panes) #{window_find_matches}"
enum cmd_retval cmd_find_window_exec(struct cmd *, struct cmd_q *);
void cmd_find_window_callback(struct window_choose_data *);
@@ -47,7 +52,6 @@ const struct cmd_entry cmd_find_window_entry = {
"F:CNt:T", 1, 4,
"[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
0,
NULL,
cmd_find_window_exec
};
@@ -55,11 +59,12 @@ struct cmd_find_window_data {
struct winlink *wl;
char *list_ctx;
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 *);
void cmd_find_window_match(struct cmd_find_window_data_list *, int,
void cmd_find_window_match(struct cmd_find_window_list *, int,
struct winlink *, const char *, const char *);
u_int
@@ -83,15 +88,16 @@ cmd_find_window_match_flags(struct args *args)
}
void
cmd_find_window_match(struct cmd_find_window_data_list *find_list,
int match_flags, struct winlink *wl, const char *str, const char *searchstr)
cmd_find_window_match(struct cmd_find_window_list *find_list,
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;
u_int i, line;
char *sres;
memset(&find_data, 0, sizeof find_data);
find_data = xcalloc(1, sizeof *find_data);
i = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
@@ -99,30 +105,32 @@ cmd_find_window_match(struct cmd_find_window_data_list *find_list,
if ((match_flags & CMD_FIND_WINDOW_BY_NAME) &&
fnmatch(searchstr, wl->window->name, 0) == 0) {
find_data.list_ctx = xstrdup("");
find_data->list_ctx = xstrdup("");
break;
}
if ((match_flags & CMD_FIND_WINDOW_BY_TITLE) &&
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);
break;
}
if (match_flags & CMD_FIND_WINDOW_BY_CONTENT &&
(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);
free(sres);
break;
}
}
if (find_data.list_ctx != NULL) {
find_data.wl = wl;
find_data.pane_id = i - 1;
ARRAY_ADD(find_list, find_data);
}
if (find_data->list_ctx != NULL) {
find_data->wl = wl;
find_data->pane_id = i - 1;
TAILQ_INSERT_TAIL(find_list, find_data, entry);
} else
free(find_data);
}
enum cmd_retval
@@ -133,12 +141,14 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window_choose_data *cdata;
struct session *s;
struct winlink *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;
const char *template;
u_int i, match_flags;
if ((c = cmd_current_client(cmdq)) == NULL) {
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
@@ -153,21 +163,20 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
match_flags = cmd_find_window_match_flags(args);
str = args->argv[0];
ARRAY_INIT(&find_list);
TAILQ_INIT(&find_list);
xasprintf(&searchstr, "*%s*", str);
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);
if (ARRAY_LENGTH(&find_list) == 0) {
if (TAILQ_EMPTY(&find_list)) {
cmdq_error(cmdq, "no windows matching: %s", str);
ARRAY_FREE(&find_list);
return (CMD_RETURN_ERROR);
}
if (ARRAY_LENGTH(&find_list) == 1) {
if (session_select(s, ARRAY_FIRST(&find_list).wl->idx) == 0)
if (TAILQ_NEXT(TAILQ_FIRST(&find_list), entry) == NULL) {
if (session_select(s, TAILQ_FIRST(&find_list)->wl->idx) == 0)
server_redraw_session(s);
recalculate_sizes();
goto out;
@@ -176,30 +185,33 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
goto out;
for (i = 0; i < ARRAY_LENGTH(&find_list); i++) {
wm = ARRAY_ITEM(&find_list, i).wl;
i = 0;
TAILQ_FOREACH(find_data, &find_list, entry) {
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->idx = wm->idx;
cdata->wl = wm;
cdata->idx = find_data->wl->idx;
cdata->wl = find_data->wl;
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, "window_find_matches", "%s",
ARRAY_ITEM(&find_list, i).list_ctx);
format_session(cdata->ft, s);
format_winlink(cdata->ft, s, wm);
format_window_pane(cdata->ft, wm->window->active);
find_data->list_ctx);
format_defaults(cdata->ft, NULL, s, find_data->wl, NULL);
window_choose_add(wl->window->active, cdata);
i++;
}
window_choose_ready(wl->window->active, 0, cmd_find_window_callback);
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);
}

1228
cmd-find.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,47 +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"
/*
* Cause client to report an error and exit with 1 if session doesn't exist.
*/
enum cmd_retval cmd_has_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
0,
NULL,
cmd_has_session_exec
};
enum cmd_retval
cmd_has_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
return (CMD_RETURN_ERROR);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -37,19 +37,21 @@ void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"bt:", 2, 3,
"[-b] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
"bFt:", 2, 3,
"[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
0,
NULL,
cmd_if_shell_exec
};
struct cmd_if_shell_data {
char *cmd_if;
char *cmd_else;
struct cmd_q *cmdq;
int bflag;
int started;
char *cmd_if;
char *cmd_else;
struct cmd_q *cmdq;
struct mouse_event mouse;
int bflag;
int references;
};
enum cmd_retval
@@ -57,47 +59,75 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct cmd_if_shell_data *cdata;
char *shellcmd;
char *shellcmd, *cmd, *cause;
struct cmd_list *cmdlist;
struct client *c;
struct session *s = NULL;
struct winlink *wl = NULL;
struct window_pane *wp = NULL;
struct format_tree *ft;
int cwd;
if (args_has(args, 't'))
if (args_has(args, 't')) {
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
else {
cwd = wp->cwd;
} else {
c = cmd_find_client(cmdq, NULL, 1);
if (c != NULL && c->session != NULL) {
s = c->session;
wl = s->curw;
wp = wl->window->active;
}
if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else if (s != NULL)
cwd = s->cwd;
else
cwd = -1;
}
ft = format_create();
if (s != NULL)
format_session(ft, s);
if (s != NULL && wl != NULL)
format_winlink(ft, s, wl);
if (wp != NULL)
format_window_pane(ft, wp);
format_defaults(ft, NULL, s, wl, wp);
shellcmd = format_expand(ft, args->argv[0]);
format_free(ft);
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];
if (cmd == NULL)
return (CMD_RETURN_NORMAL);
if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
if (cause != NULL) {
cmdq_error(cmdq, "%s", cause);
free(cause);
}
return (CMD_RETURN_ERROR);
}
cmdq_run(cmdq, cmdlist, &cmdq->item->mouse);
cmd_list_free(cmdlist);
return (CMD_RETURN_NORMAL);
}
cdata = xmalloc(sizeof *cdata);
cdata->cmd_if = xstrdup(args->argv[1]);
if (args->argc == 3)
cdata->cmd_else = xstrdup(args->argv[2]);
else
cdata->cmd_else = NULL;
cdata->bflag = args_has(args, 'b');
cdata->started = 0;
cdata->cmdq = cmdq;
memcpy(&cdata->mouse, &cmdq->item->mouse, sizeof cdata->mouse);
cmdq->references++;
job_run(shellcmd, s, cmd_if_shell_callback, cmd_if_shell_free, cdata);
cdata->references = 1;
job_run(shellcmd, s, cwd, cmd_if_shell_callback, cmd_if_shell_free,
cdata);
free(shellcmd);
if (cdata->bflag)
@@ -113,7 +143,7 @@ cmd_if_shell_callback(struct job *job)
struct cmd_list *cmdlist;
char *cause, *cmd;
if (cmdq->dead)
if (cmdq->flags & CMD_Q_DEAD)
return;
if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
@@ -131,13 +161,12 @@ cmd_if_shell_callback(struct job *job)
return;
}
cdata->started = 1;
cmdq1 = cmdq_new(cmdq->client);
cmdq1->emptyfn = cmd_if_shell_done;
cmdq1->data = cdata;
cmdq_run(cmdq1, cmdlist);
cdata->references++;
cmdq_run(cmdq1, cmdlist, &cdata->mouse);
cmd_list_free(cmdlist);
}
@@ -149,12 +178,14 @@ cmd_if_shell_done(struct cmd_q *cmdq1)
if (cmdq1->client_exit >= 0)
cmdq->client_exit = cmdq1->client_exit;
cmdq_free(cmdq1);
if (--cdata->references != 0)
return;
if (!cmdq_free(cmdq) && !cdata->bflag)
cmdq_continue(cmdq);
cmdq_free(cmdq1);
free(cdata->cmd_else);
free(cdata->cmd_if);
free(cdata);
@@ -166,7 +197,7 @@ cmd_if_shell_free(void *data)
struct cmd_if_shell_data *cdata = data;
struct cmd_q *cmdq = cdata->cmdq;
if (cdata->started)
if (--cdata->references != 0)
return;
if (!cmdq_free(cmdq) && !cdata->bflag)

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2011 George Nachman <tmux@georgester.com>
@@ -28,7 +28,6 @@
* Join or move a pane into another (like split/swap/kill).
*/
void cmd_join_pane_key_binding(struct cmd *, int);
enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmd_q *);
enum cmd_retval join_pane(struct cmd *, struct cmd_q *, int);
@@ -36,35 +35,19 @@ enum cmd_retval join_pane(struct cmd *, struct cmd_q *, int);
const struct cmd_entry cmd_join_pane_entry = {
"join-pane", "joinp",
"bdhvp:l:s:t:", 0, 0,
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
"[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
0,
cmd_join_pane_key_binding,
cmd_join_pane_exec
};
const struct cmd_entry cmd_move_pane_entry = {
"move-pane", "movep",
"bdhvp:l:s:t:", 0, 0,
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
"[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
0,
NULL,
cmd_join_pane_exec
};
void
cmd_join_pane_key_binding(struct cmd *self, int key)
{
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_q *cmdq)
{
@@ -91,7 +74,7 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
dst_idx = dst_wl->idx;
server_unzoom_window(dst_w);
src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL, &src_wp);
if (src_wl == NULL)
return (CMD_RETURN_ERROR);
src_w = src_wl->window;
@@ -138,11 +121,7 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
layout_close_pane(src_wp);
if (src_w->active == 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);
}
window_lost_pane(src_w, src_wp);
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
if (window_count_panes(src_w) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,6 @@ const struct cmd_entry cmd_kill_pane_entry = {
"at:", 0, 0,
"[-a] " CMD_TARGET_PANE_USAGE,
0,
NULL,
cmd_kill_pane_exec
};

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,6 @@ const struct cmd_entry cmd_kill_server_entry = {
"", 0, 0,
"",
0,
NULL,
cmd_kill_server_exec
};
@@ -43,7 +42,6 @@ const struct cmd_entry cmd_start_server_entry = {
"", 0, 0,
"",
CMD_STARTSERVER,
NULL,
cmd_kill_server_exec
};

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,6 @@ const struct cmd_entry cmd_kill_session_entry = {
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
0,
NULL,
cmd_kill_session_exec
};
@@ -42,16 +41,16 @@ enum cmd_retval
cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s, *s2, *s3;
struct session *s, *sloop, *stmp;
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'a')) {
RB_FOREACH_SAFE(s2, sessions, &sessions, s3) {
if (s != s2) {
server_destroy_session(s2);
session_destroy(s2);
RB_FOREACH_SAFE(sloop, sessions, &sessions, stmp) {
if (sloop != s) {
server_destroy_session(sloop);
session_destroy(sloop);
}
}
} else {

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,14 @@ const struct cmd_entry cmd_kill_window_entry = {
"at:", 0, 0,
"[-a] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
cmd_kill_window_exec
};
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
"kt:", 0, 0,
"[-k] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_kill_window_exec
};
@@ -40,18 +47,28 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl, *wl2, *wl3;
struct window *w;
struct session *s;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (args_has(args, 'a')) {
RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
if (wl != wl2)
server_kill_window(wl2->window);
if (self->entry == &cmd_unlink_window_entry) {
if (!args_has(self->args, 'k') && !session_is_linked(s, w)) {
cmdq_error(cmdq, "window only linked to one session");
return (CMD_RETURN_ERROR);
}
} else
server_kill_window(wl->window);
server_unlink_window(s, wl);
} 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();
return (CMD_RETURN_NORMAL);

View File

@@ -1,64 +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_q *);
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"dks:t:", 0, 0,
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0,
NULL,
cmd_link_window_exec
};
enum cmd_retval
cmd_link_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *src, *dst;
struct winlink *wl;
char *cause;
int idx, kflag, dflag;
if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL)
return (CMD_RETURN_ERROR);
if ((idx = cmd_find_index(cmdq, 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) {
cmdq_error(cmdq, "can't link window: %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
recalculate_sizes();
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,6 +27,9 @@
* List paste buffers.
*/
#define LIST_BUFFERS_TEMPLATE \
"#{buffer_name}: #{buffer_size} bytes: \"#{buffer_sample}\""
enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_buffers_entry = {
@@ -34,7 +37,6 @@ const struct cmd_entry cmd_list_buffers_entry = {
"F:", 0, 0,
"[-F format]",
0,
NULL,
cmd_list_buffers_exec
};
@@ -44,18 +46,16 @@ cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args;
struct paste_buffer *pb;
struct format_tree *ft;
u_int idx;
char *line;
const char *template;
if ((template = args_get(args, 'F')) == NULL)
template = LIST_BUFFERS_TEMPLATE;
idx = 0;
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
pb = NULL;
while ((pb = paste_walk(pb)) != NULL) {
ft = format_create();
format_add(ft, "line", "%u", idx - 1);
format_paste_buffer(ft, pb);
format_defaults_paste_buffer(ft, pb, 0);
line = format_expand(ft, template);
cmdq_print(cmdq, "%s", line);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,6 +28,11 @@
* List all clients.
*/
#define LIST_CLIENTS_TEMPLATE \
"#{client_tty}: #{session_name} " \
"[#{client_width}x#{client_height} #{client_termname}]" \
"#{?client_utf8, (utf8),} #{?client_readonly, (ro),}"
enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_clients_entry = {
@@ -35,7 +40,6 @@ const struct cmd_entry cmd_list_clients_entry = {
"F:t:", 0, 0,
"[-F format] " CMD_TARGET_SESSION_USAGE,
CMD_READONLY,
NULL,
cmd_list_clients_exec
};
@@ -47,7 +51,7 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
struct session *s;
struct format_tree *ft;
const char *template;
u_int i;
u_int idx;
char *line;
if (args_has(args, 't')) {
@@ -60,24 +64,22 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
if ((template = args_get(args, 'F')) == NULL)
template = LIST_CLIENTS_TEMPLATE;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (s != NULL && s != c->session)
idx = 0;
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == NULL || (s != NULL && s != c->session))
continue;
ft = format_create();
format_add(ft, "line", "%u", i);
format_session(ft, c->session);
format_client(ft, c);
format_add(ft, "line", "%u", idx);
format_defaults(ft, c, NULL, NULL, NULL);
line = format_expand(ft, template);
cmdq_print(cmdq, "%s", line);
free(line);
format_free(ft);
idx++;
}
return (CMD_RETURN_NORMAL);

View File

@@ -1,54 +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"
/*
* List all commands with usages.
*/
enum cmd_retval cmd_list_commands_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm",
"", 0, 0,
"",
0,
NULL,
cmd_list_commands_exec
};
enum cmd_retval
cmd_list_commands_exec(unused struct cmd *self, struct cmd_q *cmdq)
{
const struct cmd_entry **entryp;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
if ((*entryp)->alias != NULL) {
cmdq_print(cmdq, "%s (%s) %s", (*entryp)->name,
(*entryp)->alias, (*entryp)->usage);
} else {
cmdq_print(cmdq, "%s %s", (*entryp)->name,
(*entryp)->usage);
}
}
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,14 +27,23 @@
*/
enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_list_keys_commands(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk",
"t:", 0, 0,
"[-t key-table]",
"t:T:", 0, 0,
"[-t mode-table] [-T key-table]",
0,
cmd_list_keys_exec
};
const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm",
"", 0, 0,
"",
0,
NULL,
cmd_list_keys_exec
};
@@ -42,55 +51,70 @@ enum cmd_retval
cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct key_table *table;
struct key_binding *bd;
const char *key;
char tmp[BUFSIZ], flags[8];
const char *key, *tablename, *r;
char tmp[BUFSIZ];
size_t used;
int width, keywidth;
int repeat, width, tablewidth, keywidth;
if (self->entry == &cmd_list_commands_entry)
return (cmd_list_keys_commands(self, cmdq));
if (args_has(args, 't'))
return (cmd_list_keys_table(self, cmdq));
width = 0;
RB_FOREACH(bd, key_bindings, &key_bindings) {
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;
tablename = args_get(args, 'T');
if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
cmdq_error(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
RB_FOREACH(bd, key_bindings, &key_bindings) {
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
repeat = 0;
tablewidth = keywidth = 0;
RB_FOREACH(table, key_tables, &key_tables) {
if (tablename != NULL && strcmp(table->name, tablename) != 0)
continue;
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
key = key_string_lookup_key(bd->key);
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 ");
repeat = 1;
used = xsnprintf(tmp, sizeof tmp, "%s%*s ",
flags, (int) (width - strlen(flags)), key);
if (used >= sizeof tmp)
width = strlen(table->name);
if (width > tablewidth)
tablewidth =width;
width = strlen(key);
if (width > keywidth)
keywidth = width;
}
}
RB_FOREACH(table, key_tables, &key_tables) {
if (tablename != NULL && strcmp(table->name, tablename) != 0)
continue;
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
key = key_string_lookup_key(bd->key);
if (key == NULL)
continue;
cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
cmdq_print(cmdq, "bind-key %s", tmp);
if (!repeat)
r = "";
else if (bd->can_repeat)
r = "-r ";
else
r = " ";
used = xsnprintf(tmp, sizeof tmp, "%s-T %-*s %-*s ", r,
(int)tablewidth, table->name, (int)keywidth, key);
if (used < sizeof tmp) {
cmd_list_print(bd->cmdlist, tmp + used,
(sizeof tmp) - used);
}
cmdq_print(cmdq, "bind-key %s", tmp);
}
}
return (CMD_RETURN_NORMAL);
@@ -148,3 +172,22 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_list_keys_commands(unused struct cmd *self, struct cmd_q *cmdq)
{
const struct cmd_entry **entryp;
const struct cmd_entry *entry;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
entry = *entryp;
if (entry->alias == NULL) {
cmdq_print(cmdq, "%s %s", entry->name, entry->usage);
continue;
}
cmdq_print(cmdq, "%s (%s) %s", entry->name, entry->alias,
entry->usage);
}
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,7 +19,6 @@
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
@@ -30,17 +29,16 @@
enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmd_q *);
void cmd_list_panes_server(struct cmd *, struct cmd_q *);
void cmd_list_panes_session(
struct cmd *, struct session *, struct cmd_q *, int);
void cmd_list_panes_window(struct cmd *,
struct session *, struct winlink *, struct cmd_q *, int);
void cmd_list_panes_session(struct cmd *, struct session *, struct cmd_q *,
int);
void cmd_list_panes_window(struct cmd *, struct session *, struct winlink *,
struct cmd_q *, int);
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
"asF:t:", 0, 0,
"[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
cmd_list_panes_exec
};
@@ -78,8 +76,8 @@ cmd_list_panes_server(struct cmd *self, struct cmd_q *cmdq)
}
void
cmd_list_panes_session(
struct cmd *self, struct session *s, struct cmd_q *cmdq, int type)
cmd_list_panes_session(struct cmd *self, struct session *s, struct cmd_q *cmdq,
int type)
{
struct winlink *wl;
@@ -88,8 +86,8 @@ cmd_list_panes_session(
}
void
cmd_list_panes_window(struct cmd *self,
struct session *s, struct winlink *wl, struct cmd_q *cmdq, int type)
cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl,
struct cmd_q *cmdq, int type)
{
struct args *args = self->args;
struct window_pane *wp;
@@ -116,9 +114,9 @@ cmd_list_panes_window(struct cmd *self,
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
break;
case 2:
template = "#{session_name}:#{window_index}.#{pane_index}: "
"[#{pane_width}x#{pane_height}] [history "
"#{history_size}/#{history_limit}, "
template = "#{session_name}:#{window_index}."
"#{pane_index}: [#{pane_width}x#{pane_height}] "
"[history #{history_size}/#{history_limit}, "
"#{history_bytes} bytes] #{pane_id}"
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
break;
@@ -129,9 +127,7 @@ cmd_list_panes_window(struct cmd *self,
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
ft = format_create();
format_add(ft, "line", "%u", n);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wp);
format_defaults(ft, NULL, s, wl, wp);
line = format_expand(ft, template);
cmdq_print(cmdq, "%s", line);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,6 +28,14 @@
* List all sessions.
*/
#define LIST_SESSIONS_TEMPLATE \
"#{session_name}: #{session_windows} windows " \
"(created #{session_created_string}) " \
"[#{session_width}x#{session_height}]" \
"#{?session_grouped, (group ,}" \
"#{session_group}#{?session_grouped,),}" \
"#{?session_attached, (attached),}"
enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_sessions_entry = {
@@ -35,7 +43,6 @@ const struct cmd_entry cmd_list_sessions_entry = {
"F:", 0, 0,
"[-F format]",
0,
NULL,
cmd_list_sessions_exec
};
@@ -56,7 +63,7 @@ cmd_list_sessions_exec(struct cmd *self, struct cmd_q *cmdq)
RB_FOREACH(s, sessions, &sessions) {
ft = format_create();
format_add(ft, "line", "%u", n);
format_session(ft, s);
format_defaults(ft, NULL, s, NULL, NULL);
line = format_expand(ft, template);
cmdq_print(cmdq, "%s", line);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,18 +27,29 @@
* List windows on given session.
*/
#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}] "
enum cmd_retval cmd_list_windows_exec(struct cmd *, struct cmd_q *);
void cmd_list_windows_server(struct cmd *, struct cmd_q *);
void cmd_list_windows_session(
struct cmd *, struct session *, struct cmd_q *, int);
void cmd_list_windows_session(struct cmd *, struct session *,
struct cmd_q *, int);
const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw",
"F:at:", 0, 0,
"[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
0,
NULL,
cmd_list_windows_exec
};
@@ -96,9 +107,7 @@ cmd_list_windows_session(
RB_FOREACH(wl, winlinks, &s->windows) {
ft = format_create();
format_add(ft, "line", "%u", n);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wl->window->active);
format_defaults(ft, NULL, s, wl, NULL);
line = format_expand(ft, template);
cmdq_print(cmdq, "%s", line);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,7 +24,7 @@
#include "tmux.h"
struct cmd_list *
cmd_list_parse(int argc, char **argv, const char* file, u_int line,
cmd_list_parse(int argc, char **argv, const char *file, u_int line,
char **cause)
{
struct cmd_list *cmdlist;
@@ -103,7 +103,7 @@ size_t
cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
{
struct cmd *cmd;
size_t off;
size_t off, used;
off = 0;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
@@ -112,8 +112,12 @@ cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
off += cmd_print(cmd, buf + off, len - off);
if (off >= len)
break;
if (TAILQ_NEXT(cmd, qentry) != NULL)
off += xsnprintf(buf + off, len - off, " ; ");
if (TAILQ_NEXT(cmd, qentry) != NULL) {
used = xsnprintf(buf + off, len - off, " ; ");
if (used > len - off)
used = len - off;
off += used;
}
}
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -39,7 +39,6 @@ const struct cmd_entry cmd_load_buffer_entry = {
"b:", 1, 1,
CMD_BUFFER_USAGE " path",
0,
NULL,
cmd_load_buffer_exec
};
@@ -50,30 +49,19 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client;
struct session *s;
FILE *f;
const char *path;
const char *path, *bufname;
char *pdata, *new_pdata, *cause;
size_t psize;
u_int limit;
int ch, error, buffer, *buffer_ptr, cwd, fd;
int ch, error, cwd, fd;
if (!args_has(args, 'b'))
buffer = -1;
else {
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
cmdq_error(cmdq, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
}
bufname = NULL;
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
path = args->argv[0];
if (strcmp(path, "-") == 0) {
buffer_ptr = xmalloc(sizeof *buffer_ptr);
*buffer_ptr = buffer;
error = server_set_stdin_callback(c, cmd_load_buffer_callback,
buffer_ptr, &cause);
(void *)bufname, &cause);
if (error != 0) {
cmdq_error(cmdq, "%s: %s", path, cause);
free(cause);
@@ -84,7 +72,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
if (c != NULL && c->session == NULL)
cwd = c->cwd;
else if ((s = cmd_current_session(cmdq, 0)) != NULL)
else if ((s = cmd_find_current(cmdq)) != NULL)
cwd = s->cwd;
else
cwd = AT_FDCWD;
@@ -117,14 +105,10 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
fclose(f);
limit = options_get_number(&global_options, "buffer-limit");
if (buffer == -1) {
paste_add(&global_buffers, pdata, psize, limit);
return (CMD_RETURN_NORMAL);
}
if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
cmdq_error(cmdq, "no buffer %d", buffer);
if (paste_set(pdata, psize, bufname, &cause) != 0) {
cmdq_error(cmdq, "%s", cause);
free(pdata);
free(cause);
return (CMD_RETURN_ERROR);
}
@@ -140,40 +124,34 @@ error:
void
cmd_load_buffer_callback(struct client *c, int closed, void *data)
{
int *buffer = data;
char *pdata;
size_t psize;
u_int limit;
const char *bufname = data;
char *pdata, *cause;
size_t psize;
if (!closed)
return;
c->stdin_callback = NULL;
c->references--;
server_client_unref(c);
if (c->flags & CLIENT_DEAD)
return;
psize = EVBUFFER_LENGTH(c->stdin_data);
if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) {
free(data);
if (psize == 0 || (pdata = malloc(psize + 1)) == NULL)
goto out;
}
memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize);
pdata[psize] = '\0';
evbuffer_drain(c->stdin_data, psize);
limit = options_get_number(&global_options, "buffer-limit");
if (*buffer == -1)
paste_add(&global_buffers, pdata, psize, limit);
else if (paste_replace(&global_buffers, *buffer, pdata, psize) != 0) {
if (paste_set(pdata, psize, bufname, &cause) != 0) {
/* No context so can't use server_client_msg_error. */
evbuffer_add_printf(c->stderr_data, "no buffer %d\n", *buffer);
evbuffer_add_printf(c->stderr_data, "%s", cause);
server_push_stderr(c);
free(pdata);
free(cause);
}
free(data);
out:
cmdq_continue(c->cmdq);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,10 +18,6 @@
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
/*
@@ -35,7 +31,6 @@ const struct cmd_entry cmd_lock_server_entry = {
"", 0, 0,
"",
0,
NULL,
cmd_lock_server_exec
};
@@ -44,7 +39,6 @@ const struct cmd_entry cmd_lock_session_entry = {
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
0,
NULL,
cmd_lock_server_exec
};
@@ -53,7 +47,6 @@ const struct cmd_entry cmd_lock_client_entry = {
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
NULL,
cmd_lock_server_exec
};

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,10 +30,17 @@ enum cmd_retval cmd_move_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew",
"dkrs:t:", 0, 0,
"adkrs:t:", 0, 0,
"[-dkr] " CMD_SRCDST_WINDOW_USAGE,
0,
NULL,
cmd_move_window_exec
};
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"adks:t:", 0, 0,
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0,
cmd_move_window_exec
};
@@ -44,10 +51,11 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct session *src, *dst, *s;
struct winlink *wl;
char *cause;
int idx, kflag, dflag;
int idx, kflag, dflag, sflag;
if (args_has(args, 'r')) {
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
session_renumber_windows(s);
@@ -63,12 +71,33 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
kflag = args_has(self->args, 'k');
dflag = args_has(self->args, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
cmdq_error(cmdq, "can't move window: %s", cause);
sflag = args_has(self->args, 's');
if (args_has(self->args, 'a')) {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
if ((idx = winlink_shuffle_up(s, s->curw)) == -1)
return (CMD_RETURN_ERROR);
}
if (server_link_window(src, wl, dst, idx, kflag, !dflag,
&cause) != 0) {
cmdq_error(cmdq, "can't link window: %s", cause);
free(cause);
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();
return (CMD_RETURN_NORMAL);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,7 +20,6 @@
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
@@ -32,16 +31,25 @@
* Create a new session and attach to the current terminal unless -d is given.
*/
#define NEW_SESSION_TEMPLATE "#{session_name}:"
enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"Ac:dDF:n:Ps:t:x:y:", 0, 1,
"[-AdDP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] [-y height] "
"[command]",
CMD_STARTSERVER|CMD_CANTNEST,
NULL,
"Ac:dDEF:n:Ps:t:x:y:", 0, -1,
"[-AdDEP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
"[-y height] [command]",
CMD_STARTSERVER,
cmd_new_session_exec
};
const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
0,
cmd_new_session_exec
};
@@ -55,10 +63,19 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
struct environ env;
struct termios tio, *tiop;
const char *newname, *target, *update, *errstr, *template;
char *cmd, *cause, *cp;
const char *path;
char **argv, *cmd, *cause, *cp;
int detached, already_attached, idx, cwd, fd = -1;
int argc;
u_int sx, sy;
struct format_tree *ft;
struct environ_entry *envent;
if (self->entry == &cmd_has_session_entry) {
if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
return (CMD_RETURN_ERROR);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
cmdq_error(cmdq, "command or window name given with target");
@@ -74,7 +91,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (session_find(newname) != NULL) {
if (args_has(args, 'A')) {
return (cmd_attach_session(cmdq, newname,
args_has(args, 'D'), 0, NULL));
args_has(args, 'D'), 0, NULL,
args_has(args, 'E')));
}
cmdq_error(cmdq, "duplicate session: %s", newname);
return (CMD_RETURN_ERROR);
@@ -102,8 +120,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
/* Get the new session working directory. */
if (args_has(args, 'c')) {
ft = format_create();
if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c0);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL,
NULL);
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
@@ -120,7 +138,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
cwd = fd;
} else if (c != NULL && c->session == NULL)
cwd = c->cwd;
else if ((c0 = cmd_current_client(cmdq)) != NULL)
else if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
cwd = c0->session->cwd;
else {
fd = open(".", O_RDONLY);
@@ -128,15 +146,20 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
}
/*
* Save the termios settings, part of which is used for new windows in
* this session.
* If this is a new client, check for nesting and save the termios
* 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
* detached, tty_open won't be called. Because of this, it must be done
* before opening the terminal as that calls tcsetattr() to prepare for
* tmux taking over.
* tcgetattr() is used rather than using tty.tio since if the client is
* detached, tty_open won't be called. It must be done before opening
* the terminal as that calls tcsetattr() to prepare for tmux taking
* over.
*/
if (!detached && !already_attached && c->tty.fd != -1) {
if (server_client_check_nested(cmdq->client)) {
cmdq_error(cmdq, "sessions should be nested with care, "
"unset $TMUX to force");
return (CMD_RETURN_ERROR);
}
if (tcgetattr(c->tty.fd, &tio) != 0)
fatal("tcgetattr failed");
tiop = &tio;
@@ -145,7 +168,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
/* Open the terminal if necessary. */
if (!detached && !already_attached) {
if (server_client_open(c, NULL, &cause) != 0) {
if (server_client_open(c, &cause) != 0) {
cmdq_error(cmdq, "open terminal failed: %s", cause);
free(cause);
goto error;
@@ -182,22 +205,42 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
sy = 1;
/* Figure out the command for the new window. */
if (target != NULL)
cmd = NULL;
else if (args->argc != 0)
cmd = args->argv[0];
else
argc = -1;
argv = NULL;
if (target == NULL && args->argc != 0) {
argc = args->argc;
argv = args->argv;
} else if (target == NULL) {
cmd = options_get_string(&global_s_options, "default-command");
if (cmd != NULL && *cmd != '\0') {
argc = 1;
argv = &cmd;
} else {
argc = 0;
argv = NULL;
}
}
path = NULL;
if (c != NULL && c->session == NULL)
envent = environ_find(&c->environ, "PATH");
else
envent = environ_find(&global_environ, "PATH");
if (envent != NULL)
path = envent->value;
/* Construct the environment. */
environ_init(&env);
update = options_get_string(&global_s_options, "update-environment");
if (c != NULL)
if (c != NULL && !args_has(args, 'E')) {
update = options_get_string(&global_s_options,
"update-environment");
environ_update(update, &c->environ, &env);
}
/* Create the new session. */
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(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
sy, &cause);
if (s == NULL) {
cmdq_error(cmdq, "create session failed: %s", cause);
free(cause);
@@ -206,7 +249,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
environ_free(&env);
/* 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;
window_set_name(w, args_get(args, 'n'));
options_set_number(&w->options, "automatic-rename", 0);
@@ -219,7 +262,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (groupwith != NULL) {
session_group_add(groupwith, s);
session_group_synchronize_to(s);
session_select(s, RB_ROOT(&s->windows)->idx);
session_select(s, RB_MIN(winlinks, &s->windows)->idx);
}
/*
@@ -232,8 +275,10 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
else if (c->session != NULL)
c->last_session = c->session;
c->session = s;
status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
server_redraw_client(c);
}
recalculate_sizes();
@@ -252,9 +297,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
template = NEW_SESSION_TEMPLATE;
ft = format_create();
if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c0);
format_session(ft, s);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,15 +30,16 @@
* Create a new window.
*/
#define NEW_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
enum cmd_retval cmd_new_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
"ac:dF:kn:Pt:", 0, 1,
"ac:dF:kn:Pt:", 0, -1,
"[-adkP] [-c start-directory] [-F format] [-n window-name] "
CMD_TARGET_WINDOW_USAGE " [command]",
0,
NULL,
cmd_new_window_exec
};
@@ -48,52 +49,53 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args;
struct session *s;
struct winlink *wl;
struct client *c;
const char *cmd, *template;
char *cause, *cp;
int idx, last, detached, cwd, fd = -1;
const char *cmd, *path, *template;
char **argv, *cause, *cp;
int argc, idx, detached, cwd, fd = -1;
struct format_tree *ft;
struct environ_entry *envent;
if (args_has(args, 'a')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
if (wl == NULL)
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) {
if ((idx = winlink_shuffle_up(s, wl)) == -1) {
cmdq_error(cmdq, "no free window indexes");
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(cmdq, args_get(args, 't'), &s)) == -2)
idx = cmd_find_index(cmdq, args_get(args, 't'), &s);
if (idx == -2)
return (CMD_RETURN_ERROR);
}
detached = args_has(args, 'd');
if (args->argc == 0)
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 (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
cmd = args->argv[0];
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (args_has(args, 'c')) {
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, s->curw);
format_window_pane(ft, s->curw->window->active);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
@@ -135,7 +137,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (idx == -1)
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) {
cmdq_error(cmdq, "create window failed: %s", cause);
free(cause);
@@ -152,11 +155,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
template = NEW_WINDOW_TEMPLATE;
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wl->window->active);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
NULL);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,9 +35,8 @@ void cmd_paste_buffer_filter(struct window_pane *,
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
"db:prs:t:", 0, 0,
"[-dpr] [-s separator] [-b buffer-index] " CMD_TARGET_PANE_USAGE,
"[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE,
0,
NULL,
cmd_paste_buffer_exec
};
@@ -48,36 +47,28 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct window_pane *wp;
struct session *s;
struct paste_buffer *pb;
const char *sepstr;
char *cause;
int buffer;
int pflag;
const char *sepstr, *bufname, *bufdata, *bufend, *line;
size_t seplen, bufsize;
int bracket = args_has(args, 'p');
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
return (CMD_RETURN_ERROR);
if (!args_has(args, 'b'))
buffer = -1;
else {
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
cmdq_error(cmdq, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
}
bufname = NULL;
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
if (buffer == -1)
pb = paste_get_top(&global_buffers);
if (bufname == NULL)
pb = paste_get_top(NULL);
else {
pb = paste_get_index(&global_buffers, buffer);
pb = paste_get_name(bufname);
if (pb == NULL) {
cmdq_error(cmdq, "no buffer %d", buffer);
cmdq_error(cmdq, "no buffer %s", bufname);
return (CMD_RETURN_ERROR);
}
}
if (pb != NULL) {
if (pb != NULL && ~wp->flags & PANE_INPUTOFF) {
sepstr = args_get(args, 's');
if (sepstr == NULL) {
if (args_has(args, 'r'))
@@ -85,17 +76,33 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
else
sepstr = "\r";
}
pflag = (wp->screen->mode & MODE_BRACKETPASTE);
paste_send_pane(pb, wp, sepstr, args_has(args, 'p') && pflag);
seplen = strlen(sepstr);
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 (args_has(args, 'd')) {
if (buffer == -1)
paste_free_top(&global_buffers);
else
paste_free_index(&global_buffers, buffer);
}
if (pb != NULL && args_has(args, 'd'))
paste_free(pb);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
@@ -40,7 +41,6 @@ const struct cmd_entry cmd_pipe_pane_entry = {
"ot:", 0, 1,
"[-o] " CMD_TARGET_PANE_USAGE " [command]",
0,
NULL,
cmd_pipe_pane_exec
};
@@ -49,11 +49,14 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct session *s;
struct winlink *wl;
struct window_pane *wp;
char *command;
char *cmd;
int old_fd, pipe_fd[2], null_fd;
struct format_tree *ft;
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
c = cmd_find_client(cmdq, NULL, 1);
@@ -84,10 +87,18 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
/* Expand the command. */
ft = format_create();
format_defaults(ft, c, s, wl, wp);
cmd = format_expand_time(ft, args->argv[0], time(NULL));
format_free(ft);
/* Fork the child. */
switch (fork()) {
case -1:
cmdq_error(cmdq, "fork error: %s", strerror(errno));
free(cmd);
return (CMD_RETURN_ERROR);
case 0:
/* Child process. */
@@ -109,9 +120,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
closefrom(STDERR_FILENO + 1);
command = status_replace(
c, NULL, NULL, NULL, args->argv[0], time(NULL), 0);
execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
_exit(1);
default:
/* Parent process. */
@@ -125,6 +134,8 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
bufferevent_enable(wp->pipe_event, EV_WRITE);
setblocking(wp->pipe_fd, 0);
free(cmd);
return (CMD_RETURN_NORMAL);
}
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,10 +20,13 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "tmux.h"
enum cmd_retval cmdq_continue_one(struct cmd_q *);
/* Create new command queue. */
struct cmd_q *
cmdq_new(struct client *c)
@@ -32,7 +35,7 @@ cmdq_new(struct client *c)
cmdq = xcalloc(1, sizeof *cmdq);
cmdq->references = 1;
cmdq->dead = 0;
cmdq->flags = 0;
cmdq->client = c;
cmdq->client_exit = -1;
@@ -48,8 +51,11 @@ cmdq_new(struct client *c)
int
cmdq_free(struct cmd_q *cmdq)
{
if (--cmdq->references != 0)
return (cmdq->dead);
if (--cmdq->references != 0) {
if (cmdq->flags & CMD_Q_DEAD)
return (1);
return (0);
}
cmdq_flush(cmdq);
free(cmdq);
@@ -57,7 +63,7 @@ cmdq_free(struct cmd_q *cmdq)
}
/* Show message from command. */
void printflike2
void
cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
{
struct client *c = cmdq->client;
@@ -86,55 +92,23 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
va_end(ap);
}
/* Show info from command. */
void printflike2
cmdq_info(struct cmd_q *cmdq, const char *fmt, ...)
{
struct client *c = cmdq->client;
va_list ap;
char *msg;
if (options_get_number(&global_options, "quiet"))
return;
va_start(ap, fmt);
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
} else {
xvasprintf(&msg, fmt, ap);
*msg = toupper((u_char) *msg);
status_message_set(c, "%s", msg);
free(msg);
}
va_end(ap);
}
/* Show error from command. */
void printflike2
void
cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
{
struct client *c = cmdq->client;
struct cmd *cmd = cmdq->cmd;
va_list ap;
char *msg, *cause;
char *msg;
size_t msglen;
va_start(ap, fmt);
msglen = xvasprintf(&msg, fmt, ap);
va_end(ap);
if (c == NULL) {
xasprintf(&cause, "%s:%u: %s", cmd->file, cmd->line, msg);
ARRAY_ADD(&cfg_causes, cause);
} else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
if (c == NULL)
cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
evbuffer_add(c->stderr_data, msg, msglen);
evbuffer_add(c->stderr_data, "\n", 1);
@@ -149,27 +123,24 @@ cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
}
/* Print a guard line. */
int
void
cmdq_guard(struct cmd_q *cmdq, const char *guard, int flags)
{
struct client *c = cmdq->client;
if (c == NULL)
return 0;
if (!(c->flags & CLIENT_CONTROL))
return 0;
if (c == NULL || !(c->flags & CLIENT_CONTROL))
return;
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
(long) cmdq->time, cmdq->number, flags);
server_push_stdout(c);
return 1;
}
/* Add command list to queue and begin processing if needed. */
void
cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist)
cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
{
cmdq_append(cmdq, cmdlist);
cmdq_append(cmdq, cmdlist, m);
if (cmdq->item == NULL) {
cmdq->cmd = NULL;
@@ -179,7 +150,7 @@ cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist)
/* Add command list to queue. */
void
cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist)
cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
{
struct cmd_q_item *item;
@@ -187,19 +158,54 @@ cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist)
item->cmdlist = cmdlist;
TAILQ_INSERT_TAIL(&cmdq->queue, item, qentry);
cmdlist->references++;
if (m != NULL)
memcpy(&item->mouse, m, sizeof item->mouse);
else
item->mouse.valid = 0;
}
/* Process one command. */
enum cmd_retval
cmdq_continue_one(struct cmd_q *cmdq)
{
struct cmd *cmd = cmdq->cmd;
enum cmd_retval retval;
char tmp[1024];
int flags = !!(cmd->flags & CMD_CONTROL);
cmd_print(cmd, tmp, sizeof tmp);
log_debug("cmdq %p: %s", cmdq, tmp);
cmdq->time = time(NULL);
cmdq->number++;
cmdq_guard(cmdq, "begin", flags);
retval = cmd->entry->exec(cmd, cmdq);
if (retval == CMD_RETURN_ERROR)
cmdq_guard(cmdq, "error", flags);
else
cmdq_guard(cmdq, "end", flags);
return (retval);
}
/* Continue processing command queue. Returns 1 if finishes empty. */
int
cmdq_continue(struct cmd_q *cmdq)
{
struct client *c = cmdq->client;
struct cmd_q_item *next;
enum cmd_retval retval;
int empty, guard, flags;
char s[1024];
int empty;
cmdq->references++;
notify_disable();
log_debug("continuing cmdq %p: flags=%#x, client=%d", cmdq, cmdq->flags,
c != NULL ? c->ibuf.fd : -1);
empty = TAILQ_EMPTY(&cmdq->queue);
if (empty)
goto empty;
@@ -211,28 +217,8 @@ cmdq_continue(struct cmd_q *cmdq)
cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
do {
next = TAILQ_NEXT(cmdq->item, qentry);
while (cmdq->cmd != NULL) {
cmd_print(cmdq->cmd, s, sizeof s);
log_debug("cmdq %p: %s (client %d)", cmdq, s,
cmdq->client != NULL ? cmdq->client->ibuf.fd : -1);
cmdq->time = time(NULL);
cmdq->number++;
flags = !!(cmdq->cmd->flags & CMD_CONTROL);
guard = cmdq_guard(cmdq, "begin", flags);
retval = cmdq->cmd->entry->exec(cmdq->cmd, cmdq);
if (guard) {
if (retval == CMD_RETURN_ERROR)
cmdq_guard(cmdq, "error", flags);
else
cmdq_guard(cmdq, "end", flags);
}
retval = cmdq_continue_one(cmdq);
if (retval == CMD_RETURN_ERROR)
break;
if (retval == CMD_RETURN_WAIT)
@@ -241,9 +227,9 @@ cmdq_continue(struct cmd_q *cmdq)
cmdq_flush(cmdq);
goto empty;
}
cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
}
next = TAILQ_NEXT(cmdq->item, qentry);
TAILQ_REMOVE(&cmdq->queue, cmdq->item, qentry);
cmd_list_free(cmdq->item->cmdlist);
@@ -258,11 +244,13 @@ empty:
if (cmdq->client_exit > 0)
cmdq->client->flags |= CLIENT_EXIT;
if (cmdq->emptyfn != NULL)
cmdq->emptyfn(cmdq); /* may free cmdq */
cmdq->emptyfn(cmdq);
empty = 1;
out:
notify_enable();
cmdq_free(cmdq);
return (empty);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,6 @@ const struct cmd_entry cmd_refresh_client_entry = {
"C:St:", 0, 0,
"[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
0,
NULL,
cmd_refresh_client_exec
};
@@ -67,10 +66,12 @@ cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq)
if (tty_set_size(&c->tty, w, h))
recalculate_sizes();
} else if (args_has(args, 'S')) {
status_update_jobs(c);
c->flags |= CLIENT_STATUSFORCE;
server_status_client(c);
} else
} else {
c->flags |= CLIENT_STATUSFORCE;
server_redraw_client(c);
}
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,6 @@ const struct cmd_entry cmd_rename_session_entry = {
"t:", 1, 1,
CMD_TARGET_SESSION_USAGE " new-name",
0,
NULL,
cmd_rename_session_exec
};

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,6 @@ const struct cmd_entry cmd_rename_window_entry = {
"t:", 1, 1,
CMD_TARGET_WINDOW_USAGE " new-name",
0,
NULL,
cmd_rename_window_exec
};

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,68 +26,25 @@
* Increase or decrease pane size.
*/
void cmd_resize_pane_key_binding(struct cmd *, int);
enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_q *);
void cmd_resize_pane_mouse_update(struct client *, struct mouse_event *);
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
"DLRt:Ux:y:Z", 0, 1,
"[-DLRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]",
"DLMRt:Ux:y:Z", 0, 1,
"[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE
" [adjustment]",
0,
cmd_resize_pane_key_binding,
cmd_resize_pane_exec
};
void
cmd_resize_pane_key_binding(struct cmd *self, int key)
{
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;
case 'z':
self->args = args_create(0);
args_set(self->args, 'Z', NULL);
break;
default:
self->args = args_create(0);
break;
}
}
enum cmd_retval
cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c = cmdq->client;
struct session *s;
struct winlink *wl;
struct window *w;
const char *errstr;
@@ -96,6 +53,16 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
u_int adjust;
int x, y;
if (args_has(args, 'M')) {
if (cmd_mouse_window(&cmdq->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, &cmdq->item->mouse);
return (CMD_RETURN_NORMAL);
}
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
@@ -154,3 +121,50 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
}
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);
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);
found = 1;
}
}
if (found)
server_redraw_window(wl->window);
else
c->tty.mouse_drag_update = NULL;
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,9 @@ enum cmd_retval cmd_respawn_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_respawn_pane_entry = {
"respawn-pane", "respawnp",
"kt:", 0, 1,
"kt:", 0, -1,
"[-k] " CMD_TARGET_PANE_USAGE " [command]",
0,
NULL,
cmd_respawn_pane_exec
};
@@ -48,9 +47,10 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
struct window_pane *wp;
struct session *s;
struct environ env;
const char *cmd;
const char *path;
char *cause;
u_int idx;
struct environ_entry *envent;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
@@ -59,7 +59,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
if (!args_has(self->args, 'k') && wp->fd != -1) {
if (window_pane_index(wp, &idx) != 0)
fatalx("index not found");
cmdq_error(cmdq, "pane still active: %s:%u.%u",
cmdq_error(cmdq, "pane still active: %s:%d.%u",
s->name, wl->idx, idx);
return (CMD_RETURN_ERROR);
}
@@ -73,11 +73,16 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
screen_reinit(&wp->base);
input_init(wp);
if (args->argc != 0)
cmd = args->argv[0];
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
cmd = NULL;
if (window_pane_spawn(wp, cmd, NULL, -1, &env, s->tio, &cause) != 0) {
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn pane failed: %s", cause);
free(cause);
environ_free(&env);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,9 @@ enum cmd_retval cmd_respawn_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw",
"kt:", 0, 1,
"kt:", 0, -1,
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
0,
NULL,
cmd_respawn_window_exec
};
@@ -47,8 +46,9 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window_pane *wp;
struct session *s;
struct environ env;
const char *cmd;
const char *path;
char *cause;
struct environ_entry *envent;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
@@ -75,11 +75,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
window_destroy_panes(w);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy);
if (args->argc != 0)
cmd = args->argv[0];
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
cmd = NULL;
if (window_pane_spawn(wp, cmd, NULL, -1, &env, s->tio, &cause) != 0) {
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn window failed: %s", cause);
free(cause);
environ_free(&env);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,7 +24,6 @@
* Rotate the panes in a window.
*/
void cmd_rotate_window_key_binding(struct cmd *, int);
enum cmd_retval cmd_rotate_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_rotate_window_entry = {
@@ -32,18 +31,9 @@ const struct cmd_entry cmd_rotate_window_entry = {
"Dt:U", 0, 0,
"[-DU] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_rotate_window_key_binding,
cmd_rotate_window_exec
};
void
cmd_rotate_window_key_binding(struct cmd *self, int key)
{
self->args = args_create(0);
if (key == ('o' | KEYC_ESCAPE))
args_set(self->args, 'D', NULL);
}
enum cmd_retval
cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq)
{

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -40,7 +40,6 @@ const struct cmd_entry cmd_run_shell_entry = {
"bt:", 1, 1,
"[-b] " CMD_TARGET_PANE_USAGE " shell-command",
0,
NULL,
cmd_run_shell_exec
};
@@ -81,25 +80,28 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl = NULL;
struct window_pane *wp = NULL;
struct format_tree *ft;
int cwd;
if (args_has(args, 't'))
if (args_has(args, 't')) {
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
else {
cwd = wp->cwd;
} else {
c = cmd_find_client(cmdq, NULL, 1);
if (c != NULL && c->session != NULL) {
s = c->session;
wl = s->curw;
wp = wl->window->active;
}
if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else if (s != NULL)
cwd = s->cwd;
else
cwd = -1;
}
ft = format_create();
if (s != NULL)
format_session(ft, s);
if (s != NULL && wl != NULL)
format_winlink(ft, s, wl);
if (wp != NULL)
format_window_pane(ft, wp);
format_defaults(ft, NULL, s, wl, wp);
shellcmd = format_expand(ft, args->argv[0]);
format_free(ft);
@@ -111,7 +113,8 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
cdata->cmdq = cmdq;
cmdq->references++;
job_run(shellcmd, s, cmd_run_shell_callback, cmd_run_shell_free, cdata);
job_run(shellcmd, s, cwd, cmd_run_shell_callback, cmd_run_shell_free,
cdata);
if (cdata->bflag)
return (CMD_RETURN_NORMAL);
@@ -128,7 +131,7 @@ cmd_run_shell_callback(struct job *job)
int retcode;
u_int lines;
if (cmdq->dead)
if (cmdq->flags & CMD_Q_DEAD)
return;
cmd = cdata->cmd;
@@ -161,13 +164,9 @@ cmd_run_shell_callback(struct job *job)
retcode = WTERMSIG(job->status);
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL) {
if (lines == 0)
cmdq_info(cmdq, "%s", msg);
else
cmd_run_shell_print(job, msg);
free(msg);
}
if (msg != NULL)
cmd_run_shell_print(job, msg);
free(msg);
}
void

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -38,7 +38,6 @@ const struct cmd_entry cmd_save_buffer_entry = {
"ab:", 1, 1,
"[-a] " CMD_BUFFER_USAGE " path",
0,
NULL,
cmd_save_buffer_exec
};
@@ -47,7 +46,6 @@ const struct cmd_entry cmd_show_buffer_entry = {
"b:", 0, 0,
CMD_BUFFER_USAGE,
0,
NULL,
cmd_save_buffer_exec
};
@@ -58,31 +56,26 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client;
struct session *s;
struct paste_buffer *pb;
const char *path;
char *cause, *start, *end, *msg;
size_t size, used, msglen;
int cwd, fd, buffer;
const char *path, *bufname, *bufdata, *start, *end;
char *msg;
size_t size, used, msglen, bufsize;
int cwd, fd;
FILE *f;
if (!args_has(args, 'b')) {
if ((pb = paste_get_top(&global_buffers)) == NULL) {
if ((pb = paste_get_top(NULL)) == NULL) {
cmdq_error(cmdq, "no buffers");
return (CMD_RETURN_ERROR);
}
} else {
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
cmdq_error(cmdq, "buffer %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
pb = paste_get_index(&global_buffers, buffer);
bufname = args_get(args, 'b');
pb = paste_get_name(bufname);
if (pb == NULL) {
cmdq_error(cmdq, "no buffer %d", buffer);
cmdq_error(cmdq, "no buffer %s", bufname);
return (CMD_RETURN_ERROR);
}
}
bufdata = paste_buffer_data(pb, &bufsize);
if (self->entry == &cmd_show_buffer_entry)
path = "-";
@@ -100,7 +93,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
if (c != NULL && c->session == NULL)
cwd = c->cwd;
else if ((s = cmd_current_session(cmdq, 0)) != NULL)
else if ((s = cmd_find_current(cmdq)) != NULL)
cwd = s->cwd;
else
cwd = AT_FDCWD;
@@ -111,7 +104,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
if (fd != -1)
f = fdopen(fd, "ab");
} else {
fd = openat(cwd, path, O_CREAT|O_RDWR, 0600);
fd = openat(cwd, path, O_CREAT|O_RDWR|O_TRUNC, 0600);
if (fd != -1)
f = fdopen(fd, "wb");
}
@@ -121,7 +114,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
return (CMD_RETURN_ERROR);
}
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
cmdq_error(cmdq, "%s: fwrite error", path);
fclose(f);
return (CMD_RETURN_ERROR);
@@ -131,29 +124,28 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
do_stdout:
evbuffer_add(c->stdout_data, pb->data, pb->size);
evbuffer_add(c->stdout_data, bufdata, bufsize);
server_push_stdout(c);
return (CMD_RETURN_NORMAL);
do_print:
if (pb->size > (INT_MAX / 4) - 1) {
if (bufsize > (INT_MAX / 4) - 1) {
cmdq_error(cmdq, "buffer too big");
return (CMD_RETURN_ERROR);
}
msg = NULL;
msglen = 0;
used = 0;
while (used != pb->size) {
start = pb->data + used;
end = memchr(start, '\n', pb->size - used);
while (used != bufsize) {
start = bufdata + used;
end = memchr(start, '\n', bufsize - used);
if (end != NULL)
size = end - start;
else
size = pb->size - used;
size = bufsize - used;
msglen = size * 4 + 1;
msg = xrealloc(msg, 1, msglen);
msg = xrealloc(msg, msglen);
strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
cmdq_print(cmdq, "%s", msg);

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,21 +18,21 @@
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Switch window to selected layout.
*/
void cmd_select_layout_key_binding(struct cmd *, int);
enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
"npt:", 0, 1,
"[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
"nopt:", 0, 1,
"[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
0,
cmd_select_layout_key_binding,
cmd_select_layout_exec
};
@@ -41,7 +41,6 @@ const struct cmd_entry cmd_next_layout_entry = {
"t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
0,
NULL,
cmd_select_layout_exec
};
@@ -50,83 +49,79 @@ const struct cmd_entry cmd_previous_layout_entry = {
"t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
0,
NULL,
cmd_select_layout_exec
};
void
cmd_select_layout_key_binding(struct cmd *self, int key)
{
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;
default:
self->args = args_create(0);
break;
}
}
enum cmd_retval
cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
const char *layoutname;
char *oldlayout;
int next, previous, layout;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
server_unzoom_window(wl->window);
w = wl->window;
server_unzoom_window(w);
next = self->entry == &cmd_next_layout_entry;
if (args_has(self->args, 'n'))
if (args_has(args, 'n'))
next = 1;
previous = self->entry == &cmd_previous_layout_entry;
if (args_has(self->args, 'p'))
if (args_has(args, 'p'))
previous = 1;
oldlayout = w->old_layout;
w->old_layout = layout_dump(w->layout_root);
if (next || previous) {
if (next)
layout = layout_set_next(wl->window);
layout_set_next(w);
else
layout = layout_set_previous(wl->window);
server_redraw_window(wl->window);
cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout));
return (CMD_RETURN_NORMAL);
layout_set_previous(w);
goto changed;
}
if (args->argc == 0)
layout = wl->window->lastlayout;
else
layout = layout_set_lookup(args->argv[0]);
if (layout != -1) {
layout = layout_set_select(wl->window, layout);
server_redraw_window(wl->window);
cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout));
return (CMD_RETURN_NORMAL);
}
if (args->argc != 0) {
layoutname = args->argv[0];
if (layout_parse(wl->window, layoutname) == -1) {
cmdq_error(cmdq, "can't set layout: %s", layoutname);
return (CMD_RETURN_ERROR);
if (!args_has(args, 'o')) {
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;
}
server_redraw_window(wl->window);
cmdq_info(cmdq, "arranging in: %s", layoutname);
}
if (args->argc != 0)
layoutname = args->argv[0];
else if (args_has(args, 'o'))
layoutname = oldlayout;
else
layoutname = NULL;
if (layoutname != NULL) {
if (layout_parse(w, layoutname) == -1) {
cmdq_error(cmdq, "can't set layout: %s", layoutname);
goto error;
}
goto changed;
}
free(oldlayout);
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,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,75 +24,100 @@
* Select pane.
*/
void cmd_select_pane_key_binding(struct cmd *, int);
enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
"lDLRt:U", 0, 0,
"[-lDLRU] " CMD_TARGET_PANE_USAGE,
"DdegLlMmP:Rt:U", 0, 0,
"[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE,
0,
cmd_select_pane_key_binding,
cmd_select_pane_exec
};
const struct cmd_entry cmd_last_pane_entry = {
"last-pane", "lastp",
"t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
"det:", 0, 0,
"[-de] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
cmd_select_pane_exec
};
void
cmd_select_pane_key_binding(struct cmd *self, int key)
{
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_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window_pane *wp;
struct window *w;
struct session *s;
struct window_pane *wp, *lastwp, *markedwp;
const char *style;
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
if (wl == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (wl->window->last == NULL) {
if (w->last == NULL) {
cmdq_error(cmdq, "no last pane");
return (CMD_RETURN_ERROR);
}
server_unzoom_window(wl->window);
window_set_active_pane(wl->window, wl->window->last);
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
if (args_has(self->args, 'e'))
w->last->flags &= ~PANE_INPUTOFF;
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);
}
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
server_unzoom_window(wp->window);
if (!window_pane_visible(wp)) {
cmdq_error(cmdq, "pane not visible");
return (CMD_RETURN_ERROR);
if (args_has(args, 'm') || args_has(args, 'M')) {
if (args_has(args, 'm') && !window_pane_visible(wp))
return (CMD_RETURN_NORMAL);
lastwp = marked_window_pane;
if (args_has(args, 'M') || server_is_marked(s, wl, wp))
server_clear_marked();
else
server_set_marked(s, wl, wp);
markedwp = marked_window_pane;
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, '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(cmdq, "bad style: %s", style);
return (CMD_RETURN_ERROR);
}
wp->flags |= PANE_REDRAW;
}
if (args_has(self->args, 'g'))
cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
return (CMD_RETURN_NORMAL);
}
if (args_has(self->args, 'L'))
@@ -103,14 +128,30 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
wp = window_pane_find_up(wp);
else if (args_has(self->args, 'D'))
wp = window_pane_find_down(wp);
if (wp == NULL) {
cmdq_error(cmdq, "pane not found");
return (CMD_RETURN_ERROR);
if (wp == NULL)
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);
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
if (wp == w->active)
return (CMD_RETURN_NORMAL);
server_unzoom_window(wp->window);
if (!window_pane_visible(wp)) {
cmdq_error(cmdq, "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);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,7 +26,6 @@
* Select window by index.
*/
void cmd_select_window_key_binding(struct cmd *, int);
enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_select_window_entry = {
@@ -34,7 +33,6 @@ const struct cmd_entry cmd_select_window_entry = {
"lnpTt:", 0, 0,
"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_select_window_key_binding,
cmd_select_window_exec
};
@@ -43,7 +41,6 @@ const struct cmd_entry cmd_next_window_entry = {
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
0,
cmd_select_window_key_binding,
cmd_select_window_exec
};
@@ -52,7 +49,6 @@ const struct cmd_entry cmd_previous_window_entry = {
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
0,
cmd_select_window_key_binding,
cmd_select_window_exec
};
@@ -61,24 +57,9 @@ const struct cmd_entry cmd_last_window_entry = {
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
0,
NULL,
cmd_select_window_exec
};
void
cmd_select_window_key_binding(struct cmd *self, int key)
{
char tmp[16];
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_q *cmdq)
{

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,9 @@ enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"lRt:", 0, -1,
"[-lR] " CMD_TARGET_PANE_USAGE " key ...",
"lRMt:", 0, -1,
"[-lRM] " CMD_TARGET_PANE_USAGE " key ...",
0,
NULL,
cmd_send_keys_exec
};
@@ -43,7 +42,6 @@ const struct cmd_entry cmd_send_prefix_entry = {
"2t:", 0, 0,
"[-2] " CMD_TARGET_PANE_USAGE,
0,
NULL,
cmd_send_keys_exec
};
@@ -51,12 +49,22 @@ enum cmd_retval
cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct mouse_event *m = &cmdq->item->mouse;
struct window_pane *wp;
struct session *s;
struct input_ctx *ictx;
const u_char *str;
int i, key;
if (args_has(args, 'M')) {
wp = cmd_mouse_pane(m, &s, NULL);
if (wp == NULL) {
cmdq_error(cmdq, "no mouse target");
return (CMD_RETURN_ERROR);
}
window_pane_key(wp, NULL, s, m->key, m);
return (CMD_RETURN_NORMAL);
}
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
return (CMD_RETURN_ERROR);
@@ -65,35 +73,22 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
key = options_get_number(&s->options, "prefix2");
else
key = options_get_number(&s->options, "prefix");
window_pane_key(wp, s, key);
window_pane_key(wp, NULL, s, key, NULL);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'R')) {
ictx = &wp->ictx;
memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
ictx->old_cx = 0;
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);
}
if (args_has(args, 'R'))
input_reset(wp);
for (i = 0; i < args->argc; i++) {
str = args->argv[i];
if (!args_has(args, 'l') &&
(key = key_string_lookup_string(str)) != KEYC_NONE) {
window_pane_key(wp, s, key);
window_pane_key(wp, NULL, s, key, NULL);
} else {
for (; *str != '\0'; str++)
window_pane_key(wp, s, *str);
window_pane_key(wp, NULL, s, *str, NULL);
}
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,50 +24,92 @@
#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_q *);
const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb",
"b:", 1, 1,
CMD_BUFFER_USAGE " data",
"ab:n:", 0, 1,
"[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
0,
cmd_set_buffer_exec
};
const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb",
"b:", 0, 0,
CMD_BUFFER_USAGE,
0,
NULL,
cmd_set_buffer_exec
};
enum cmd_retval
cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
u_int limit;
char *pdata, *cause;
size_t psize;
int buffer;
struct args *args = self->args;
struct paste_buffer *pb;
char *bufdata, *cause;
const char *bufname, *olddata;
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]);
psize = strlen(pdata);
if (!args_has(args, 'b')) {
paste_add(&global_buffers, pdata, psize, limit);
if (self->entry == &cmd_delete_buffer_entry) {
if (pb == NULL)
pb = paste_get_top(&bufname);
if (pb == NULL) {
cmdq_error(cmdq, "no buffer");
return (CMD_RETURN_ERROR);
}
paste_free(pb);
return (CMD_RETURN_NORMAL);
}
buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
if (cause != NULL) {
cmdq_error(cmdq, "buffer %s", cause);
free(cause);
free(pdata);
return (CMD_RETURN_ERROR);
if (args_has(args, 'n')) {
if (pb == NULL)
pb = paste_get_top(&bufname);
if (pb == NULL) {
cmdq_error(cmdq, "no buffer");
return (CMD_RETURN_ERROR);
}
if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) {
cmdq_error(cmdq, "%s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
cmdq_error(cmdq, "no buffer %d", buffer);
free(pdata);
if (args->argc != 1) {
cmdq_error(cmdq, "no data specified");
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(cmdq, "%s", cause);
free(bufdata);
free(cause);
return (CMD_RETURN_ERROR);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,6 @@ const struct cmd_entry cmd_set_environment_entry = {
"grt:u", 1, 2,
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
0,
NULL,
cmd_set_environment_exec
};

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -69,7 +69,6 @@ const struct cmd_entry cmd_set_option_entry = {
"agoqst:uw", 1, 2,
"[-agosquw] [-t target-session|target-window] option [value]",
0,
NULL,
cmd_set_option_exec
};
@@ -78,7 +77,6 @@ const struct cmd_entry cmd_set_window_option_entry = {
"agoqt:u", 1, 2,
"[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
0,
NULL,
cmd_set_option_exec
};
@@ -93,7 +91,6 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
struct options *oo;
struct window *w;
const char *optstr, *valstr;
u_int i;
/* Get the option name and value. */
optstr = args->argv[0];
@@ -113,12 +110,18 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
/* Find the option entry, try each table. */
table = oe = NULL;
if (options_table_find(optstr, &table, &oe) != 0) {
cmdq_error(cmdq, "ambiguous option: %s", optstr);
return (CMD_RETURN_ERROR);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "ambiguous option: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
if (oe == NULL) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
/* Work out the tree from the table. */
@@ -163,31 +166,33 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
} else {
if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
if (!args_has(args, 'q'))
cmdq_print(cmdq, "already set: %s", optstr);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "already set: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
if (cmd_set_option_set(self, cmdq, oe, oo, valstr) != 0)
return (CMD_RETURN_ERROR);
}
/* Start or stop timers when automatic-rename changed. */
/* Start or stop timers if necessary. */
if (strcmp(oe->name, "automatic-rename") == 0) {
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) == NULL)
continue;
RB_FOREACH(w, windows, &windows) {
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
else if (event_initialized(&w->name_timer))
evtimer_del(&w->name_timer);
w->active->flags |= PANE_CHANGED;
}
}
if (strcmp(oe->name, "status") == 0 ||
strcmp(oe->name, "status-interval") == 0)
status_timer_start_all();
if (strcmp(oe->name, "monitor-silence") == 0)
alerts_reset_all();
/* Update sizes and redraw. May not need it but meh. */
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != NULL)
server_redraw_client(c);
}
@@ -196,7 +201,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
/* Set user option. */
enum cmd_retval
cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char *optstr,
const char *valstr)
{
struct args *args = self->args;
@@ -229,8 +234,11 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
if (args_has(args, 'u')) {
if (options_find1(oo, optstr) == NULL) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
if (valstr != NULL) {
cmdq_error(cmdq, "value passed to unset option: %s",
@@ -244,54 +252,64 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
return (CMD_RETURN_ERROR);
}
if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
if (!args_has(args, 'q'))
cmdq_print(cmdq, "already set: %s", optstr);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "already set: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
options_set_string(oo, optstr, "%s", valstr);
if (!args_has(args, 'q')) {
cmdq_info(cmdq, "set option: %s -> %s", optstr,
valstr);
}
}
return (CMD_RETURN_NORMAL);
}
/* Unset an option. */
int
cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
struct args *args = self->args;
if (args_has(args, 'g')) {
cmdq_error(cmdq, "can't unset global option: %s", oe->name);
return (-1);
}
if (value != NULL) {
cmdq_error(cmdq, "value passed to unset option: %s", oe->name);
return (-1);
}
options_remove(oo, oe->name);
if (!args_has(args, 'q'))
cmdq_info(cmdq, "unset option: %s", oe->name);
if (args_has(args, 'g') || oo == &global_options) {
switch (oe->type) {
case OPTIONS_TABLE_STRING:
options_set_string(oo, oe->name, "%s", oe->default_str);
break;
case OPTIONS_TABLE_STYLE:
options_set_style(oo, oe->name, oe->default_str, 0);
break;
default:
options_set_number(oo, oe->name, oe->default_num);
break;
}
} else
options_remove(oo, oe->name);
return (0);
}
/* Set an option. */
int
cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
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) {
cmdq_error(cmdq, "empty value");
return (-1);
switch (oe->type) {
case OPTIONS_TABLE_FLAG:
case OPTIONS_TABLE_CHOICE:
break;
default:
if (value == NULL) {
cmdq_error(cmdq, "empty value");
return (-1);
}
}
o = NULL;
@@ -327,17 +345,14 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
}
if (o == NULL)
return (-1);
s = options_table_print_entry(oe, o, 0);
if (!args_has(args, 'q'))
cmdq_info(cmdq, "set option: %s -> %s", oe->name, s);
return (0);
}
/* Set a string option. */
struct options_entry *
cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
struct args *args = self->args;
struct options_entry *o;
@@ -358,7 +373,8 @@ cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
/* Set a number option. */
struct options_entry *
cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
long long ll;
const char *errstr;
@@ -375,7 +391,8 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a key option. */
struct options_entry *
cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int key;
@@ -390,7 +407,8 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a colour option. */
struct options_entry *
cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int colour;
@@ -405,7 +423,8 @@ cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
/* Set an attributes option. */
struct options_entry *
cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int attr;
@@ -420,7 +439,8 @@ cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a flag option. */
struct options_entry *
cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int flag;
@@ -453,21 +473,27 @@ cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
const char **choicep;
int n, choice = -1;
n = 0;
for (choicep = oe->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (value == NULL) {
choice = options_get_number(oo, oe->name);
if (choice < 2)
choice = !choice;
} else {
n = 0;
for (choicep = oe->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (choice != -1) {
cmdq_error(cmdq, "ambiguous value: %s", value);
if (choice != -1) {
cmdq_error(cmdq, "ambiguous value: %s", value);
return (NULL);
}
choice = n - 1;
}
if (choice == -1) {
cmdq_error(cmdq, "unknown value: %s", value);
return (NULL);
}
choice = n - 1;
}
if (choice == -1) {
cmdq_error(cmdq, "unknown value: %s", value);
return (NULL);
}
return (options_set_number(oo, oe->name, choice));

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,17 +27,61 @@
* Show environment.
*/
enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *);
char *cmd_show_environment_escape(struct environ_entry *);
void cmd_show_environment_print(struct cmd *, struct cmd_q *,
struct environ_entry *);
const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv",
"gt:", 0, 1,
"[-g] " CMD_TARGET_SESSION_USAGE " [name]",
"gst:", 0, 1,
"[-gs] " CMD_TARGET_SESSION_USAGE " [name]",
0,
NULL,
cmd_show_environment_exec
};
char *
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);
}
void
cmd_show_environment_print(struct cmd *self, struct cmd_q *cmdq,
struct environ_entry *envent)
{
char *escaped;
if (!args_has(self->args, 's')) {
if (envent->value != NULL)
cmdq_print(cmdq, "%s=%s", envent->name, envent->value);
else
cmdq_print(cmdq, "-%s", envent->name);
return;
}
if (envent->value != NULL) {
escaped = cmd_show_environment_escape(envent);
cmdq_print(cmdq, "%s=\"%s\"; export %s;", envent->name, escaped,
envent->name);
free(escaped);
} else
cmdq_print(cmdq, "unset %s;", envent->name);
}
enum cmd_retval
cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq)
{
@@ -49,7 +93,8 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq)
if (args_has(self->args, 'g'))
env = &global_environ;
else {
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
env = &s->environ;
}
@@ -60,19 +105,11 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "unknown variable: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
if (envent->value != NULL)
cmdq_print(cmdq, "%s=%s", envent->name, envent->value);
else
cmdq_print(cmdq, "-%s", envent->name);
cmd_show_environment_print(self, cmdq, envent);
return (CMD_RETURN_NORMAL);
}
RB_FOREACH(envent, environ, env) {
if (envent->value != NULL)
cmdq_print(cmdq, "%s=%s", envent->name, envent->value);
else
cmdq_print(cmdq, "-%s", envent->name);
}
RB_FOREACH(envent, environ, env)
cmd_show_environment_print(self, cmdq, envent);
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,7 +35,6 @@ const struct cmd_entry cmd_show_messages_entry = {
"IJTt:", 0, 0,
"[-IJT] " CMD_TARGET_CLIENT_USAGE,
0,
NULL,
cmd_show_messages_exec
};
@@ -44,15 +43,14 @@ const struct cmd_entry cmd_server_info_entry = {
"", 0, 0,
"",
0,
NULL,
cmd_show_messages_exec
};
void cmd_show_messages_server(struct cmd_q *);
void cmd_show_messages_terminals(struct cmd_q *);
void cmd_show_messages_jobs(struct cmd_q *);
int cmd_show_messages_server(struct cmd_q *);
int cmd_show_messages_terminals(struct cmd_q *, int);
int cmd_show_messages_jobs(struct cmd_q *, int);
void
int
cmd_show_messages_server(struct cmd_q *cmdq)
{
char *tim;
@@ -64,64 +62,48 @@ cmd_show_messages_server(struct cmd_q *cmdq)
cmdq_print(cmdq, "socket path %s", socket_path);
cmdq_print(cmdq, "debug level %d", debug_level);
cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
return (1);
}
void
cmd_show_messages_terminals(struct cmd_q *cmdq)
int
cmd_show_messages_terminals(struct cmd_q *cmdq, int blank)
{
struct tty_term *term;
const struct tty_term_code_entry *ent;
struct tty_code *code;
u_int i, n;
char out[80];
struct tty_term *term;
u_int i, n;
n = 0;
LIST_FOREACH(term, &tty_terms, entry) {
cmdq_print(cmdq,
"Terminal %u: %s [references=%u, flags=0x%x]:",
if (blank) {
cmdq_print(cmdq, "%s", "");
blank = 0;
}
cmdq_print(cmdq, "Terminal %u: %s [references=%u, flags=0x%x]:",
n, term->name, term->references, term->flags);
n++;
for (i = 0; i < NTTYCODE; i++) {
ent = &tty_term_codes[i];
code = &term->codes[ent->code];
switch (code->type) {
case TTYCODE_NONE:
cmdq_print(cmdq, "%4u: %s: [missing]",
ent->code, ent->name);
break;
case TTYCODE_STRING:
strnvis(out, code->value.string, sizeof out,
VIS_OCTAL|VIS_TAB|VIS_NL);
cmdq_print(cmdq, "%4u: %s: (string) %s",
ent->code, ent->name, out);
break;
case TTYCODE_NUMBER:
cmdq_print(cmdq, "%4u: %s: (number) %d",
ent->code, ent->name, code->value.number);
break;
case TTYCODE_FLAG:
cmdq_print(cmdq, "%4u: %s: (flag) %s",
ent->code, ent->name,
code->value.flag ? "true" : "false");
break;
}
}
for (i = 0; i < tty_term_ncodes(); i++)
cmdq_print(cmdq, "%s", tty_term_describe(term, i));
}
return (n != 0);
}
void
cmd_show_messages_jobs(struct cmd_q *cmdq)
int
cmd_show_messages_jobs(struct cmd_q *cmdq, int blank)
{
struct job *job;
u_int n;
n = 0;
LIST_FOREACH(job, &all_jobs, lentry) {
cmdq_print(cmdq,
"Job %u: %s [fd=%d, pid=%d, status=%d]",
if (blank) {
cmdq_print(cmdq, "%s", "");
blank = 0;
}
cmdq_print(cmdq, "Job %u: %s [fd=%d, pid=%d, status=%d]",
n, job->cmd, job->fd, job->pid, job->status);
n++;
}
return (n != 0);
}
enum cmd_retval
@@ -131,24 +113,19 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c;
struct message_entry *msg;
char *tim;
u_int i;
int done;
int done, blank;
done = 0;
done = blank = 0;
if (args_has(args, 'I') || self->entry == &cmd_server_info_entry) {
cmd_show_messages_server(cmdq);
blank = cmd_show_messages_server(cmdq);
done = 1;
}
if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) {
if (done)
cmdq_print(cmdq, "%s", "");
cmd_show_messages_terminals(cmdq);
blank = cmd_show_messages_terminals(cmdq, blank);
done = 1;
}
if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) {
if (done)
cmdq_print(cmdq, "%s", "");
cmd_show_messages_jobs(cmdq);
cmd_show_messages_jobs(cmdq, blank);
done = 1;
}
if (done)
@@ -157,9 +134,7 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
msg = &ARRAY_ITEM(&c->message_log, i);
TAILQ_FOREACH(msg, &c->message_log, entry) {
tim = ctime(&msg->msg_time);
*strchr(tim, '\n') = '\0';

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -39,7 +39,6 @@ const struct cmd_entry cmd_show_options_entry = {
"gqst:vw", 0, 1,
"[-gqsvw] [-t target-session|target-window] [option]",
0,
NULL,
cmd_show_options_exec
};
@@ -48,7 +47,6 @@ const struct cmd_entry cmd_show_window_options_entry = {
"gvt:", 0, 1,
"[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
0,
NULL,
cmd_show_options_exec
};
@@ -100,15 +98,17 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
struct options *oo, int quiet)
{
struct args *args = self->args;
const char *name = args->argv[0];
const struct options_table_entry *table, *oe;
struct options_entry *o;
const char *optval;
if (*args->argv[0] == '@') {
if ((o = options_find1(oo, args->argv[0])) == NULL) {
retry:
if (*name == '@') {
if ((o = options_find1(oo, name)) == NULL) {
if (quiet)
return (CMD_RETURN_NORMAL);
cmdq_error(cmdq, "unknown option: %s", args->argv[0]);
cmdq_error(cmdq, "unknown option: %s", name);
return (CMD_RETURN_ERROR);
}
if (args_has(self->args, 'v'))
@@ -119,16 +119,20 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
}
table = oe = NULL;
if (options_table_find(args->argv[0], &table, &oe) != 0) {
cmdq_error(cmdq, "ambiguous option: %s", args->argv[0]);
if (options_table_find(name, &table, &oe) != 0) {
cmdq_error(cmdq, "ambiguous option: %s", name);
return (CMD_RETURN_ERROR);
}
if (oe == NULL) {
if (quiet)
return (CMD_RETURN_NORMAL);
cmdq_error(cmdq, "unknown option: %s", args->argv[0]);
cmdq_error(cmdq, "unknown option: %s", name);
return (CMD_RETURN_ERROR);
}
if (oe->style != NULL) {
name = oe->style;
goto retry;
}
if ((o = options_find1(oo, oe->name)) == NULL)
return (CMD_RETURN_NORMAL);
optval = options_table_print_entry(oe, o, args_has(self->args, 'v'));
@@ -157,6 +161,8 @@ cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq,
}
for (oe = table; oe->name != NULL; oe++) {
if (oe->style != NULL)
continue;
if ((o = options_find1(oo, oe->name)) == NULL)
continue;
optval = options_table_print_entry(oe, o,

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -28,7 +28,6 @@
enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_q *);
void cmd_source_file_show(struct cmd_q *);
void cmd_source_file_done(struct cmd_q *);
const struct cmd_entry cmd_source_file_entry = {
@@ -36,7 +35,6 @@ const struct cmd_entry cmd_source_file_entry = {
"", 1, 1,
"path",
0,
NULL,
cmd_source_file_exec
};
@@ -60,11 +58,12 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
free(cause);
return (CMD_RETURN_ERROR);
}
ARRAY_ADD(&cfg_causes, cause);
cfg_add_cause("%s", cause);
free(cause);
/* FALLTHROUGH */
case 0:
if (cfg_references == 0)
cmd_source_file_show(cmdq);
cfg_print_causes(cmdq);
cmdq_free(cmdq1);
return (CMD_RETURN_NORMAL);
}
@@ -76,20 +75,6 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_WAIT);
}
void
cmd_source_file_show(struct cmd_q *cmdq)
{
u_int i;
char *cause;
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
cmdq_print(cmdq, "%s", cause);
free(cause);
}
ARRAY_FREE(&cfg_causes);
}
void
cmd_source_file_done(struct cmd_q *cmdq1)
{
@@ -106,6 +91,6 @@ cmd_source_file_done(struct cmd_q *cmdq1)
return;
if (cfg_references == 0)
cmd_source_file_show(cmdq);
cfg_print_causes(cmdq);
cmdq_continue(cmdq);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,27 +30,19 @@
* 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_q *);
const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"c:dF:l:hp:Pt:v", 0, 1,
"[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
"bc:dF:l:hp:Pt:v", 0, -1,
"[-bdhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
CMD_TARGET_PANE_USAGE " [command]",
0,
cmd_split_window_key_binding,
cmd_split_window_exec
};
void
cmd_split_window_key_binding(struct cmd *self, int key)
{
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_q *cmdq)
{
@@ -60,14 +52,14 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window *w;
struct window_pane *wp, *new_wp = NULL;
struct environ env;
const char *cmd, *shell, *template;
char *cause, *new_cause, *cp;
const char *cmd, *path, *shell, *template;
char **argv, *cause, *new_cause, *cp;
u_int hlimit;
int size, percentage, cwd, fd = -1;
int argc, size, percentage, cwd, fd = -1;
enum layout_type type;
struct layout_cell *lc;
struct client *c;
struct format_tree *ft;
struct environ_entry *envent;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
@@ -79,18 +71,24 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
if (args->argc == 0)
if (args->argc == 0) {
cmd = options_get_string(&s->options, "default-command");
else
cmd = args->argv[0];
if (cmd != NULL && *cmd != '\0') {
argc = 1;
argv = (char **)&cmd;
} else {
argc = 0;
argv = NULL;
}
} else {
argc = args->argc;
argv = args->argv;
}
if (args_has(args, 'c')) {
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, s->curw);
format_window_pane(ft, s->curw->window->active);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
@@ -142,16 +140,26 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
if ((lc = layout_split_pane(wp, type, size, 0)) == NULL) {
lc = layout_split_pane(wp, type, size, args_has(args, 'b'));
if (lc == NULL) {
cause = xstrdup("pane too small");
goto error;
}
new_wp = window_add_pane(w, hlimit);
if (window_pane_spawn(
new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
layout_assign_pane(lc, new_wp);
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, &env,
s->tio, &cause) != 0)
goto error;
server_redraw_window(w);
if (!args_has(args, 'd')) {
@@ -168,11 +176,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
template = SPLIT_WINDOW_TEMPLATE;
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, new_wp);
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
new_wp);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);
@@ -188,8 +193,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
error:
environ_free(&env);
if (new_wp != NULL)
if (new_wp != NULL) {
layout_close_pane(new_wp);
window_remove_pane(w, new_wp);
}
cmdq_error(cmdq, "create pane failed: %s", cause);
free(cause);
if (fd != -1)

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -107,10 +107,11 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
case ' ':
case '\t':
if (buf != NULL) {
buf = xrealloc(buf, 1, len + 1);
buf = xrealloc(buf, len + 1);
buf[len] = '\0';
argv = xrealloc(argv, argc + 1, sizeof *argv);
argv = xreallocarray(argv, argc + 1,
sizeof *argv);
argv[argc++] = buf;
buf = NULL;
@@ -151,7 +152,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
if (len >= SIZE_MAX - 2)
goto error;
buf = xrealloc(buf, 1, len + 1);
buf = xrealloc(buf, len + 1);
buf[len++] = ch;
break;
}
@@ -179,7 +180,7 @@ cmd_string_copy(char **dst, char *src, size_t *len)
srclen = strlen(src);
*dst = xrealloc(*dst, 1, *len + srclen + 1);
*dst = xrealloc(*dst, *len + srclen + 1);
strlcpy(*dst + *len, src, srclen + 1);
*len += srclen;
@@ -231,11 +232,11 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
if (len >= SIZE_MAX - 2)
goto error;
buf = xrealloc(buf, 1, len + 1);
buf = xrealloc(buf, len + 1);
buf[len++] = ch;
}
buf = xrealloc(buf, 1, len + 1);
buf = xrealloc(buf, len + 1);
buf[len] = '\0';
return (buf);
@@ -278,7 +279,7 @@ cmd_string_variable(const char *s, size_t *p)
return (t);
}
buf = xrealloc(buf, 1, len + 1);
buf = xrealloc(buf, len + 1);
buf[len++] = ch;
for (;;) {
@@ -288,7 +289,7 @@ cmd_string_variable(const char *s, size_t *p)
else {
if (len >= SIZE_MAX - 3)
goto error;
buf = xrealloc(buf, 1, len + 1);
buf = xrealloc(buf, len + 1);
buf[len++] = ch;
}
}
@@ -299,7 +300,7 @@ cmd_string_variable(const char *s, size_t *p)
if (ch != EOF && fch != '{')
cmd_string_ungetc(p); /* ch */
buf = xrealloc(buf, 1, len + 1);
buf = xrealloc(buf, len + 1);
buf[len] = '\0';
envent = environ_find(&global_environ, buf);

View File

@@ -1,55 +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_q *);
const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
NULL,
cmd_suspend_client_exec
};
enum cmd_retval
cmd_suspend_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == 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,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,7 +26,6 @@
* Swap two panes.
*/
void cmd_swap_pane_key_binding(struct cmd *, int);
enum cmd_retval cmd_swap_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_swap_pane_entry = {
@@ -34,20 +33,9 @@ const struct cmd_entry cmd_swap_pane_entry = {
"dDs:t:U", 0, 0,
"[-dDU] " CMD_SRCDST_PANE_USAGE,
0,
cmd_swap_pane_key_binding,
cmd_swap_pane_exec
};
void
cmd_swap_pane_key_binding(struct cmd *self, int key)
{
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_q *cmdq)
{
@@ -75,13 +63,15 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
} else {
src_wl = cmd_find_pane(cmdq, NULL, NULL, &src_wp);
src_wl = cmd_find_pane_marked(cmdq, NULL, NULL,
&src_wp);
if (src_wl == NULL)
return (CMD_RETURN_ERROR);
src_w = src_wl->window;
}
} else {
src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL,
&src_wp);
if (src_wl == NULL)
return (CMD_RETURN_ERROR);
src_w = src_wl->window;

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,6 @@ const struct cmd_entry cmd_swap_window_entry = {
"ds:t:", 0, 0,
"[-d] " CMD_SRCDST_WINDOW_USAGE,
0,
NULL,
cmd_swap_window_exec
};
@@ -48,7 +47,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window *w;
target_src = args_get(args, 's');
if ((wl_src = cmd_find_window(cmdq, target_src, &src)) == NULL)
if ((wl_src = cmd_find_window_marked(cmdq, target_src, &src)) == NULL)
return (CMD_RETURN_ERROR);
target_dst = args_get(args, 't');
if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL)

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,35 +27,16 @@
* Switch client to a different session.
*/
void cmd_switch_client_key_binding(struct cmd *, int);
enum cmd_retval cmd_switch_client_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc",
"lc:npt:r", 0, 0,
"[-lnpr] [-c target-client] [-t target-session]",
"lc:Enpt:rT:", 0, 0,
"[-Elnpr] [-c target-client] [-t target-session] [-T key-table]",
CMD_READONLY,
cmd_switch_client_key_binding,
cmd_switch_client_exec
};
void
cmd_switch_client_key_binding(struct cmd *self, int key)
{
self->args = args_create(0);
switch (key) {
case '(':
args_set(self->args, 'p', NULL);
break;
case ')':
args_set(self->args, 'n', NULL);
break;
case 'L':
args_set(self->args, 'l', NULL);
break;
}
}
enum cmd_retval
cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
@@ -65,19 +46,29 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
struct winlink *wl = NULL;
struct window *w = NULL;
struct window_pane *wp = NULL;
const char *tflag;
const char *tflag, *tablename, *update;
struct key_table *table;
if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'r')) {
if (c->flags & CLIENT_READONLY) {
if (c->flags & CLIENT_READONLY)
c->flags &= ~CLIENT_READONLY;
cmdq_info(cmdq, "made client writable");
} else {
else
c->flags |= CLIENT_READONLY;
cmdq_info(cmdq, "made client read-only");
}
tablename = args_get(args, 'T');
if (tablename != NULL) {
table = key_bindings_get_table(tablename, 0);
if (table == NULL) {
cmdq_error(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
table->references++;
key_bindings_unref_table(c->keytable);
c->keytable = table;
}
tflag = args_get(args, 't');
@@ -108,10 +99,12 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
} else {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
w = cmd_lookup_windowid(tflag);
if (w == NULL &&
(wp = cmd_lookup_paneid(tflag)) != NULL)
w = wp->window;
w = window_find_by_id_str(tflag);
if (w == NULL) {
wp = window_pane_find_by_id_str(tflag);
if (wp != NULL)
w = wp->window;
}
if (w != NULL)
wl = winlink_find_by_window(&s->windows, w);
}
@@ -126,10 +119,17 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
if (c->session != NULL)
if (c != NULL && !args_has(args, 'E')) {
update = options_get_string(&s->options, "update-environment");
environ_update(update, &c->environ, &s->environ);
}
if (c->session != NULL && c->session != s)
c->last_session = c->session;
c->session = s;
session_update_activity(s);
status_timer_start(c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
recalculate_sizes();
server_check_unattached();

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,23 +27,22 @@
*/
enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_unbind_key_table(struct cmd *, struct cmd_q *, int);
enum cmd_retval cmd_unbind_key_mode_table(struct cmd *, struct cmd_q *, int);
const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind",
"acnt:", 0, 1,
"[-acn] [-t key-table] key",
"acnt:T:", 0, 1,
"[-acn] [-t mode-table] [-T key-table] key",
0,
NULL,
cmd_unbind_key_exec
};
enum cmd_retval
cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct key_binding *bd;
int key;
struct args *args = self->args;
int key;
const char *tablename;
if (!args_has(args, 'a')) {
if (args->argc != 1) {
@@ -64,24 +63,39 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
}
if (args_has(args, 't'))
return (cmd_unbind_key_table(self, cmdq, key));
return (cmd_unbind_key_mode_table(self, cmdq, key));
if (key == KEYC_NONE) {
while (!RB_EMPTY(&key_bindings)) {
bd = RB_ROOT(&key_bindings);
key_bindings_remove(bd->key);
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(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
key_bindings_remove_table(tablename);
return (CMD_RETURN_NORMAL);
}
if (!args_has(args, 'n'))
key |= KEYC_PREFIX;
key_bindings_remove(key);
if (args_has(args, 'T')) {
tablename = args_get(args, 'T');
if (key_bindings_get_table(tablename, 0) == NULL) {
cmdq_error(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
} else if (args_has(args, 'n'))
tablename = "root";
else
tablename = "prefix";
key_bindings_remove(tablename, key);
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_unbind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
{
struct args *args = self->args;
const char *tablename;

View File

@@ -1,69 +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_q *);
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
"kt:", 0, 0,
"[-k] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
cmd_unlink_window_exec
};
enum cmd_retval
cmd_unlink_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
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(cmdq, 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) {
cmdq_error(cmdq, "window is only linked to one session");
return (CMD_RETURN_ERROR);
}
server_unlink_window(s, wl);
recalculate_sizes();
return (CMD_RETURN_NORMAL);
}

View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,13 +35,13 @@ const struct cmd_entry cmd_wait_for_entry = {
"LSU", 1, 1,
"[-L|-S|-U] channel",
0,
NULL,
cmd_wait_for_exec
};
struct wait_channel {
const char *name;
int locked;
int woken;
TAILQ_HEAD(, cmd_q) waiters;
TAILQ_HEAD(, cmd_q) lockers;
@@ -70,8 +70,48 @@ enum cmd_retval cmd_wait_for_lock(struct cmd_q *, const char *,
enum cmd_retval cmd_wait_for_unlock(struct cmd_q *, const char *,
struct wait_channel *);
struct wait_channel *cmd_wait_for_add(const char *);
void cmd_wait_for_remove(struct wait_channel *wc);
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);
}
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);
}
enum cmd_retval
cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)
cmd_wait_for_exec(struct cmd *self, unused struct cmd_q *cmdq)
{
struct args *args = self->args;
const char *name = args->argv[0];
@@ -90,15 +130,20 @@ cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)
}
enum cmd_retval
cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,
cmd_wait_for_signal(unused struct cmd_q *cmdq, const char *name,
struct wait_channel *wc)
{
struct cmd_q *wq, *wq1;
if (wc == NULL || TAILQ_EMPTY(&wc->waiters)) {
cmdq_error(cmdq, "no waiting clients on %s", name);
return (CMD_RETURN_ERROR);
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(wq, &wc->waiters, waitentry, wq1) {
TAILQ_REMOVE(&wc->waiters, wq, waitentry);
@@ -106,12 +151,7 @@ cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,
cmdq_continue(wq);
}
if (!wc->locked) {
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void*) wc->name);
free(wc);
}
cmd_wait_for_remove(wc);
return (CMD_RETURN_NORMAL);
}
@@ -119,19 +159,23 @@ enum cmd_retval
cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
struct wait_channel *wc)
{
if (cmdq->client == NULL || cmdq->client->session != NULL) {
struct client *c = cmdq->client;
if (c == NULL || c->session != NULL) {
cmdq_error(cmdq, "not able to wait");
return (CMD_RETURN_ERROR);
}
if (wc == NULL) {
wc = xmalloc(sizeof *wc);
wc->name = xstrdup(name);
wc->locked = 0;
TAILQ_INIT(&wc->waiters);
TAILQ_INIT(&wc->lockers);
RB_INSERT(wait_channels, &wait_channels, wc);
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (wc->woken) {
log_debug("wait channel %s already woken (client %d)", wc->name,
c->tty.fd);
cmd_wait_for_remove(wc);
return (CMD_RETURN_NORMAL);
}
log_debug("wait channel %s not woken (client %d)", wc->name, c->tty.fd);
TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry);
cmdq->references++;
@@ -148,14 +192,8 @@ cmd_wait_for_lock(struct cmd_q *cmdq, const char *name,
return (CMD_RETURN_ERROR);
}
if (wc == NULL) {
wc = xmalloc(sizeof *wc);
wc->name = xstrdup(name);
wc->locked = 0;
TAILQ_INIT(&wc->waiters);
TAILQ_INIT(&wc->lockers);
RB_INSERT(wait_channels, &wait_channels, wc);
}
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (wc->locked) {
TAILQ_INSERT_TAIL(&wc->lockers, cmdq, waitentry);
@@ -184,13 +222,31 @@ cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name,
cmdq_continue(wq);
} else {
wc->locked = 0;
if (TAILQ_EMPTY(&wc->waiters)) {
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void*) wc->name);
free(wc);
}
cmd_wait_for_remove(wc);
}
return (CMD_RETURN_NORMAL);
}
void
cmd_wait_for_flush(void)
{
struct wait_channel *wc, *wc1;
struct cmd_q *wq, *wq1;
RB_FOREACH_SAFE(wc, wait_channels, &wait_channels, wc1) {
TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {
TAILQ_REMOVE(&wc->waiters, wq, waitentry);
if (!cmdq_free(wq))
cmdq_continue(wq);
}
wc->woken = 1;
TAILQ_FOREACH_SAFE(wq, &wc->lockers, waitentry, wq1) {
TAILQ_REMOVE(&wc->lockers, wq, waitentry);
if (!cmdq_free(wq))
cmdq_continue(wq);
}
wc->locked = 0;
cmd_wait_for_remove(wc);
}
}

1087
cmd.c

File diff suppressed because it is too large Load Diff

396
colour.c
View File

@@ -1,4 +1,4 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,91 +29,305 @@
* of the 256 colour palette.
*/
/* An RGB colour. */
struct colour_rgb {
u_char i;
u_char r;
u_char g;
u_char b;
};
/* 256 colour RGB table, generated on first use. */
struct colour_rgb *colour_rgb_256;
const struct colour_rgb colour_from_256[] = {
{ 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
{ 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
{ 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
{ 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
{ 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
{ 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
{ 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
{ 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
{ 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
{ 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
{ 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
{ 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
{ 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
{ 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
{ 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
{ 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
{ 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
{ 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
{ 36, 0x5f, 0x00, 0x00 }, { 37, 0x5f, 0x00, 0x5f },
{ 38, 0x5f, 0x00, 0x87 }, { 39, 0x5f, 0x00, 0xaf },
{ 40, 0x5f, 0x00, 0xd7 }, { 41, 0x5f, 0x00, 0xff },
{ 42, 0x5f, 0x5f, 0x00 }, { 43, 0x5f, 0x5f, 0x5f },
{ 44, 0x5f, 0x5f, 0x87 }, { 45, 0x5f, 0x5f, 0xaf },
{ 46, 0x5f, 0x5f, 0xd7 }, { 47, 0x5f, 0x5f, 0xff },
{ 48, 0x5f, 0x87, 0x00 }, { 49, 0x5f, 0x87, 0x5f },
{ 50, 0x5f, 0x87, 0x87 }, { 51, 0x5f, 0x87, 0xaf },
{ 52, 0x5f, 0x87, 0xd7 }, { 53, 0x5f, 0x87, 0xff },
{ 54, 0x5f, 0xaf, 0x00 }, { 55, 0x5f, 0xaf, 0x5f },
{ 56, 0x5f, 0xaf, 0x87 }, { 57, 0x5f, 0xaf, 0xaf },
{ 58, 0x5f, 0xaf, 0xd7 }, { 59, 0x5f, 0xaf, 0xff },
{ 60, 0x5f, 0xd7, 0x00 }, { 61, 0x5f, 0xd7, 0x5f },
{ 62, 0x5f, 0xd7, 0x87 }, { 63, 0x5f, 0xd7, 0xaf },
{ 64, 0x5f, 0xd7, 0xd7 }, { 65, 0x5f, 0xd7, 0xff },
{ 66, 0x5f, 0xff, 0x00 }, { 67, 0x5f, 0xff, 0x5f },
{ 68, 0x5f, 0xff, 0x87 }, { 69, 0x5f, 0xff, 0xaf },
{ 70, 0x5f, 0xff, 0xd7 }, { 71, 0x5f, 0xff, 0xff },
{ 72, 0x87, 0x00, 0x00 }, { 73, 0x87, 0x00, 0x5f },
{ 74, 0x87, 0x00, 0x87 }, { 75, 0x87, 0x00, 0xaf },
{ 76, 0x87, 0x00, 0xd7 }, { 77, 0x87, 0x00, 0xff },
{ 78, 0x87, 0x5f, 0x00 }, { 79, 0x87, 0x5f, 0x5f },
{ 80, 0x87, 0x5f, 0x87 }, { 81, 0x87, 0x5f, 0xaf },
{ 82, 0x87, 0x5f, 0xd7 }, { 83, 0x87, 0x5f, 0xff },
{ 84, 0x87, 0x87, 0x00 }, { 85, 0x87, 0x87, 0x5f },
{ 86, 0x87, 0x87, 0x87 }, { 87, 0x87, 0x87, 0xaf },
{ 88, 0x87, 0x87, 0xd7 }, { 89, 0x87, 0x87, 0xff },
{ 90, 0x87, 0xaf, 0x00 }, { 91, 0x87, 0xaf, 0x5f },
{ 92, 0x87, 0xaf, 0x87 }, { 93, 0x87, 0xaf, 0xaf },
{ 94, 0x87, 0xaf, 0xd7 }, { 95, 0x87, 0xaf, 0xff },
{ 96, 0x87, 0xd7, 0x00 }, { 97, 0x87, 0xd7, 0x5f },
{ 98, 0x87, 0xd7, 0x87 }, { 99, 0x87, 0xd7, 0xaf },
{ 100, 0x87, 0xd7, 0xd7 }, { 101, 0x87, 0xd7, 0xff },
{ 102, 0x87, 0xff, 0x00 }, { 103, 0x87, 0xff, 0x5f },
{ 104, 0x87, 0xff, 0x87 }, { 105, 0x87, 0xff, 0xaf },
{ 106, 0x87, 0xff, 0xd7 }, { 107, 0x87, 0xff, 0xff },
{ 108, 0xaf, 0x00, 0x00 }, { 109, 0xaf, 0x00, 0x5f },
{ 110, 0xaf, 0x00, 0x87 }, { 111, 0xaf, 0x00, 0xaf },
{ 112, 0xaf, 0x00, 0xd7 }, { 113, 0xaf, 0x00, 0xff },
{ 114, 0xaf, 0x5f, 0x00 }, { 115, 0xaf, 0x5f, 0x5f },
{ 116, 0xaf, 0x5f, 0x87 }, { 117, 0xaf, 0x5f, 0xaf },
{ 118, 0xaf, 0x5f, 0xd7 }, { 119, 0xaf, 0x5f, 0xff },
{ 120, 0xaf, 0x87, 0x00 }, { 121, 0xaf, 0x87, 0x5f },
{ 122, 0xaf, 0x87, 0x87 }, { 123, 0xaf, 0x87, 0xaf },
{ 124, 0xaf, 0x87, 0xd7 }, { 125, 0xaf, 0x87, 0xff },
{ 126, 0xaf, 0xaf, 0x00 }, { 127, 0xaf, 0xaf, 0x5f },
{ 128, 0xaf, 0xaf, 0x87 }, { 129, 0xaf, 0xaf, 0xaf },
{ 130, 0xaf, 0xaf, 0xd7 }, { 131, 0xaf, 0xaf, 0xff },
{ 132, 0xaf, 0xd7, 0x00 }, { 133, 0xaf, 0xd7, 0x5f },
{ 134, 0xaf, 0xd7, 0x87 }, { 135, 0xaf, 0xd7, 0xaf },
{ 136, 0xaf, 0xd7, 0xd7 }, { 137, 0xaf, 0xd7, 0xff },
{ 138, 0xaf, 0xff, 0x00 }, { 139, 0xaf, 0xff, 0x5f },
{ 140, 0xaf, 0xff, 0x87 }, { 141, 0xaf, 0xff, 0xaf },
{ 142, 0xaf, 0xff, 0xd7 }, { 143, 0xaf, 0xff, 0xff },
{ 144, 0xd7, 0x00, 0x00 }, { 145, 0xd7, 0x00, 0x5f },
{ 146, 0xd7, 0x00, 0x87 }, { 147, 0xd7, 0x00, 0xaf },
{ 148, 0xd7, 0x00, 0xd7 }, { 149, 0xd7, 0x00, 0xff },
{ 150, 0xd7, 0x5f, 0x00 }, { 151, 0xd7, 0x5f, 0x5f },
{ 152, 0xd7, 0x5f, 0x87 }, { 153, 0xd7, 0x5f, 0xaf },
{ 154, 0xd7, 0x5f, 0xd7 }, { 155, 0xd7, 0x5f, 0xff },
{ 156, 0xd7, 0x87, 0x00 }, { 157, 0xd7, 0x87, 0x5f },
{ 158, 0xd7, 0x87, 0x87 }, { 159, 0xd7, 0x87, 0xaf },
{ 160, 0xd7, 0x87, 0xd7 }, { 161, 0xd7, 0x87, 0xff },
{ 162, 0xd7, 0xaf, 0x00 }, { 163, 0xd7, 0xaf, 0x5f },
{ 164, 0xd7, 0xaf, 0x87 }, { 165, 0xd7, 0xaf, 0xaf },
{ 166, 0xd7, 0xaf, 0xd7 }, { 167, 0xd7, 0xaf, 0xff },
{ 168, 0xd7, 0xd7, 0x00 }, { 169, 0xd7, 0xd7, 0x5f },
{ 170, 0xd7, 0xd7, 0x87 }, { 171, 0xd7, 0xd7, 0xaf },
{ 172, 0xd7, 0xd7, 0xd7 }, { 173, 0xd7, 0xd7, 0xff },
{ 174, 0xd7, 0xff, 0x00 }, { 175, 0xd7, 0xff, 0x5f },
{ 176, 0xd7, 0xff, 0x87 }, { 177, 0xd7, 0xff, 0xaf },
{ 178, 0xd7, 0xff, 0xd7 }, { 179, 0xd7, 0xff, 0xff },
{ 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
{ 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
{ 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
{ 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
{ 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
{ 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
{ 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
{ 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
{ 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
{ 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
{ 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
{ 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
{ 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
{ 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
{ 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
{ 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
{ 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
{ 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
{ 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
{ 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
{ 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
{ 224, 0x58, 0x58, 0x58 }, { 225, 0x62, 0x62, 0x62 },
{ 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
{ 228, 0x80, 0x80, 0x80 }, { 229, 0x8a, 0x8a, 0x8a },
{ 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
{ 232, 0xa8, 0xa8, 0xa8 }, { 233, 0xb2, 0xb2, 0xb2 },
{ 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
{ 236, 0xd0, 0xd0, 0xd0 }, { 237, 0xda, 0xda, 0xda },
{ 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
};
const struct colour_rgb colour_to_256[] = {
{ 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
{ 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
{ 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
{ 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
{ 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
{ 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
{ 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
{ 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
{ 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
{ 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
{ 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
{ 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
{ 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
{ 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
{ 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
{ 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
{ 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
{ 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
{ 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
{ 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
{ 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
{ 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
{ 224, 0x58, 0x58, 0x58 }, { 36, 0x5f, 0x00, 0x00 },
{ 37, 0x5f, 0x00, 0x5f }, { 38, 0x5f, 0x00, 0x87 },
{ 39, 0x5f, 0x00, 0xaf }, { 40, 0x5f, 0x00, 0xd7 },
{ 41, 0x5f, 0x00, 0xff }, { 42, 0x5f, 0x5f, 0x00 },
{ 43, 0x5f, 0x5f, 0x5f }, { 44, 0x5f, 0x5f, 0x87 },
{ 45, 0x5f, 0x5f, 0xaf }, { 46, 0x5f, 0x5f, 0xd7 },
{ 47, 0x5f, 0x5f, 0xff }, { 48, 0x5f, 0x87, 0x00 },
{ 49, 0x5f, 0x87, 0x5f }, { 50, 0x5f, 0x87, 0x87 },
{ 51, 0x5f, 0x87, 0xaf }, { 52, 0x5f, 0x87, 0xd7 },
{ 53, 0x5f, 0x87, 0xff }, { 54, 0x5f, 0xaf, 0x00 },
{ 55, 0x5f, 0xaf, 0x5f }, { 56, 0x5f, 0xaf, 0x87 },
{ 57, 0x5f, 0xaf, 0xaf }, { 58, 0x5f, 0xaf, 0xd7 },
{ 59, 0x5f, 0xaf, 0xff }, { 60, 0x5f, 0xd7, 0x00 },
{ 61, 0x5f, 0xd7, 0x5f }, { 62, 0x5f, 0xd7, 0x87 },
{ 63, 0x5f, 0xd7, 0xaf }, { 64, 0x5f, 0xd7, 0xd7 },
{ 65, 0x5f, 0xd7, 0xff }, { 66, 0x5f, 0xff, 0x00 },
{ 67, 0x5f, 0xff, 0x5f }, { 68, 0x5f, 0xff, 0x87 },
{ 69, 0x5f, 0xff, 0xaf }, { 70, 0x5f, 0xff, 0xd7 },
{ 71, 0x5f, 0xff, 0xff }, { 225, 0x62, 0x62, 0x62 },
{ 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
{ 228, 0x80, 0x80, 0x80 }, { 72, 0x87, 0x00, 0x00 },
{ 73, 0x87, 0x00, 0x5f }, { 74, 0x87, 0x00, 0x87 },
{ 75, 0x87, 0x00, 0xaf }, { 76, 0x87, 0x00, 0xd7 },
{ 77, 0x87, 0x00, 0xff }, { 78, 0x87, 0x5f, 0x00 },
{ 79, 0x87, 0x5f, 0x5f }, { 80, 0x87, 0x5f, 0x87 },
{ 81, 0x87, 0x5f, 0xaf }, { 82, 0x87, 0x5f, 0xd7 },
{ 83, 0x87, 0x5f, 0xff }, { 84, 0x87, 0x87, 0x00 },
{ 85, 0x87, 0x87, 0x5f }, { 86, 0x87, 0x87, 0x87 },
{ 87, 0x87, 0x87, 0xaf }, { 88, 0x87, 0x87, 0xd7 },
{ 89, 0x87, 0x87, 0xff }, { 90, 0x87, 0xaf, 0x00 },
{ 91, 0x87, 0xaf, 0x5f }, { 92, 0x87, 0xaf, 0x87 },
{ 93, 0x87, 0xaf, 0xaf }, { 94, 0x87, 0xaf, 0xd7 },
{ 95, 0x87, 0xaf, 0xff }, { 96, 0x87, 0xd7, 0x00 },
{ 97, 0x87, 0xd7, 0x5f }, { 98, 0x87, 0xd7, 0x87 },
{ 99, 0x87, 0xd7, 0xaf }, { 100, 0x87, 0xd7, 0xd7 },
{ 101, 0x87, 0xd7, 0xff }, { 102, 0x87, 0xff, 0x00 },
{ 103, 0x87, 0xff, 0x5f }, { 104, 0x87, 0xff, 0x87 },
{ 105, 0x87, 0xff, 0xaf }, { 106, 0x87, 0xff, 0xd7 },
{ 107, 0x87, 0xff, 0xff }, { 229, 0x8a, 0x8a, 0x8a },
{ 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
{ 232, 0xa8, 0xa8, 0xa8 }, { 108, 0xaf, 0x00, 0x00 },
{ 109, 0xaf, 0x00, 0x5f }, { 110, 0xaf, 0x00, 0x87 },
{ 111, 0xaf, 0x00, 0xaf }, { 112, 0xaf, 0x00, 0xd7 },
{ 113, 0xaf, 0x00, 0xff }, { 114, 0xaf, 0x5f, 0x00 },
{ 115, 0xaf, 0x5f, 0x5f }, { 116, 0xaf, 0x5f, 0x87 },
{ 117, 0xaf, 0x5f, 0xaf }, { 118, 0xaf, 0x5f, 0xd7 },
{ 119, 0xaf, 0x5f, 0xff }, { 120, 0xaf, 0x87, 0x00 },
{ 121, 0xaf, 0x87, 0x5f }, { 122, 0xaf, 0x87, 0x87 },
{ 123, 0xaf, 0x87, 0xaf }, { 124, 0xaf, 0x87, 0xd7 },
{ 125, 0xaf, 0x87, 0xff }, { 126, 0xaf, 0xaf, 0x00 },
{ 127, 0xaf, 0xaf, 0x5f }, { 128, 0xaf, 0xaf, 0x87 },
{ 129, 0xaf, 0xaf, 0xaf }, { 130, 0xaf, 0xaf, 0xd7 },
{ 131, 0xaf, 0xaf, 0xff }, { 132, 0xaf, 0xd7, 0x00 },
{ 133, 0xaf, 0xd7, 0x5f }, { 134, 0xaf, 0xd7, 0x87 },
{ 135, 0xaf, 0xd7, 0xaf }, { 136, 0xaf, 0xd7, 0xd7 },
{ 137, 0xaf, 0xd7, 0xff }, { 138, 0xaf, 0xff, 0x00 },
{ 139, 0xaf, 0xff, 0x5f }, { 140, 0xaf, 0xff, 0x87 },
{ 141, 0xaf, 0xff, 0xaf }, { 142, 0xaf, 0xff, 0xd7 },
{ 143, 0xaf, 0xff, 0xff }, { 233, 0xb2, 0xb2, 0xb2 },
{ 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
{ 236, 0xd0, 0xd0, 0xd0 }, { 144, 0xd7, 0x00, 0x00 },
{ 145, 0xd7, 0x00, 0x5f }, { 146, 0xd7, 0x00, 0x87 },
{ 147, 0xd7, 0x00, 0xaf }, { 148, 0xd7, 0x00, 0xd7 },
{ 149, 0xd7, 0x00, 0xff }, { 150, 0xd7, 0x5f, 0x00 },
{ 151, 0xd7, 0x5f, 0x5f }, { 152, 0xd7, 0x5f, 0x87 },
{ 153, 0xd7, 0x5f, 0xaf }, { 154, 0xd7, 0x5f, 0xd7 },
{ 155, 0xd7, 0x5f, 0xff }, { 156, 0xd7, 0x87, 0x00 },
{ 157, 0xd7, 0x87, 0x5f }, { 158, 0xd7, 0x87, 0x87 },
{ 159, 0xd7, 0x87, 0xaf }, { 160, 0xd7, 0x87, 0xd7 },
{ 161, 0xd7, 0x87, 0xff }, { 162, 0xd7, 0xaf, 0x00 },
{ 163, 0xd7, 0xaf, 0x5f }, { 164, 0xd7, 0xaf, 0x87 },
{ 165, 0xd7, 0xaf, 0xaf }, { 166, 0xd7, 0xaf, 0xd7 },
{ 167, 0xd7, 0xaf, 0xff }, { 168, 0xd7, 0xd7, 0x00 },
{ 169, 0xd7, 0xd7, 0x5f }, { 170, 0xd7, 0xd7, 0x87 },
{ 171, 0xd7, 0xd7, 0xaf }, { 172, 0xd7, 0xd7, 0xd7 },
{ 173, 0xd7, 0xd7, 0xff }, { 174, 0xd7, 0xff, 0x00 },
{ 175, 0xd7, 0xff, 0x5f }, { 176, 0xd7, 0xff, 0x87 },
{ 177, 0xd7, 0xff, 0xaf }, { 178, 0xd7, 0xff, 0xd7 },
{ 179, 0xd7, 0xff, 0xff }, { 237, 0xda, 0xda, 0xda },
{ 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
{ 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
{ 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
{ 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
{ 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
{ 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
{ 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
{ 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
{ 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
{ 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
{ 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
{ 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
{ 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
{ 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
{ 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
{ 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
{ 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
{ 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
};
void colour_rgb_generate256(void);
u_int colour_rgb_distance(struct colour_rgb *, struct colour_rgb *);
int colour_rgb_find(struct colour_rgb *);
int colour_cmp_rgb(const void *, const void *);
/* Generate 256 colour RGB table. */
void
colour_rgb_generate256(void)
/* Compare function for bsearch(). */
int
colour_cmp_rgb(const void *lhs0, const void *rhs0)
{
struct colour_rgb *rgb;
u_int i, r, g, b;
const struct colour_rgb *lhs = lhs0, *rhs = rhs0;
/*
* 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);
if (lhs->r < rhs->r)
return (-1);
if (lhs->r > rhs->r)
return (1);
/* Add the colours first. */
r = g = b = 0;
for (i = 240; i > 24; i--) {
rgb = &colour_rgb_256[240 - i];
if (lhs->g < rhs->g)
return (-1);
if (lhs->g > rhs->g)
return (1);
if (r != 0)
rgb->r = (r * 40) + 55;
if (g != 0)
rgb->g = (g * 40) + 55;
if (b != 0)
rgb->b = (b * 40) + 55;
if (lhs->b < rhs->b)
return (-1);
if (lhs->b > rhs->b)
return (1);
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);
return (0);
}
/* Work out the nearest colour from the 256 colour set. */
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;
struct colour_rgb rgb = { .r = r, .g = g, .b = b }, *found;
u_int distance, lowest, colour, i;
int dr, dg, db;
if (colour_rgb_256 == NULL)
colour_rgb_generate256();
found = bsearch(&rgb, colour_to_256, nitems(colour_to_256),
sizeof colour_to_256[0], colour_cmp_rgb);
if (found != NULL)
return (16 + found->i);
colour = 16;
lowest = UINT_MAX;
for (i = 0; i < 240; i++) {
distance = colour_rgb_distance(&colour_rgb_256[i], rgb);
dr = (int)colour_from_256[i].r - r;
dg = (int)colour_from_256[i].g - g;
db = (int)colour_from_256[i].b - b;
distance = dr * dr + dg * dg + db * db;
if (distance < lowest) {
lowest = distance;
colour = 16 + i;
@@ -147,7 +361,7 @@ colour_tostring(int c)
static char s[32];
if (c & 0x100) {
xsnprintf(s, sizeof s, "colour%u", c & ~0x100);
xsnprintf(s, sizeof s, "colour%d", c & ~0x100);
return (s);
}
@@ -194,20 +408,20 @@ colour_tostring(int c)
int
colour_fromstring(const char *s)
{
const char *errstr;
const char *cp;
struct colour_rgb rgb;
int n;
const char *errstr;
const char *cp;
int n;
u_char r, g, b;
if (*s == '#' && strlen(s) == 7) {
for (cp = s + 1; isxdigit((u_char) *cp); cp++)
;
if (*cp != '\0')
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)
return (-1);
return (colour_rgb_find(&rgb) | 0x100);
return (colour_find_rgb(r, g, b) | 0x100);
}
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
@@ -217,47 +431,39 @@ colour_fromstring(const char *s)
return (n | 0x100);
}
if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0'))
if (strcasecmp(s, "black") == 0 || strcmp(s, "0") == 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);
if (strcasecmp(s, "green") == 0 || (s[0] == '2' && s[1] == '\0'))
if (strcasecmp(s, "green") == 0 || strcmp(s, "2") == 0)
return (2);
if (strcasecmp(s, "yellow") == 0 || (s[0] == '3' && s[1] == '\0'))
if (strcasecmp(s, "yellow") == 0 || strcmp(s, "3") == 0)
return (3);
if (strcasecmp(s, "blue") == 0 || (s[0] == '4' && s[1] == '\0'))
if (strcasecmp(s, "blue") == 0 || strcmp(s, "4") == 0)
return (4);
if (strcasecmp(s, "magenta") == 0 || (s[0] == '5' && s[1] == '\0'))
if (strcasecmp(s, "magenta") == 0 || strcmp(s, "5") == 0)
return (5);
if (strcasecmp(s, "cyan") == 0 || (s[0] == '6' && s[1] == '\0'))
if (strcasecmp(s, "cyan") == 0 || strcmp(s, "6") == 0)
return (6);
if (strcasecmp(s, "white") == 0 || (s[0] == '7' && s[1] == '\0'))
if (strcasecmp(s, "white") == 0 || strcmp(s, "7") == 0)
return (7);
if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0'))
if (strcasecmp(s, "default") == 0 || strcmp(s, "8") == 0)
return (8);
if (strcasecmp(s, "brightblack") == 0 ||
(s[0] == '9' && s[1] == '0' && s[1] == '\0'))
if (strcasecmp(s, "brightblack") == 0 || strcmp(s, "90") == 0)
return (90);
if (strcasecmp(s, "brightred") == 0 ||
(s[0] == '9' && s[1] == '1' && s[1] == '\0'))
if (strcasecmp(s, "brightred") == 0 || strcmp(s, "91") == 0)
return (91);
if (strcasecmp(s, "brightgreen") == 0 ||
(s[0] == '9' && s[1] == '2' && s[1] == '\0'))
if (strcasecmp(s, "brightgreen") == 0 || strcmp(s, "92") == 0)
return (92);
if (strcasecmp(s, "brightyellow") == 0 ||
(s[0] == '9' && s[1] == '3' && s[1] == '\0'))
if (strcasecmp(s, "brightyellow") == 0 || strcmp(s, "93") == 0)
return (93);
if (strcasecmp(s, "brightblue") == 0 ||
(s[0] == '9' && s[1] == '4' && s[1] == '\0'))
if (strcasecmp(s, "brightblue") == 0 || strcmp(s, "94") == 0)
return (94);
if (strcasecmp(s, "brightmagenta") == 0 ||
(s[0] == '9' && s[1] == '5' && s[1] == '\0'))
if (strcasecmp(s, "brightmagenta") == 0 || strcmp(s, "95") == 0)
return (95);
if (strcasecmp(s, "brightcyan") == 0 ||
(s[0] == '9' && s[1] == '6' && s[1] == '\0'))
if (strcasecmp(s, "brightcyan") == 0 || strcmp(s, "96") == 0)
return (96);
if (strcasecmp(s, "brightwhite") == 0 ||
(s[0] == '9' && s[1] == '7' && s[1] == '\0'))
if (strcasecmp(s, "brightwhite") == 0 || strcmp(s, "97") == 0)
return (97);
return (-1);
}

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
@@ -176,9 +174,15 @@ typedef uint64_t u_int64_t;
#define TTY_NAME_MAX 32
#endif
#ifndef HAVE_BZERO
#undef bzero
#define bzero(buf, len) memset(buf, 0, len);
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif
#ifndef HAVE_FLOCK
#define LOCK_SH 0
#define LOCK_EX 0
#define LOCK_NB 0
#define flock(fd, op) (0)
#endif
#ifndef HAVE_CLOSEFROM
@@ -239,6 +243,10 @@ int vasprintf(char **, const char *, va_list);
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_FPARSELN
char *fparseln(FILE *, size_t *, size_t *, const char *, int);
#endif
#ifndef HAVE_SETENV
/* setenv.c */
int setenv(const char *, const char *, int);

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
*
@@ -56,10 +54,12 @@ vasprintf(char **ret, const char *fmt, va_list ap)
free(*ret);
goto error;
}
va_end(ap2);
return (n);
error:
va_end(ap2);
*ret = NULL;
return (-1);
}

View File

@@ -1,4 +1,3 @@
/* $Id$ */
/* $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 $ */

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* Copyright (c) 2013 Dagobert Michelsen
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* Copyright (c) 2004-2005 Todd C. Miller <Todd.Miller@courtesan.com>
*

View File

@@ -1,4 +1,3 @@
/* $Id$ */
/* $OpenBSD: daemon.c,v 1.6 2005/08/08 08:05:33 espie Exp $ */
/*-
* Copyright (c) 1990, 1993

View File

@@ -1,4 +1,3 @@
/* $Id$ */
/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
/*-

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
@@ -23,21 +21,29 @@
#include <stdlib.h>
#include <stropts.h>
#include <unistd.h>
#include <errno.h>
#include "tmux.h"
pid_t
forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
{
int slave, fd;
char *path;
int slave = -1, fd, pipe_fd[2];
char *path, dummy;
pid_t pid;
if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1)
if (pipe(pipe_fd) == -1)
return (-1);
if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1)
goto out;
if ((path = ttyname(*master)) == NULL)
goto out;
if (name != NULL)
strlcpy(name, path, TTY_NAME_MAX);
if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
goto out;
@@ -47,6 +53,13 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
case 0:
close(*master);
close(pipe_fd[1]);
while (read(pipe_fd[0], &dummy, 1) == -1) {
if (errno != EINTR)
break;
}
close(pipe_fd[0]);
fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
if (fd >= 0) {
ioctl(fd, TIOCNOTTY, NULL);
@@ -80,10 +93,14 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
dup2(slave, 2);
if (slave > 2)
close(slave);
return (0);
}
close(slave);
close(pipe_fd[0]);
close(pipe_fd[1]);
return (pid);
out:
@@ -91,5 +108,8 @@ out:
close(*master);
if (slave != -1)
close(slave);
close(pipe_fd[0]);
close(pipe_fd[1]);
return (-1);
}

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
@@ -29,7 +27,7 @@
pid_t
forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
{
int slave;
int slave = -1;
char *path;
pid_t pid;

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
@@ -30,7 +28,7 @@
pid_t
forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
{
int slave;
int slave = -1;
char *path;
pid_t pid;

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