354 Commits
1.1 ... 1.3

Author SHA1 Message Date
no_author
946fd162ba This commit was manufactured by cvs2svn to create tag 'TMUX_1_3'. 2010-07-18 13:41:00 +00:00
Tiago Cunha
9b47a48393 Changes for 1.3. 2010-07-18 13:40:59 +00:00
Tiago Cunha
0482983d53 Done. 2010-07-18 13:39:02 +00:00
Tiago Cunha
2b512dc49d Bump VERSION, and comment FDEBUG. 2010-07-18 13:36:52 +00:00
Tiago Cunha
ae45c2ea45 Sync OpenBSD patchset 736:
some escapes i missed;
2010-07-17 14:39:01 +00:00
Tiago Cunha
11f81e8134 Sync OpenBSD patchset 735:
Make pane/window wrapping more logical (so with 10 windows, +10 from
window 5 stays in the same place), and tidy the code. From Tiago Cunha.
2010-07-17 14:38:13 +00:00
Tiago Cunha
ad6a528f61 Sync OpenBSD patchset 734:
Return the command client return code with MSG_EXIT now that MSG_ERROR and
MSG_PRINT are unused.

New clients should be compatible with old tmux servers but vice versa may print
an error.
2010-07-17 14:36:41 +00:00
Tiago Cunha
46f27eab22 Sync OpenBSD patchset 733:
replace some magic mouse constants with defines for clarity. ok nicm
2010-07-02 02:56:07 +00:00
Tiago Cunha
e4703bacb5 Sync OpenBSD patchset 732:
Custom layouts. list-windows command displays the layout as a string (such as
"bb62,159x48,0,0{79x48,0,0,79x48,80,0}") and it can be applied to another
window (with the same number of panes or fewer) using select-layout.
2010-07-02 02:54:52 +00:00
Tiago Cunha
e4573de97b Sync OpenBSD patchset 731:
Send all three of stdin, stdout, stderr from the client to the server, so that
commands can directly make use of them. This means that load-buffer and
save-buffer can have "-" as the file to read from stdin or write to stdout.

This is a protocol version bump so the tmux server will need to be restarted
after upgrade (or an older client used).
2010-07-02 02:52:13 +00:00
Tiago Cunha
63e76b555d Sync OpenBSD patchset 730:
Store the current working directory in the session, change the default-path
option to default to empty and make that mean that the stored session CWD is
used.
2010-07-02 02:49:19 +00:00
Tiago Cunha
13e7f060b1 Update. 2010-07-02 02:46:39 +00:00
Tiago Cunha
fa34c76275 Sync OpenBSD patchset 729:
New option, detach-on-destroy, to set what happens to a client when the session
it is attached to is destroyed. If on (the default), it is detached; if off, it
is switched to the most recently active session.
2010-07-02 02:45:52 +00:00
Tiago Cunha
985cd3a4de Sync OpenBSD patchset 728:
Use server_destroy_session() for kill-session.
2010-07-02 02:43:50 +00:00
Tiago Cunha
03c1c1cd9f Sync OpenBSD patchset 727:
Setting the cmdlist pointer in the bind-key to NULL to prevent it being freed
after the command is executing is bogus because it may still be needed if the
same command is going to be executed again (for example if you "bind-key a
bind-key b ..."). Making a copy is hard, so instead add a reference count to
the cmd_list.

While here, also print bind-key -n and the rest of the flags properly.

Fixes problem reported by mcbride@.
2010-07-02 02:43:01 +00:00
Tiago Cunha
0e70c8801c Update. 2010-06-22 23:37:28 +00:00
Tiago Cunha
617386370b Nuke vis.h. 2010-06-22 23:36:54 +00:00
Tiago Cunha
bf1e237410 Sync OpenBSD patchset 726:
Add a choose-buffer command for easier use of the paste buffer stack.
2010-06-22 23:35:20 +00:00
Tiago Cunha
8d3b726396 Sync OpenBSD patchset 725:
Extend the -t:+ and -t:- window targets for next and previous window to
accept an offset such as -t:+2. From Tiago Cunha.
2010-06-22 23:29:05 +00:00
Tiago Cunha
47b335dee7 Sync OpenBSD patchset 724:
Having a list of winlinks->alerts for each session is stupid, just store
the alert flags directly in the winlink itself.
2010-06-22 23:26:18 +00:00
Tiago Cunha
6c76724201 Sync OpenBSD patchset 723:
Rename activity->alert in a couple of functions for consistency.
2010-06-22 23:22:31 +00:00
Tiago Cunha
29434cb043 Sync OpenBSD patchset 722:
Give tmux sockets (but not the containing folder) group
permissions. This allows hardlinks to the sockets to be used more
easily.
2010-06-22 23:21:39 +00:00
Nicholas Marriott
b7454e37cb Done. 2010-06-21 00:19:44 +00:00
Nicholas Marriott
e2a5e02022 +. 2010-06-21 00:13:13 +00:00
Micah Cowan
cac532c3d1 Ensure we overwrite wide characters properly, and never overwrite characters we weren't overlapping.
Fixes "disappearing wide characters" glitch.
2010-06-16 18:09:23 +00:00
Tiago Cunha
e186450788 Sync OpenBSD patchset 720:
Last change erroneously used the target argument for looking up the
client which caused pipe-pane to fail when used from the command
line. Instead pass NULL which should use the current client.

Spotted by Tiago Cunha.
2010-06-15 20:25:40 +00:00
Tiago Cunha
3e8092709c Sync OpenBSD patchset 719:
Add a missing command and some missing Ic, from Tiago Cunha.
2010-06-15 20:24:52 +00:00
Nicholas Marriott
1b77ae2684 +. 2010-06-13 11:28:26 +00:00
Tiago Cunha
60134cebda imsg was moved into libutil on OpenBSD. 2010-06-06 13:00:47 +00:00
Tiago Cunha
f34861bad4 Sync OpenBSD patchset 717:
Couple of missing command aliases/flags, from Tiago Cunha.
2010-06-06 00:31:32 +00:00
Tiago Cunha
6503207185 Sync OpenBSD patchset 716:
Fix problems with window sizing seen by Raghavendra D Prabhu when
starting tmux from .xinitrc.

One of the very few things the server relies on the client for now is to
pass through a message on SIGWINCH, but there is a condition where
potentially a SIGWINCH may be lost during the transition from unattached
(main.c) to attached (client.c). So trigger a size change immediately
after the client installs its SIGWINCH handler.

Also, when the terminal is resized, reset the scroll region and cursor
position. Previously, we were clearing our saved idea of these, but in
fact some terminals do not reset them on resize, so this caused problems
during redraw.

While here make a resize to the same size not cause a redraw and rename
the tmux.out output log file to include the tmux PID.
2010-06-06 00:30:34 +00:00
Tiago Cunha
3bba401609 Sync OpenBSD patchset 715:
Support the status_replace # replacement sequences in the pipe-pane
command, thanks to Andrea Barisani.
2010-06-06 00:28:00 +00:00
Tiago Cunha
31657820bc Sync OpenBSD patchset 714:
Shut up gcc4 warnings.
2010-06-06 00:27:08 +00:00
Tiago Cunha
be3643fba0 Sync OpenBSD patchset 713:
This ioctl(TIOCGWINSZ) call is no longer necessary, the result is never
used and the server now does it later on the tty fd directly.
2010-06-06 00:25:47 +00:00
Tiago Cunha
f62d3d22bb Sync OpenBSD patchset 710:
When the mode-mouse option is on, support dragging to make a selection
in copy mode.

Also support the scroll wheel, although xterm strangely does not ignore
it in application mouse mode, causing redraw artifacts when scrolling up
(other terminals appear to be better behaved).
2010-06-06 00:23:44 +00:00
Tiago Cunha
67dc249d0e Sync OpenBSD patchset 709:
Better to say "command key bindings" since we've just called them
command keys.
2010-06-06 00:21:36 +00:00
Tiago Cunha
0778ef230b Sync OpenBSD patchset 708:
There is no real reason not to list all the key bindings here rather
than just a selection.
2010-06-06 00:20:53 +00:00
Tiago Cunha
bebfd7c2c8 Sync OpenBSD patchset 706:
Rename some imsg bits to make namespace collisions less likely buf to
ibuf, buf_read to ibuf_read, READ_BUF_SIZE to IBUF_READ_SIZE.
2010-06-06 00:08:28 +00:00
Tiago Cunha
348c3e69de Sync OpenBSD patchset 705:
Don't die if the client has been detached when the job finishes, just
don't display the output.
2010-06-06 00:04:59 +00:00
Tiago Cunha
0d6a64070c Sync OpenBSD patchset 704:
Fix an out-of-date comment.
2010-06-06 00:04:18 +00:00
Tiago Cunha
bb4d770e45 No vis.h in here. 2010-06-06 00:03:02 +00:00
Tiago Cunha
e55a59eebc Sync OpenBSD patchset 702:
Enhance paste-buffer to allow lines to be separated by any string, from
Andrea Barisani.
2010-06-06 00:01:36 +00:00
Tiago Cunha
11cd05db27 Sync OpenBSD patchset 701:
Colour+attribute options for status line alerts, from Alex Alexander.
2010-06-05 23:56:29 +00:00
Tiago Cunha
6c6255f2d7 Sync OpenBSD patchset 700:
Accept (and document) "none" instead of "default" for attributes as it
is clearer and avoids confusion with default colours.
2010-06-05 23:54:51 +00:00
Micah Cowan
227e458ebb Use a macro-based mask for obtaining a key or modifier-set from the combination.
Display C-@, etc, as C-Space, in list-keys.
2010-06-05 20:29:11 +00:00
Nicholas Marriott
89eb95265a Must allocate for putenv. 2010-06-05 18:20:48 +00:00
Nicholas Marriott
d98efa5378 Only need to build setenv.c once. 2010-06-05 18:14:29 +00:00
Nicholas Marriott
a9c6976268 Should be const char *. 2010-06-05 16:29:40 +00:00
Micah Cowan
d9c99b83c7 Make double start-of-line do what double end-of-line does, on wrapped lines. 2010-06-05 07:48:35 +00:00
Micah Cowan
d27956f160 Allow C-Space to work correctly once again, and forbid nonsensical combinations such as C-Enter or C-Escape. 2010-06-05 06:27:19 +00:00
Nicholas Marriott
e334deb872 +. 2010-05-27 08:29:17 +00:00
Nicholas Marriott
e50dc0745f +. 2010-05-24 18:21:07 +00:00
Micah Cowan
f11f71752a Pass in the session, rather than the client, to window modes' key() function.
We were only ever using the client to find the session anyway.
2010-05-22 21:56:04 +00:00
Nicholas Marriott
9e7a5fa5ef Spacing nits. 2010-05-19 21:49:57 +00:00
Nicholas Marriott
9c01a3d0db Solaris 9 is missing CMSG_ALIGN and some of the RFC2292 CMSG_*. From
Dagobert Michelsen.
2010-05-19 21:40:49 +00:00
Nicholas Marriott
278effd7ea Solaris 9 doesn't have setenv and unsetenv so add compat versions, based
on code from Dagobert Michelsen.
2010-05-19 21:31:39 +00:00
Nicholas Marriott
59c13133de Fix bad merge, from Romain Francoise. 2010-05-16 17:50:31 +00:00
Nicholas Marriott
41afc38dcc +. 2010-05-14 19:05:06 +00:00
Tiago Cunha
0beb31c261 Update. 2010-05-14 14:38:50 +00:00
Tiago Cunha
6694a01861 Sync OpenBSD patchset 698:
Catch SIGHUP and terminate if running as a client. This prevents clients
from being left hanging around when, for example, a SSH session is
disconnected.

ok nicm@
2010-05-14 14:35:26 +00:00
Tiago Cunha
9900e28ba8 Sync OpenBSD patchset 697:
Identical behaviour to select-prompt can now be obtained with
command-prompt, so remove select-prompt and change ' to be bound to
command-prompt -p index "select-window -t :%%".
2010-05-14 14:33:39 +00:00
Tiago Cunha
fc69b9ccb7 Sync OpenBSD patchset 696:
Make signal handler setup/teardown two common functions instead of six,
and reset SIGCHLD after fork to fix problems with some shells. From
Romain Francoise.
2010-05-14 14:30:01 +00:00
Tiago Cunha
d3dd6709bc Sync OpenBSD patchset 693:
Make C-] and other punctuation-based control key combinations work again.

ok nicm
2010-05-14 14:21:07 +00:00
Tiago Cunha
3cded44623 Sync OpenBSD patchset 692:
sort options.
2010-05-14 14:19:41 +00:00
Tiago Cunha
50cad52ae6 Sync OpenBSD patchset 691:
Make the active pane border have a green foreground instead of
background by default.
2010-05-14 14:18:54 +00:00
Tiago Cunha
701b5bdf61 Sync OpenBSD patchset 688:
Add a tiled layout, originally from Liam Bedford a while ago, fixed up
by me.
2010-05-14 14:16:37 +00:00
Nicholas Marriott
4e120c00f7 Use LC_ALL for sed too since apparently some platforms play silly games
in other locales.
2010-05-12 19:47:25 +00:00
Nicholas Marriott
7d4588f470 +. 2010-05-12 19:21:15 +00:00
Nicholas Marriott
893be14cf8 +. 2010-04-28 19:08:40 +00:00
Micah Cowan
342a47bc77 Avoid crashing in copy-mode during resize, when our history-viewing offset is larger than the new total number of history lines. 2010-04-28 14:29:27 +00:00
Nicholas Marriott
18ed37622e When converting A-Z into a control character, want to subtract 64 not
65... whoops.
2010-04-23 20:33:08 +00:00
Nicholas Marriott
ec56ec7920 Use INSTALL so people on Solaris can set it to ginstall. 2010-04-23 07:38:36 +00:00
Nicholas Marriott
0c5a964e63 Support NetBSD 6 which will now have its own terminfo (yay). 2010-04-23 07:29:39 +00:00
Tiago Cunha
c4c542efb9 Sync OpenBSD patchset 686:
Mark zombie windows as dead in choose-window list, from Romain Francoise.
2010-04-22 21:51:27 +00:00
Tiago Cunha
2bc150d16d Sync OpenBSD patchset 685:
Rewrite key string conversions to be readable and to work properly for
multiple modifiers.
2010-04-22 21:50:30 +00:00
Tiago Cunha
7163907ab6 Sync OpenBSD patchset 684:
Catch SIGCHLD to avoid a zombie, from patrick keshishian.
2010-04-22 21:48:49 +00:00
Nicholas Marriott
02fc1fe0da Done. 2010-04-21 21:35:07 +00:00
Nicholas Marriott
8e67b07489 Don't set user and group with install, from Nicolas Pinto. 2010-04-21 21:22:06 +00:00
Tiago Cunha
0ed80637e7 Sync OpenBSD patchset 683:
Fix typo in escape state table leading to fatal() when \033} or \033~
was entered, from Chris Johnsen.
2010-04-18 15:11:47 +00:00
Tiago Cunha
b03418fc6b Sync OpenBSD patchset 682:
If remain-on-exit is set, both the error callback and a SIGCHLD could
destroy the same pane (because the first one doesn't remove it from the
list of panes), causing the pane bufferevent to be freed twice. So don't
free it if the fd has already been set to -1, from Romain Francoise.
2010-04-18 15:10:55 +00:00
Nicholas Marriott
c0f03afbac +. 2010-04-18 07:37:09 +00:00
Tiago Cunha
0646b3caf2 Sync OpenBSD patchset 680:
Remove XXX comment and just close received fd if calloc() fails.

If this happens the imsg may no longer be usable as there may be queued
messages, but this is a) already the case with the code now, and b)
would be the case if recvmsg() fails anyway, so we can document that -1
from imsg_read() invalidates the struct imsgbuf.

discussed with and ok eric
2010-04-12 21:45:18 +00:00
Micah Cowan
b2e752b384 Don't try to use a window-link that may have been freed.
In the case where a join-pane is performed from within a grouped session,
and the source pane had no siblings in the window (causing the window to
be destroyed), there was an invalid access of the destination window
link (which had been destroyed as part of the group session's
resynchronization with the original session, due to killing the
now-empty source window).
CVS: ----------------------------------------------------------------------
CVS: Enter Log.  Lines beginning with `CVS:' are removed automatically
CVS:
CVS: Committing in .
CVS:
CVS: Modified Files:
CVS: 	cmd-join-pane.c
CVS: ----------------------------------------------------------------------
2010-04-09 07:09:37 +00:00
Nicholas Marriott
08632b4f0a there can be only one rpathbuf 2010-04-08 07:54:43 +00:00
Nicholas Marriott
10b73b7a11 Sync nit. 2010-04-06 22:08:10 +00:00
Nicholas Marriott
cd0f22b96e Unbreak. Whoops. 2010-04-06 22:02:52 +00:00
Nicholas Marriott
610056abbe Man page sync. 2010-04-06 22:02:03 +00:00
Nicholas Marriott
3743238a86 From Bob Beck:
rather than using an empty "" as the default window title, put the hostname
of the machine we are running on in there.

makes my many green lines easier to deal with without using fiddly options to
set it.
2010-04-06 22:01:32 +00:00
Nicholas Marriott
531db321e3 -s src-pane. 2010-04-06 21:59:59 +00:00
Nicholas Marriott
642f549e4d Dead assignment. 2010-04-06 21:59:37 +00:00
Nicholas Marriott
0fc65537a3 Run job commands explicitly in the global enviroment (which can be
modified with setenv -g) rather than with the environment tmux started
with.
2010-04-06 21:59:19 +00:00
Nicholas Marriott
091db41bc9 Squash a function that is only called in a callback into the
callback function.
2010-04-06 21:58:33 +00:00
Nicholas Marriott
67300e9524 Stupid style nits. 2010-04-06 21:45:36 +00:00
Nicholas Marriott
f2a4ef5260 window-more.c is now defunct. 2010-04-06 10:53:41 +00:00
Nicholas Marriott
7dc1720522 +. 2010-04-05 22:28:56 +00:00
Nicholas Marriott
07dcf8610f FreeBSD kqueue is broken before 8. 2010-04-05 22:28:25 +00:00
Micah Cowan
2d74ce1d3a Merge output (more) and copy modes into one single mode (called copy). 2010-04-05 05:11:44 +00:00
Nicholas Marriott
5879e2a32b libevent needs librt on Linux, from Aaron Isotton. 2010-04-02 21:26:40 +00:00
Nicholas Marriott
1392fba63d Don't accept keys with modifiers as input. Fixes crash reported by Brian
R Landy.
2010-03-31 18:24:08 +00:00
Nicholas Marriott
1c6ab725f5 +. 2010-03-29 18:54:07 +00:00
Nicholas Marriott
4012917302 Nuke unused functions. 2010-03-27 15:12:56 +00:00
Nicholas Marriott
dd7abd9b4c -a flag to insert a window after an existing one, moving other windows
up as necessary.
2010-03-27 15:12:11 +00:00
Nicholas Marriott
51c776fe93 +. 2010-03-27 13:43:13 +00:00
Nicholas Marriott
9382e546df +. 2010-03-18 21:10:11 +00:00
Nicholas Marriott
659d15786a Reset output functions too when changing client after attaching. 2010-03-18 21:06:40 +00:00
Nicholas Marriott
2307b91ecb paste-buffer should be per pane, from C. Coutinho. 2010-03-18 21:02:41 +00:00
Nicholas Marriott
a2c87eb899 Unused variable. 2010-03-16 23:40:14 +00:00
Nicholas Marriott
33a90efc93 Minor Nazi style tweaks to previous, and man page rephrasery. 2010-03-16 17:51:32 +00:00
Micah Cowan
009d8d2ea7 Jump-forward, jump-backward in copy mode, based on vi's F and f commands. 2010-03-16 17:30:58 +00:00
Nicholas Marriott
aa8f9018ea Support up, down, left, right movement through panes with -UDLR flags to
select-pane.

Also remove up- and down-pane: equivalent behaviour is now available
using -t :.+ and -t :.-.
2010-03-15 22:03:38 +00:00
Nicholas Marriott
4de04fac2c Accept a full key match (not a partial) even if there is data left in
the buffer.
2010-03-15 20:44:51 +00:00
Nicholas Marriott
593bcbdd49 +. 2010-03-15 16:09:49 +00:00
Nicholas Marriott
9f5b9ba0d6 New input parser based on http://vt100.net/emu/dec_ansi_parser. 2010-03-15 12:51:23 +00:00
Nicholas Marriott
b1a3090877 + an item. 2010-03-14 23:46:52 +00:00
Nicholas Marriott
4271320bb7 Quick prioritise for 1.3. 2010-03-14 23:46:09 +00:00
Nicholas Marriott
51eab54102 Avoid use-after-free when cancelling copy mode. 2010-03-14 23:17:59 +00:00
Nicholas Marriott
51c135ed73 +. 2010-03-10 23:32:49 +00:00
Nicholas Marriott
f6d36e60cf Mention dependencies. 2010-03-10 22:13:17 +00:00
Tiago Cunha
38bc7e87c5 Working on 1.3. 2010-03-10 15:44:13 +00:00
Tiago Cunha
95c6d9d31d Done. 2010-03-10 15:18:49 +00:00
Tiago Cunha
3d85d2be6a Update CHANGES, and NOTES for the 1.2 release. 2010-03-10 15:18:11 +00:00
Tiago Cunha
6681db7af0 Bump VERSION. 2010-03-10 15:16:19 +00:00
Tiago Cunha
b90e869b8b Prepare the tree for the 1.2 release. 2010-03-10 15:15:33 +00:00
Nicholas Marriott
de64913786 Plug memory leak, from Gregory Thiemonge. 2010-03-10 13:41:13 +00:00
Tiago Cunha
b34c8f5f39 Sync OpenBSD patchset 658:
Permit keys in copy mode to be prefixed by a repeat count, entered with
[1-9] in vi mode, or M-[1-9] in emacs mode.

From Micah Cowan, tweaked a little by me.
2010-03-08 15:02:07 +00:00
Tiago Cunha
70f5384d8f Sync OpenBSD patchset 657:
Extend the end-of-line key so that in normal mode a second press moves
the cursor to the end of a wrapped line (if present) and in rectangle
mode it toggles between the end of the text and the last cell on the
line.

From Micah Cowan.
2010-03-08 14:56:17 +00:00
Tiago Cunha
a2cd71ff03 Sync OpenBSD patchset 656:
Check for colour and attribute modifications early so the translated
values can be stored in the cached terminal attributes rather than the
requested (untranslated) values. Prevents tmux clearing and setting the
attributes for every character when using aixterm colours.
2010-03-08 14:53:49 +00:00
Nicholas Marriott
990971f486 +. 2010-03-06 13:24:35 +00:00
Nicholas Marriott
ce3fff4dbb +. 2010-03-01 23:56:46 +00:00
Nicholas Marriott
1533930c11 Some done, some tidying, some added. 2010-03-01 22:56:36 +00:00
Nicholas Marriott
14a5071ce0 + and -. 2010-03-01 22:16:07 +00:00
Tiago Cunha
c5fefd51af Sync OpenBSD patchset 655:
Typo fix from Tim van der Molen.
2010-02-26 13:35:04 +00:00
Tiago Cunha
862b89b78b Sync OpenBSD patchset 654:
Don't set the terminal to nonblocking on detach until we have finished with it
entirely.
2010-02-26 13:34:15 +00:00
Tiago Cunha
5920a55a87 Update. 2010-02-26 13:33:22 +00:00
Tiago Cunha
b7d5b911ac Sync OpenBSD patchset 653:
Option to set the characters considered word separators in copy mode, from
Micah Cowan.
2010-02-26 13:31:39 +00:00
Tiago Cunha
8da8bc477f Sync OpenBSD patchset 652:
In load-buffer, read until EOF rather than using stat() and reading a fixed
size. Allows use of FIFOs and whatnot. From Tiago Cunha, idea from Fulvio
Ciriaco.
2010-02-26 13:30:07 +00:00
Tiago Cunha
a0e7539743 Sync OpenBSD patchset 651:
Another copy mode fix from Micah Cowan: in rectangle copy mode, the cursor
should not wrap at the end of the text on the line but should be allowed to
move freely.
2010-02-26 13:29:25 +00:00
Tiago Cunha
f7ae833b6d Sync OpenBSD patchset 650:
Display -t argument to new-session, from Tiago Cunha.
2010-02-26 13:28:15 +00:00
Tiago Cunha
8dcb62cd87 Sync OpenBSD patchset 649:
have_arg matches buf so it is no longer necessary, spotted by Tim van der
Molen.
2010-02-26 13:27:38 +00:00
Tiago Cunha
ecac081a55 Sync OpenBSD patchset 648:
copy mode uses the real screen as backing and if it is updated while copying,
strange things can happen. So, freeze reading from the pty while in copy mode.
2010-02-26 13:26:44 +00:00
Nicholas Marriott
b4c2710bf7 +. 2010-02-24 19:03:36 +00:00
Nicholas Marriott
7da60e78c6 + 2010-02-24 00:55:20 +00:00
Tiago Cunha
f7646d2738 Sync OpenBSD patchset 647:
Make next-word stop at beginning of word even if it is at the start of the
line, from Micah Cowan.
2010-02-18 12:38:24 +00:00
Tiago Cunha
3f44ab2f0f Sync OpenBSD patchset 646:
Man page additions/improvements, thanks to Robin Lee Powell.
2010-02-18 12:37:30 +00:00
Tiago Cunha
a9dacf10ce Sync OpenBSD patchset 645:
Don't strip add newline if only copying part of wrapped line. Problem spotted
by and fix from Micah Cowan.
2010-02-18 12:36:18 +00:00
Tiago Cunha
66c38d8c5d Sync OpenBSD patchset 644:
Add "N" key to search the opposite way from the last search (reverse of "n"),
from Micah Cowan.
2010-02-18 12:35:16 +00:00
Tiago Cunha
736764b560 Sync OpenBSD patchset 643:
Clarify default status-right, from Seth Wright.
2010-02-18 12:33:52 +00:00
Nicholas Marriott
a00a0cd0c1 +. 2010-02-17 21:17:24 +00:00
Nicholas Marriott
3d99e261a1 +. 2010-02-11 21:16:11 +00:00
Tiago Cunha
2e6142ab84 Update. 2010-02-08 18:33:21 +00:00
Tiago Cunha
10abdd97cf Sync OpenBSD patchset 642:
Add an option to disable the smcup/rmcup alternate screen behaviour inside
tmux. From clemens fischer.
2010-02-08 18:32:34 +00:00
Tiago Cunha
c3c65c32a5 Sync OpenBSD patchset 641:
next-layout is bound to Space not C-Space.
2010-02-08 18:31:07 +00:00
Tiago Cunha
36a80b2cd6 Sync OpenBSD patchset 640:
Use the array.h code for the causes list.
2010-02-08 18:29:32 +00:00
Tiago Cunha
c6ba781379 Sync OpenBSD patchset 639:
Support attaching a client read-only with a new -r flag to the attach-session
command.
2010-02-08 18:27:34 +00:00
Tiago Cunha
9b57743cca Sync OpenBSD patchset 638:
Change nested check to compare server socket path rather than just assuming
that if $TMUX is set it is nested. From Micah Cowan.
2010-02-08 18:25:04 +00:00
Tiago Cunha
ac8aa0bc0f Sync OpenBSD patchset 637:
Clean up $TMUX parsing, from Micah Cowan, tweaked by me.
2010-02-08 18:23:48 +00:00
Tiago Cunha
3c37b09272 Sync OpenBSD patchset 636:
Rectangle copy support, from Robin Lee Powell.
2010-02-08 18:13:17 +00:00
Tiago Cunha
a32d095c97 Sync OpenBSD patchset 635:
Instead of bailing out on the first configuration file error, carry on,
collecting all the errors, then start with the active window in more mode
displaying them.
2010-02-08 18:10:07 +00:00
Tiago Cunha
676d0809d2 Update. 2010-02-05 02:09:27 +00:00
Tiago Cunha
fa5be75396 Sync OpenBSD patchset 634:
vi-style B, W and E keys in copy mode to navigate between words treating only
spaces as word separators. Also add . to the list of word separators for
standard word navigation.

From Micah Cowan, tweaked slightly by me.
2010-02-05 01:34:08 +00:00
Tiago Cunha
d398bbc53b Sync OpenBSD patchset 633:
Read the path from $TMUX if it is present and -L and -S are not given. Based on
a diff from Micah Cowan.
2010-02-05 01:32:10 +00:00
Tiago Cunha
82ba7e69ec Sync OpenBSD patchset 632:
Option to display the active pane in a different colour with the display-panes
command. From Paul Hoffman, thanks.
2010-02-05 01:31:06 +00:00
Tiago Cunha
23fb261b85 Sync OpenBSD patchset 631:
Fix divide by zero on small windows with main-* layouts.
2010-02-05 01:29:04 +00:00
Nicholas Marriott
0d5542e65e +. 2010-02-04 21:01:59 +00:00
Nicholas Marriott
d6b5b644b8 +. 2010-02-03 23:47:22 +00:00
Tiago Cunha
b7758a9932 Make it detect multiple options with a single leading `-' (eg set -gw). 2010-02-03 00:21:48 +00:00
Tiago Cunha
ebcc0ebd2d Sync OpenBSD patchset 630:
If redrawing line 0 of the screen onto the tty, there can't be a wrap flag on
the previous line, so move the cursor. Fixes status line redraw issues when
resizing in choose mode and hopefully at other times as well.
2010-02-02 23:56:25 +00:00
Tiago Cunha
c4724c7861 Sync OpenBSD patchset 629:
Add scroll-up/scroll-down for choose/more mode, from Micah Cowan.
2010-02-02 23:55:21 +00:00
Tiago Cunha
998d76c6b4 Sync OpenBSD patchset 628:
Remove unnecessary comparison, pointed out by Tiago Cunha.
2010-02-02 23:53:36 +00:00
Tiago Cunha
495a3056e9 Sync OpenBSD patchset 626:
Don't stop parsing command sequences when a command requests the client to
stick around (attach-session/new-session).
2010-02-02 23:51:04 +00:00
Tiago Cunha
3116e3ce21 Sync OpenBSD patchset 625:
Ignore SIGHUP as well.
2010-02-02 23:50:01 +00:00
Nicholas Marriott
4e28426c0d Old comment. 2010-02-02 21:34:16 +00:00
Nicholas Marriott
9ea05dc2ba +. 2010-01-30 23:53:07 +00:00
Tiago Cunha
72dd70b0c0 Sync OpenBSD patchset 624:
Typo, from Micah Cowan.
2010-01-28 22:48:04 +00:00
Tiago Cunha
5ef8689328 Sync OpenBSD patchset 623:
Actually bind the new key to e.
2010-01-28 22:47:21 +00:00
Tiago Cunha
95dfa950b8 Sync OpenBSD patchset 622:
Calculate offset correctly, fixes incorrect offset and prevents crash when
status-left is empty. From Micah Cowan.
2010-01-28 22:46:44 +00:00
Tiago Cunha
735cfaf09a Sync OpenBSD patchset 621:
Alter next-word to have vi-like movement behaviour, and add next-word-end with
the existing emacs behaviour. From Micah Cowan.
2010-01-28 22:45:57 +00:00
Tiago Cunha
0e320881d5 Sync OpenBSD patchset 620:
Actually use the copy made when no newline is found, from martynas@.
2010-01-28 22:44:16 +00:00
Tiago Cunha
1a6cb5fd54 Sync OpenBSD patchset 619:
Hugely simplify window_copy_cursor_next_word, which was way overcomplicated.
2010-01-28 22:43:24 +00:00
Tiago Cunha
22dd0beaa0 Sync OpenBSD patchset 618:
Update the selection properly after goto line or searching.
2010-01-28 22:42:36 +00:00
Tiago Cunha
c153a43299 Sync OpenBSD patchset 617:
Top/bottom of history mode keys, diff from Micah Cowan, tweaked by me.
2010-01-28 22:41:45 +00:00
Nicholas Marriott
0b05e6d8cb +. 2010-01-25 20:38:50 +00:00
Tiago Cunha
2305a27308 Sync OpenBSD patchset 616:
Redraw properly when scrolling backward and the cursor is on the last
line. Based on a fix from Micah Cowan.
2010-01-25 17:14:42 +00:00
Tiago Cunha
391b209008 Sync OpenBSD patchset 615:
When a window is destroyed, remove all links to it from each session rather
than just the first. Reported by Robin Lee Powell.
2010-01-25 17:13:43 +00:00
Tiago Cunha
c744964cd9 Sync OpenBSD patchset 614:
Don't leak if arguments appear multiple times, from Tiago Cunha.
2010-01-25 17:12:44 +00:00
Tiago Cunha
05e5bc7882 Sync OpenBSD patchset 613:
Use C-e and C-y for scrolling in vi mode, from Micah Cowan.
2010-01-25 17:11:42 +00:00
Nicholas Marriott
62822cc78d +. 2010-01-24 20:45:26 +00:00
Nicholas Marriott
9a0571ff32 +. 2010-01-23 11:07:25 +00:00
Tiago Cunha
4d477aaeef Sync OpenBSD patchset 612:
Don't leak line, from Tiago Cunha.
2010-01-22 17:29:19 +00:00
Tiago Cunha
64c26cf8ce Sync OpenBSD patchset 611:
Permit !, + and - to be used for window targets to specify last window (!), or
next and previous window by number (+ and -).

Also tidy an if in cmd-new-window.c.
2010-01-22 17:28:34 +00:00
Nicholas Marriott
dcfa183cfe XHTML validation issues, from Mike Putnam. 2010-01-19 18:17:23 +00:00
Tiago Cunha
21dc792395 As of release 1.0, the server automatically sets the status-utf8, and utf8
options if started with -u.
2010-01-19 00:55:56 +00:00
Tiago Cunha
f7cb814613 Done. 2010-01-19 00:51:03 +00:00
Tiago Cunha
04b4ce8117 Sync OpenBSD patchset 610:
Missing Pp, from Tiago Cunha.
2010-01-19 00:46:30 +00:00
Nicholas Marriott
d5fb69b904 +. 2010-01-18 19:44:01 +00:00
Tiago Cunha
f772e1d362 Sync OpenBSD patchset 609:
Document swap-pane -d.
2010-01-17 19:02:47 +00:00
Tiago Cunha
2a2e24a177 Sync OpenBSD patchset 608:
Permit S- prefix on keys for shift. Relatively few terminals support this
(basically xterm only) and even fewer have them in terminfo (kLFT2 and kRIT2).
2010-01-17 19:01:27 +00:00
Tiago Cunha
dfc2ad1e5f Sync OpenBSD patchset 607:
key should be an int not a char.
2010-01-17 19:00:05 +00:00
Nicholas Marriott
38ee1e66aa Add vim-style key bindings file from Daniel Thau. 2010-01-17 16:24:09 +00:00
Nicholas Marriott
796ae34f2f ++. 2010-01-14 22:13:00 +00:00
Nicholas Marriott
5483a460fd +. 2010-01-14 22:10:23 +00:00
Nicholas Marriott
3abd4ca9a7 +OpenBSD FAQ. 2010-01-11 19:30:24 +00:00
Nicholas Marriott
b4e50303ab New screenshot. 2010-01-11 19:21:27 +00:00
Nicholas Marriott
4aa8284b39 s/new-window/new-session/ 2010-01-10 00:14:34 +00:00
Tiago Cunha
22101e3fe3 Sync OpenBSD patchset 605:
mouse-select-pane has to redraw the borders now too.
2010-01-08 16:35:38 +00:00
Tiago Cunha
a339427e45 Update. 2010-01-08 16:34:49 +00:00
Tiago Cunha
7fdb647e19 Do not include paths.h, since it's OS-dependent. 2010-01-08 16:34:17 +00:00
Tiago Cunha
da194cc435 Sync OpenBSD patchset 604:
New command, join-pane, to split and move an existing pane into the space (like
splitw then movep, or the reverse of breakp).
2010-01-08 16:31:35 +00:00
Tiago Cunha
f5dd79a01a Sync OpenBSD patchset 603:
Fix this properly.
2010-01-08 16:28:04 +00:00
Tiago Cunha
4a6191c5d1 Sync OpenBSD patchset 602:
Don't return the root cell if the string doesn't match.
2010-01-08 16:25:50 +00:00
Tiago Cunha
8212e76291 Sync OpenBSD patchset 601:
Use the specified pane for size calculations. Doh.
2010-01-08 16:24:21 +00:00
Tiago Cunha
91b7db766c Sync OpenBSD patchset 600:
Change split-window to accept a pane target (it should be split-pane but
renaming the command would be annoying).
2010-01-08 16:23:38 +00:00
Tiago Cunha
7c3d4e35d7 Sync OpenBSD patchset 599:
Correctly clear 256-colour flag for aixterm colours.
2010-01-08 16:22:02 +00:00
Tiago Cunha
4d8d70a846 Sync OpenBSD patchset 598:
Fix selection behaviour when the cursor is moved backwards (ie so the selection
start is after the end).
2010-01-05 23:54:53 +00:00
Tiago Cunha
b8bc525afe Update. 2010-01-05 23:54:00 +00:00
Tiago Cunha
106011aa53 Sync OpenBSD patchset 597:
Options to set the colour of the pane borders, with different colours for the
active pane.
2010-01-05 23:52:37 +00:00
Tiago Cunha
97c40b1f37 Sync OpenBSD patchset 596:
Use the target print function for copy-mode, spotted by Tiago Cunha.
2010-01-05 23:50:22 +00:00
Tiago Cunha
027f5310b4 Sync OpenBSD patchset 595:
Use tcflush(3) instead of TIOCFLUSH, from Ed Schouten.
2010-01-05 23:49:24 +00:00
Nicholas Marriott
4b2e459062 +. 2010-01-03 17:15:57 +00:00
Nicholas Marriott
13fbec2586 +. 2010-01-02 17:32:35 +00:00
Tiago Cunha
71e6b4d617 Sync OpenBSD patchset 594:
Fix the logic so that transition from a 256 colour to default works properly.
2009-12-26 23:50:15 +00:00
Tiago Cunha
51a284e056 Sync OpenBSD patchset 593:
Nuke some stray debugging.
2009-12-26 23:49:27 +00:00
Tiago Cunha
3cc7f2e191 Sync OpenBSD patchset 592:
Use sysctl() KERN_PROC2 instead of KERN_PROC, as the latter's ABI
is sensitive to changes in struct proc.

fixes for warnings and ok nicm@
2009-12-26 23:48:37 +00:00
Tiago Cunha
f81b3ddf94 Sync OpenBSD patchset 591:
Fix a couple of problems with grouped sessions reported by danh: redraw
properly and choose the correct last window after a window is killed.
2009-12-26 23:45:21 +00:00
Nicholas Marriott
e447088a8a +. 2009-12-26 10:21:34 +00:00
Nicholas Marriott
ad2767c7fb +. 2009-12-22 20:59:53 +00:00
Tiago Cunha
9fea75149a Sync OpenBSD patchset 590:
Allow keys to be replaced and reorder the table so that terminfo-defined keys
(or terminal-overrides) take precedence over internally defined.
2009-12-18 18:57:00 +00:00
Nicholas Marriott
f4b9b84190 FreeBSD 6.x has a bug and crashes in del_curterm, so ifdef it out on that
platform.
2009-12-18 07:42:30 +00:00
Nicholas Marriott
f9e513895c Add note about TERM, add putty Ctrl entry. 2009-12-17 10:00:15 +00:00
Tiago Cunha
99075aaa72 Sync OpenBSD patchset 589:
Pass through the aixterm bright colours if the terminal supports them (>= 16
colours).
2009-12-16 01:13:09 +00:00
Tiago Cunha
de15f2b567 Update. 2009-12-16 01:11:09 +00:00
Tiago Cunha
6f578a434b Sync OpenBSD patchset 588:
Add server options to completion as well.
2009-12-16 01:10:36 +00:00
Tiago Cunha
90d40e27da Sync OpenBSD patchset 587:
New server option, escape-time, to set the timeout used to detect if escapes
are alone or part of a function key or meta sequence.
2009-12-16 01:09:01 +00:00
Nicholas Marriott
ef3e483a0d +. 2009-12-13 15:47:16 +00:00
Nicholas Marriott
fcbf4ea2c0 Tweak text slightly. 2009-12-12 09:54:42 +00:00
Nicholas Marriott
243c63f867 FAQ about grouped sessions. 2009-12-12 09:54:02 +00:00
Tiago Cunha
7459be544e Sync OpenBSD patchset 586:
Use quiet variable, and add missing sentinel to options array.
2009-12-12 01:01:11 +00:00
Nicholas Marriott
b70be285b7 Look in /opt/blah on OS X, from simmel. 2009-12-11 20:08:18 +00:00
Tiago Cunha
dac1d365c0 Update. 2009-12-10 17:16:31 +00:00
Tiago Cunha
dcdd2fb094 Sync OpenBSD patchset 585:
Add "server options" which are server-wide and not bound to a session or
window. Set and displayed with "set -s" and "show -s".

Currently the only option is "quiet" (like command-line -q, allowing it to be
set from .tmux.conf), but others will come along.
2009-12-10 16:59:02 +00:00
Tiago Cunha
328861e330 Sync OpenBSD patchset 584:
Permit panes to be referred to as "top", "bottom", "top-left" etc, if the right
pane can be identified.
2009-12-10 16:52:58 +00:00
Tiago Cunha
39b1cdbdb9 Sync OpenBSD patchset 583:
vte is buggy and doesn't home the cursor after changing the scroll
region. Several people are hitting this, so add a workaround.
2009-12-04 22:17:26 +00:00
Tiago Cunha
3db559cf5a Sync OpenBSD patchset 582:
Wrap at 80 columns.
2009-12-04 22:16:15 +00:00
Tiago Cunha
cc094fdfe6 Sync OpenBSD patchset 581:
Massive spaces->tabs and trailing whitespace cleanup, hopefully for the last
time now I've configured emacs to make them displayed in really annoying
colours...
2009-12-04 22:14:47 +00:00
Tiago Cunha
1caa73afb4 Sync OpenBSD patchset 580:
Eliminate duplicate code and ease the passage for server-wide options by adding
a -w flag to set-option and show-options and making setw and showw aliases to
set -w and show -w.

Note: setw and showw are still there, but now aliases for set -w and show -w.
2009-12-04 22:11:23 +00:00
Tiago Cunha
ddb5bb80fa Sync OpenBSD patchset 579:
Reflect the keypad mode of the application so that numlock works.
2009-12-04 22:05:52 +00:00
Tiago Cunha
4ba8fce7ea Sync OpenBSD patchset 578:
Close the pane if the process died due to a signal, not just if it exited
normally.
2009-12-04 22:04:55 +00:00
Nicholas Marriott
1f7ac1e0cb Solaris requires this header ordering. 2009-12-03 14:33:27 +00:00
Nicholas Marriott
8fffdd28fb Quick way to turn UTF-8 on in putty. 2009-12-02 16:57:38 +00:00
Tiago Cunha
59eaef6107 Update. 2009-12-02 15:11:20 +00:00
Tiago Cunha
55f51c4949 Sync OpenBSD patchset 577:
New command, capture-pane, which copies the entire pane contents to a paste
buffer. From Jonathan Alvarado.
2009-12-02 15:10:44 +00:00
Tiago Cunha
c87379b04d Sync OpenBSD patchset 576:
Look for mice and xterm keys before standard function keys as they are less
likely to be partial versions.
2009-12-02 15:07:28 +00:00
Tiago Cunha
97350cd883 Sync OpenBSD patchset 575:
Handle partial xterm function key sequences.
2009-12-02 15:06:35 +00:00
Nicholas Marriott
5081d73330 +. 2009-11-28 23:55:41 +00:00
Tiago Cunha
b42f231027 Sync OpenBSD patchset 574:
Add a couple of comments.
2009-11-28 14:59:26 +00:00
Tiago Cunha
dc57c5bb50 Sync OpenBSD patchset 573:
This doesn't need to be u_int.
2009-11-28 14:57:59 +00:00
Tiago Cunha
575510045a Sync OpenBSD patchset 572:
Make types clearer and lint happier.
2009-11-28 14:57:04 +00:00
Tiago Cunha
4c7b3a5906 Sync OpenBSD patchset 571:
Fix type - attributes should be u_char not int.
2009-11-28 14:56:11 +00:00
Tiago Cunha
91cf94b34b Sync OpenBSD patchset 570:
Change paranoia check to check for <= 0 and to avoid warning.
2009-11-28 14:55:22 +00:00
Tiago Cunha
fabf40b3b3 Sync OpenBSD patchset 569:
Tidy up various bits of the paste code, make the data buffer char * and add
comments.
2009-11-28 14:54:12 +00:00
Tiago Cunha
66bf2e2f04 Sync OpenBSD patchset 568:
Continue rather than returning if not a mouse key, to avoid hanging on any
function key...
2009-11-28 14:51:37 +00:00
Tiago Cunha
c12e0b0708 Sync OpenBSD patchset 567:
Remove a couple of unused arguments where possible, and add /* ARGSUSED */ to
the rest to reduce lint output.
2009-11-28 14:50:37 +00:00
Tiago Cunha
bbd9652d32 Sync OpenBSD patchset 566:
Rename a variable to something more helpful.
2009-11-28 14:46:23 +00:00
Tiago Cunha
d9001ead7d Sync OpenBSD patchset 565:
Get a u_char from the string, otherwise it isn't possible to enter \0377 as it
is mistaken for EOF (doh).

Also drop an unused argument.
2009-11-28 14:45:30 +00:00
Tiago Cunha
d517ffe7c9 Sync OpenBSD patchset 564:
Handle the possibility of partial mouse reads, and fix a comment while here.
2009-11-28 14:44:00 +00:00
Tiago Cunha
8ba590b473 Sync OpenBSD patchset 563:
Emulate il1, dl1, ich1 to run (albeit slowly) with vt100 feature set.
2009-11-28 14:42:21 +00:00
Tiago Cunha
635d36f928 Sync OpenBSD patchset 562:
Output the right keys for application and number keypad modes (they were the
wrong way round).
2009-11-28 14:41:17 +00:00
Tiago Cunha
5f366e6d54 Sync OpenBSD patchset 561:
Add a -p flag to display-message to print the output rather than displaying in
the status line, this allows things like "display -p '#W'" to find the current
window index.
2009-11-28 14:39:53 +00:00
Tiago Cunha
a3024f3d2a Sync OpenBSD patchset 560:
Add cursor keys to the key names list.
2009-11-28 14:38:30 +00:00
Nicholas Marriott
399002baa4 Despite terminfo being in use for around 20 years, NetBSD still haven't got
their act together, so add an ifdef to use ncurses.h instead of curses.h.

Untested.
2009-11-26 09:19:05 +00:00
Nicholas Marriott
809902226e Sync. 2009-11-24 19:03:59 +00:00
Nicholas Marriott
45ac2cc4e7 +. 2009-11-23 20:29:04 +00:00
Nicholas Marriott
727fdb44a0 +load average. 2009-11-23 09:53:24 +00:00
Tiago Cunha
3cb0c8e650 Done. 2009-11-22 23:29:09 +00:00
Tiago Cunha
1a41a3b48f Sync OpenBSD patchset 559:
Use home from struct passwd if HOME is empty as well as if it is NULL, and fix
a style nit. Both from Tiago Cunha.
2009-11-22 00:13:34 +00:00
Tiago Cunha
1527ed0ff8 Sync OpenBSD patchset 558:
When -h and -p are given to split-window, calculate the percentage size using
the width instead of the height.
2009-11-22 00:12:33 +00:00
Tiago Cunha
bce5aedc64 Sync OpenBSD patchset 557:
Display UTF-8 properly in status line messages and prompt. Cursor handling is
still way off though.
2009-11-22 00:11:33 +00:00
Tiago Cunha
1d58ca61a7 Sync OpenBSD patchset 556:
Remove oldest messages from log when limit is hit, not newest.
2009-11-22 00:10:39 +00:00
Tiago Cunha
074780fea4 Sync OpenBSD patchset 555:
Get some brackets in the right place so ## works. Also fix a space in a
comment.
2009-11-22 00:09:42 +00:00
Nicholas Marriott
ec68dae252 +. 2009-11-20 14:59:45 +00:00
Tiago Cunha
7a9bfabf7a Sync OpenBSD patchset 554:
Change status line drawing to create the window list in a separate screen and
then copy it into the status line screen. This allows UTF-8 in window names and
fixes some problems with #[] in window-status-format.
2009-11-19 22:37:04 +00:00
Tiago Cunha
cbc7a23e33 Update. 2009-11-19 22:35:51 +00:00
Tiago Cunha
f9451028c0 Sync OpenBSD patchset 553:
Two new options, window-status-format and window-status-current-format, which
allow the format of each window in the status line window list to be controlled
using similar # sequences as status-left/right.

This diff also moves part of the way towards UTF-8 support in window names but
it isn't quite there yet.
2009-11-19 22:35:10 +00:00
Tiago Cunha
1feea926ed Sync OpenBSD patchset 552:
tweak previous;
2009-11-19 22:32:12 +00:00
Tiago Cunha
8512811535 Sync OpenBSD patchset 551:
Revert to xterm-keys off by default. It was on as an experiment to see if the
option could be removed, but it affects vi, so we have to keep the option, and
a conservative default is better.
2009-11-19 22:31:27 +00:00
Tiago Cunha
224ae13ab0 Sync OpenBSD patchset 550:
Tidy up by breaking the # replacement code into a separate function, also add a
few comments.
2009-11-19 22:30:39 +00:00
Tiago Cunha
5fd1cf743e Update. 2009-11-19 22:28:59 +00:00
Tiago Cunha
563f34477a Sync OpenBSD patchset 549:
Don't interpret #() for display-message, it usually doesn't make sense and may
leak commands.
2009-11-19 22:25:52 +00:00
Tiago Cunha
a5ae0dc216 Sync OpenBSD patchset 548:
Missed an unused variable :-/.
2009-11-19 22:24:17 +00:00
Tiago Cunha
a0b2b8e875 Sync OpenBSD patchset 547:
Cleanup by moving various (mostly horrible) little bits handling UTF-8 grid
data into functions in a new file, grid-utf8.c, and use sizeof intead of
UTF8_DATA.

Also nuke trailing whitespace from tmux.1, reminded by jmc.
2009-11-19 22:23:27 +00:00
Tiago Cunha
acc331c787 Sync OpenBSD patchset 546:
Add a per-client log of status line messages displayed while that client
exists. A new message-limit session option sets the maximum number of entries
and a command, show-messages, shows the log (bound to ~ by default).

This (and prompt history) might be better as a single global log but until
there are global options it is easier for them to be per client.
2009-11-19 22:20:04 +00:00
Tiago Cunha
8777a809dc Sync OpenBSD patchset 545:
Mark -n keys with (no prefix) rather than [].
2009-11-19 22:15:58 +00:00
Nicholas Marriott
ec48709dc2 +. 2009-11-18 13:56:06 +00:00
Tiago Cunha
9829cfc8d2 Sync OpenBSD patchset 544:
Permit top-bit-set characters to be entered in the status line. They could
already be set from the shell and are just passed through when printing (so
invisible characters or displaying on terminals with different character sets
may cause problems).

Note that entering UTF-8 may not work and in any case currently the status line
cannot display it correctly (outside of status-left/status-right).
2009-11-18 01:28:43 +00:00
Tiago Cunha
4c2e037046 Sync OpenBSD patchset 543:
In choose mode, assign each item a number or lowercase letter from those
available and accept that as a shortcut key for the item.
2009-11-18 01:27:33 +00:00
Tiago Cunha
1c97866a5f Sync OpenBSD patchset 542:
A screen can be one cell wide; don't crash if that is the case.
2009-11-18 01:25:35 +00:00
Tiago Cunha
063a474fe0 Sync OpenBSD patchset 541:
I made a complete horlicks of the last change, fix it so it doesn't either lead
to a double free or free the item after the end of the array.
2009-11-18 01:24:33 +00:00
Tiago Cunha
a7158784f2 Sync OpenBSD patchset 540:
Tweak a comment and add some spacing.
2009-11-14 17:57:41 +00:00
Tiago Cunha
e35f5b35bd Sync OpenBSD patchset 539:
Get rid of the ugly CMD_CHFLAG macro and use a const string (eg "dDU") in the
command entry structs and a couple of functions to check/set the flags.
2009-11-14 17:56:39 +00:00
Tiago Cunha
fc6a835be8 Sync OpenBSD patchset 538:
Unreachable statement, found by lint.
2009-11-14 17:52:04 +00:00
Tiago Cunha
ee9be88946 Sync OpenBSD patchset 537:
Tidy up and fix some types, prompted by lint via deraadt.
2009-11-14 17:51:06 +00:00
Tiago Cunha
0bb00a0df3 Sync OpenBSD patchset 536:
imsg_read returns ssize_t not int, pointed out by lint via deraadt.
2009-11-14 17:49:37 +00:00
Tiago Cunha
72bc03ac4c Sync OpenBSD patchset 535:
Destroy panes immediately rather than checking them all every loop.
2009-11-14 17:48:39 +00:00
Tiago Cunha
56447d73c1 Sync OpenBSD patchset 534:
Use winlink_remove() to remove old winlinks when synchronizing grouped sessions
rather than doing it manually and not adjusted the reference count. Fixes
crash seen by Dan Harnett.
2009-11-13 16:59:19 +00:00
Tiago Cunha
0986001908 Sync OpenBSD patchset 533:
Zap unused functions, prompted by deraadt.
2009-11-13 16:58:24 +00:00
Tiago Cunha
2bd39071d3 Sync OpenBSD patchset 532:
Emulate the ri (reverse index) capability: this allows tmux to at least start
on Sun consoles (TERM=sun or sun-color), even if there appear to still be
problems on some boxes (my Blade 100 is fine but edd's Blade 1000 shows odd
screen corruption).
2009-11-13 16:57:21 +00:00
Tiago Cunha
ac6b1a817b Sync OpenBSD patchset 531:
Support rxvt-style keys again, but this time: support all the variations, put
them in as raw escape sequences rather than fiddling with the values from
terminfo, put them /after/ the terminfo values so the latter take precedence.
2009-11-13 16:56:15 +00:00
Tiago Cunha
ba832ff2c3 Sync OpenBSD patchset 530:
Rewrite a confusing loop when freeing the arg array on exit and move the check
for argv being NULL, prompted by parfait via deraadt.

Also fix some definite brokenness when assigning multiple environment variables
in arguments (such as "X=1 Y=2").
2009-11-13 16:55:10 +00:00
Tiago Cunha
2ec5aca064 Sync OpenBSD patchset 529:
Add an explicit zero-length check for UTF-8 input data, prompted by a report
from parfait via deraadt.

While here, add a statement to set the width when filling with _s if not enough
space (width should never be high enough at the moment anyway), and wrap some
long lines.
2009-11-13 16:54:04 +00:00
Tiago Cunha
e8424d333e Sync OpenBSD patchset 528:
Free the pane bufferevent when the fd is closed (the signal could come before
the error callback).
2009-11-13 16:52:46 +00:00
Tiago Cunha
1b4a76d58f Sync OpenBSD patchset 527:
Only need to chmod +x or -x the socket when a client is created, lost or
attached, rather than every event loop.
2009-11-13 16:51:49 +00:00
Nicholas Marriott
7230fe1648 OS X is still broken, so ask libevent not to use kqueue or poll. 2009-11-11 09:54:07 +00:00
Tiago Cunha
60869fa4c3 Sync OpenBSD patchset 526:
There is no real standard for modifier plus function keys. Previously, tmux
output some from rxvt but in other ways did the same as xterm or other
terminals, but this is a bit inconsistent.

xterm's method is fairly sensible and we already support it (xterm-keys), so
enable it by default instead.
2009-11-10 23:34:03 +00:00
Tiago Cunha
ba7aa506f3 Sync OpenBSD patchset 525:
Don't output rxvtisms either.
2009-11-10 23:32:53 +00:00
Tiago Cunha
9817d41947 Sync OpenBSD patchset 524:
Twiddling the last bit is an rxvtism, so do not support it in the table by
default.
2009-11-10 23:32:09 +00:00
Tiago Cunha
74e742113d Sync OpenBSD patchset 523:
Whoops, this is needed for last commit as well.
2009-11-10 23:31:21 +00:00
Tiago Cunha
e9b357550f Sync OpenBSD patchset 522:
Lookup key as a named key (eg 'Space') before checking for single character
keys, makes C-Space/M-Space etc resolve to the correct key code.
2009-11-10 23:30:26 +00:00
Tiago Cunha
38ac9bb414 Sync OpenBSD patchset 521:
Don't return 1 unless there was actually a problem (signal/lost server) rather
than for all events (normal exit/detach/etc).
2009-11-10 23:28:53 +00:00
Tiago Cunha
c01816c26d Sync OpenBSD patchset 520:
Just ignore tty fd errors rather than dying, stops the server dying if the
session is disconnected abrubtly (eg ssh ~.).
2009-11-10 23:27:57 +00:00
Tiago Cunha
36bb298bfa Sync OpenBSD patchset 519:
The input key should be a u_char. Fixes top-bit-set input problem reported by
ajacoutot@.
2009-11-10 23:27:03 +00:00
Tiago Cunha
e275bc52f2 Sync OpenBSD patchset 518:
Constify buf.
2009-11-10 23:26:13 +00:00
Nicholas Marriott
ef45c1c65b +. 2009-11-10 15:33:31 +00:00
Nicholas Marriott
c202377859 +. 2009-11-09 20:03:31 +00:00
Tiago Cunha
34b4c2e607 Sync OpenBSD patchset 517:
Don't try enable/disable the event if the window pane is dead (fd == -1), as
the event will have been freed.
2009-11-08 23:35:53 +00:00
Tiago Cunha
dcb85fe4b1 Sync OpenBSD patchset 516:
Clear to the end of the screen from the right starting point when drawing
line-by-line (in panes or if ed not supported). Fixes problem spotted by Frank
Terbeck.
2009-11-08 23:34:47 +00:00
Tiago Cunha
8fe9ecae05 Sync OpenBSD patchset 515:
Old xterm F1-F4 are \033O_P not \033[O_P.
2009-11-08 23:33:57 +00:00
Tiago Cunha
946337484e Sync OpenBSD patchset 514:
Unused variable. Aargh.
2009-11-08 23:33:17 +00:00
Tiago Cunha
181e1cc711 Sync OpenBSD patchset 513:
Switch the tty key tree over to an (unbalanced) ternary tree which allows
partial matches to be done (they wait for further data or a timer to expire,
like a naked escape).

Mouse and xterm-style keys still expect to be atomic.
2009-11-08 23:32:39 +00:00
Tiago Cunha
f18b224983 Sync OpenBSD patchset 512:
key_string_lookup_key uses a static buffer, so copy its output into the working
buffer before calling the command print function which can also use it (eg
send-keys).
2009-11-08 23:30:42 +00:00
Tiago Cunha
7d288e7fd8 Sync OpenBSD patchset 511:
Key flags are only used for initialisation so they are not needed in the main
tty_key struct.
2009-11-08 23:29:34 +00:00
Tiago Cunha
fb22aaf87f Sync OpenBSD patchset 510:
EVLOOP_ONCE takes care of the wakeup, so no need to call event_loopexit(NULL).
2009-11-08 23:28:40 +00:00
Tiago Cunha
5ac6ea61bd Sync OpenBSD patchset 509:
Now all timers are events, there is no longer any need to wake up every 50 ms -
only wake up when an event happens.
2009-11-08 23:27:58 +00:00
Tiago Cunha
66957412d5 Sync OpenBSD patchset 508:
Switch tty key input over to happen on a read event. This is a bit more
complicated because of escape input, but in that case instead of processing a
key immediately, schedule a timer and reprocess the bufer when it expires.

This currently assumes that keys will be atomic (ie that if eg F1 is pressed
the entire sequence is present in the buffer). This is usually but not always
true, a change in the tree format so it can differentiate potential (partial)
key sequences will happens soon and will allow this to be fixed.
2009-11-08 23:26:56 +00:00
Tiago Cunha
ac6092c27f Sync OpenBSD patchset 507:
Convert the key repeat timer to an event.
2009-11-08 23:24:59 +00:00
Tiago Cunha
81336d6bb0 Make it compile on the portable version. 2009-11-08 23:23:36 +00:00
Tiago Cunha
ab38d91913 Sync OpenBSD patchset 506:
Change window name change to use a timer event rather than a gettimeofday()
check every loop.
2009-11-08 23:22:24 +00:00
Tiago Cunha
915031b049 Sync OpenBSD patchset 505:
Move status timer check into the global once-per-second timer, this could maybe
be done better but one every second is better than once every 50 ms.
2009-11-08 23:12:35 +00:00
Tiago Cunha
02438c01b7 Sync OpenBSD patchset 504:
Use timeout events for the identify and message timers.
2009-11-08 23:11:23 +00:00
Tiago Cunha
bee17719d8 Sync OpenBSD patchset 503:
Don't reenlist the client imsg event every loop, instead have a small function
to it and call it after the event triggers or after a imsg is added.
2009-11-08 23:09:36 +00:00
Tiago Cunha
0cd4f4e321 Sync OpenBSD patchset 502:
It would help if I read my own comments... make alt keys work again by sending
alt AND the key not alt instead of it.
2009-11-08 23:08:12 +00:00
Tiago Cunha
3acb995ef3 Sync OpenBSD patchset 501:
Move some common code into a function.
2009-11-08 23:07:14 +00:00
Tiago Cunha
40b6941c0f Sync OpenBSD patchset 500:
Tell the client to exit on configuration file error.
2009-11-08 23:06:25 +00:00
Tiago Cunha
142962742c Sync OpenBSD patchset 499:
Bye-bye buffer*.c.
2009-11-08 23:05:36 +00:00
Tiago Cunha
2df0882722 Sync OpenBSD patchset 498:
Convert the window pane (pty master side) fd over to use a bufferevent.

The evbuffer API is very similar to the existing tmux buffer API so this was
remarkably painless. Not many possible ways to do it, I suppose.
2009-11-08 23:02:56 +00:00
Tiago Cunha
70b2f1981e Sync OpenBSD patchset 497:
Call event_init() before loading the config file, since potentially it could
set up events.
2009-11-08 23:00:44 +00:00
Tiago Cunha
cb0bf6a043 Sync OpenBSD patchset 496:
Switch window pane pipe redirect fd over to a bufferevent.
2009-11-08 22:59:53 +00:00
Tiago Cunha
971a7b2fe0 Sync OpenBSD patchset 495:
Switch tty fds over to a bufferevent.
2009-11-08 22:58:38 +00:00
Tiago Cunha
7851bb81f5 Sync OpenBSD patchset 494:
Add back JOB_PERSIST checks that got lost.
2009-11-08 22:56:54 +00:00
Tiago Cunha
53ef4c2bab Sync OpenBSD patchset 493:
Switch jobs over to use a bufferevent.
2009-11-08 22:56:04 +00:00
Tiago Cunha
5116aaa51a Sync OpenBSD patchset 492:
A couple of minor cosmetic changes.
2009-11-08 22:53:13 +00:00
Tiago Cunha
e41055c5aa Adjust recent libevent changes to the portable version. 2009-11-08 22:51:34 +00:00
Tiago Cunha
dd36982ad5 Sync OpenBSD patchset 491:
Initial changes to move tmux to libevent.

This moves the client-side loops are pretty much fully over to event-based only
(tmux.c and client.c) but server-side (server.c and friends) treats libevent as
a sort of clever poll, waking up after every event to run various things.

Moving the server stuff over to bufferevents and timers and so on will come
later.
2009-11-08 22:40:36 +00:00
Tiago Cunha
5ce49941fb Working on 1.2. 2009-11-05 13:18:19 +00:00
Tiago Cunha
09c34be825 Use %%VERSION%% so the Makefile can replace it by VERSION. 2009-11-05 13:13:19 +00:00
158 changed files with 9770 additions and 6722 deletions

105
CHANGES
View File

@@ -1,3 +1,106 @@
CHANGES FROM 1.2 TO 1.3, 18 July 2010
* New input parser.
* Flags to move through panes -UDLR added to select-pane.
* Commands up-pane, and down-pane removed, since equivalent behaviour is now
available through the target flag (-t:+ and -t:-).
* Jump-forward/backward in copy move (based on vi's F, and f commands).
* Make paste-buffer accept a pane as a target.
* Flag -a added to new-window to insert a window after an existing one, moving
windows up if necessary.
* Merge more mode into copy mode.
* Run job commands explicitly in the global environment (which can be modified
with setenv -g), rather than with the environment tmux started with.
* Use the machine's hostname as the default title, instead of an empty string.
* Prevent double free if the window option remain-on-exit is set.
* Key string conversions rewritten.
* Mark zombie windows as dead in the choose-window list.
* Tiled layout added.
* Signal handling reworked.
* Reset SIGCHLD after fork to fix problems with some shells.
* Select-prompt command removed. Therefore, bound ' to command-prompt -p index
"select-window -t:%%" by default.
* Catch SIGHUP and terminate if running as a client, thus avoiding clients from
being left hanging around when, for instance, a SSH session is disconnected.
* Solaris 9 fixes (such as adding compat {get,set}env(3) code).
* Accept none instead of default for attributes.
* Window options window-status-alert-{alert,bg,fg} added.
* Flag -s added to the paste-buffer command to specify a custom separator.
* Allow dragging to make a selection in copy mode if the mode-mouse option is
set.
* Support the mouse scroll wheel.
* Make pipe-pane accept special character sequences (eg #I).
* Fix problems with window sizing when starting tmux from .xinitrc.
* Give tmux sockets (but not the containing folder) group permissions.
* Extend the target flags (ie -t) to accept an offset (for example -t:+2), and
make it wrap windows, and panes.
* New command choose-buffer added.
* New server option detach-on-destroy to set what happens to a client when the
session it is attached to is destroyed. If on (default), the client is
detached. Otherwise, the client is switched to the most recently active of
the remaining sessions.
* The commands load-buffer, and save-buffer now accept a dash (-) as the file
to read from stdin, or write to stdout.
* Custom layouts added.
* Additional code reduction, bug fixes, and manpage enhancements.
CHANGES FROM 1.1 TO 1.2, 10 March 2010
* Switch to libevent.
* Emulate the ri (reverse index) capability, ergo allowing tmux to at least
start on Sun consoles (TERM=sun, or sun-color).
* Assign each entry a number, or lowercase letter in choose mode, and accept
that as a shortcut key.
* Permit top-bit-set characters to be entered in the status line.
* Mark no-prefix keys with (no prefix), rather than [] in list-keys.
* New command show-messages (alias showmsgs), and new session option
message-limit, to show a per-client log of status lines messages up to the
number defined by message-limit.
* Do not interpret #() for display-message to avoid leaking commands.
* New window options window-status-format, and window-status-current-format to
control the format of each window in the status line.
* Add a -p flag to display-message to print the output, instead of displaying
it in the status line.
* Emulate il1, dl1, ich1 to run with vt100 feature set.
* New command capture-pane (alias capturep) to copy the entire pane contents
to a paste buffer.
* Avoid duplicating code by adding a -w flag to set-option, and show-options to
set, and show window options. The commands set-window-option, and
show-window-options are now aliases.
* Panes can now be referred to as top, bottom, top-left, etc.
* Add server-wide options, which can be set with set-option -s, and shown with
show-options -s.
* New server option quiet (like -q from the command line).
* New server option escape-time to set the timeout used to detect if escapes
are alone, part of a function key, or meta sequence.
* New session options pane-active-border-bg, pane-active-border-fg,
pane-border-bg, and pane-border-fg to set pane colours.
* Make split-window accept a pane target, instead of a window.
* New command join-pane (alias joinp) to split, and move an existing pane into
the space (the opposite of break-pane), thus simplifying calls to
split-window, followed by move-window.
* Permit S- prefix on keys for shift when the terminal/terminfo supports them.
* Window targets (-t flag) can now refer to the last window (!), next (+), and
previous (-) window by number.
* Mode keys to jump to the bottom/top of history, end of the next word, scroll
up/down, and reverse search in copy mode.
* New session option display-panes-active-colour to display the active pane in
a different colour with the display-panes command.
* Read the socket path from $TMUX if it's present, and -L, and -S are not
given.
* Vi-style mode keys B, W, and E to navigate between words in copy mode.
* Start in more mode when configuration file errors are detected.
* Rectangle copy support added.
* If attach-session was specified with the -r flag, make the client read-only.
* Per-window alternate-screen option.
* Make load-buffer work with FIFOs.
* New window option word-separators to set the characters considered as word
separators in copy mode.
* Permit keys in copy mode to be prefixed by a repeat count, entered with [1-9]
in vi mode, or M-[1-9] in emacs mode.
* utf8 improvements.
* As usual, additional code reduction, bug fixes, and manpage enhancements.
CHANGES FROM 1.0 TO 1.1, 05 November 2009
* New run-shell (alias run) command to run an external command without a
@@ -1410,7 +1513,7 @@ The list of older changes is below.
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
$Id: CHANGES,v 1.301 2009-11-05 12:35:47 tcunha Exp $
$Id: CHANGES,v 1.303 2010-07-18 13:40:59 tcunha Exp $
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

58
FAQ
View File

@@ -1,5 +1,17 @@
tmux frequently asked questions
******************************************************************************
* PLEASE NOTE: most display problems are due to incorrect TERM! Before *
* reporting problems make SURE that TERM settings are correct inside and *
* outside tmux. *
* *
* Inside tmux TERM must be "screen" or similar (such as "screen-256color"). *
* Don't bother reporting problems where it isn't! *
* *
* Outside, it must match your terminal: particularly, use "rxvt" for rxvt *
* and derivatives. *
******************************************************************************
* How is tmux different from GNU screen? What else does it offer?
tmux offers several advantages over screen:
@@ -26,8 +38,9 @@ There are still a few features screen includes that tmux omits:
* I found a bug! What do I do?
Please send bug reports by email to nicm@users.sourceforge.net. Please
include as much of the following information as possible:
Please send bug reports by email to nicm@users.sourceforge.net or
tmux-users@lists.sourceforge.net. Please include as much of the following
information as possible:
- the version of tmux you are running;
- the operating system you are using and its version;
@@ -82,19 +95,17 @@ default) to the new key. For example:
* How do I use UTF-8?
When running tmux in a UTF-8 capable terminal, two things must be done to
enable support. UTF-8 must be turned on in tmux; this may be done separately
for each tmux window or globally by setting the "utf8" flag:
setw -g utf8 on
As of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by
When running tmux in a UTF-8 capable terminal, UTF-8 must be turned on in tmux;
as of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by
checking the LC_ALL, LC_CTYPE and LANG environment variables. list-clients may
be used to check if this is detected correctly; if not, the -u command-line
flag may be specified when creating or attaching a client to a tmux session:
$ tmux -u new
Since the 1.0 release, tmux will turn on UTF-8 related options automatically
(ie status-utf8, and utf8) if the above conditions are met.
* How do I use a 256 colour terminal?
Provided the underlying terminal supports 256 colours, it is usually sufficient
@@ -201,4 +212,31 @@ on the Window -> Translation configuration page. For example, change UTF-8 to
ISO-8859-1 or CP437. It may also be necessary to adjust the way PuTTY treats
line drawing characters in the lower part of the same configuration page.
$Id: FAQ,v 1.29 2009-08-08 20:46:26 nicm Exp $
* What is the best way to display the load average? Why no #L?
It isn't possible to get the load average portably in code and it is preferable
not to add portability goop. The following works on at least Linux, *BSD and OS
X:
uptime|awk '{split(substr($0, index($0, "load")), a, ":"); print a[2]}'
* How do I attach the same session to multiple clients but with a different
current window, like screen -x?
One or more of the windows can be linked into multiple sessions manually with
link-window, or a grouped session with all the windows can be created with
new-session -t.
* Ctrl and arrow keys doesn't work in putty! What do I do?
putty inverts the sense of the cursor key mode on ctrl, which is a bit hard for
tmux to detect properly. To get ctrl keys right, change the terminfo settings
so kUP5 (Ctrl-Up etc) are the adjusted versions, and disable smkx/rmkx so tmux
doesn't change the mode. For example with this line in .tmux.conf (assuming you
have TERM set to xterm):
set -g terminal-overrides "xterm*:kLFT5=\eOD:kRIT5=\eOC:kUP5=\eOA:kDN5=\eOB:smkx@:rmkx@"
Note that this will only work in tmux 1.2 and above.
$Id: FAQ,v 1.36 2010-02-04 21:01:59 nicm Exp $

View File

@@ -1,4 +1,4 @@
# $Id: GNUmakefile,v 1.120 2009-11-05 12:30:55 tcunha Exp $
# $Id: GNUmakefile,v 1.128 2010-07-18 13:36:52 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
@@ -17,7 +17,7 @@
.PHONY: clean
VERSION= 1.1
VERSION= 1.3
#FDEBUG= 1
@@ -28,7 +28,7 @@ LIBS+=
# Sun CC
ifneq ($(shell ($(CC) -V 2>&1|awk '/Sun C/' || true)), )
CFLAGS+=-erroff=E_EMPTY_DECLARATION
CFLAGS+= -erroff=E_EMPTY_DECLARATION
FDEBUG=
endif
@@ -52,11 +52,12 @@ endif
endif
PREFIX?= /usr/local
INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555
INSTALLMAN= install -g bin -o root -m 444
INSTALL?= install
INSTALLDIR= $(INSTALL) -d
INSTALLBIN= $(INSTALL) -m 555
INSTALLMAN= $(INSTALL) -m 444
SRCS= $(shell echo *.c|sed 's|osdep-[a-z0-9]*.c||g')
SRCS= $(shell echo *.c|LC_ALL=C sed 's|osdep-[a-z0-9]*.c||g')
include config.mk
OBJS= $(patsubst %.c,%.o,$(SRCS))

View File

@@ -1,4 +1,4 @@
# $Id: Makefile,v 1.153 2009-11-05 12:30:55 tcunha Exp $
# $Id: Makefile,v 1.160 2010-07-18 13:36:52 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
@@ -18,7 +18,7 @@
.SUFFIXES: .c .o
.PHONY: clean
VERSION= 1.1
VERSION= 1.3
#FDEBUG= 1
@@ -48,11 +48,12 @@ CFLAGS+= -Wno-pointer-sign
.endif
PREFIX?= /usr/local
INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555
INSTALLMAN= install -g bin -o root -m 444
INSTALL?= install
INSTALLDIR= ${INSTALL} -d
INSTALLBIN= ${INSTALL} -m 555
INSTALLMAN= ${INSTALL} -m 444
SRCS!= echo *.c|sed 's|osdep-[a-z0-9]*.c||g'
SRCS!= echo *.c|LC_ALL=C sed 's|osdep-[a-z0-9]*.c||g'
.include "config.mk"
OBJS= ${SRCS:S/.c/.o/}

14
NOTES
View File

@@ -9,12 +9,10 @@ run on Solaris and AIX (although they haven't been tested in a while). It is
usable, although there remain a number of missing features and some remaining
bugs are expected.
If upgrading from 1.0, PLEASE NOTE:
- The internal locking mechanism has gone, so the set-password command and -U
command line option have been removed.
- The -d command line flag was dropped. It will now automatically detect the
default colours by using op/AX. Nevertheless, if needed, the
terminal-overrides session option can replace it.
Since the 1.2 release that tmux depends on libevent. Download the stable
version from:
http://www.monkey.org/~provos/libevent/
tmux consists of a server part and multiple clients. The server is created when
required and runs continuously unless killed by the user. Clients access the
@@ -51,7 +49,7 @@ are missing it may refuse to run, or not behave correctly.
tmux supports UTF-8. To use it, the utf8 option must be set on each window;
this may be turned on for all windows by setting it as a global option, see
tmux(1) and the FAQ file. As of 0.9, tmux attempts to autodetect a
UTF-8-capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment
UTF-8 capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment
variables. list-clients may be used to check if this is detected correctly; if
not, the -u command-line flag may be specified.
@@ -88,4 +86,4 @@ start. Please contact me with any queries.
-- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.51 2009-11-05 12:35:47 tcunha Exp $
$Id: NOTES,v 1.53 2010-03-10 15:18:11 tcunha Exp $

91
TODO
View File

@@ -15,7 +15,6 @@
session not being watched?
- next prev word etc in command prompt
- many more info() displays for various things
- input.c is too complicated. simplify?
- use a better termcap internally instead of screen, perhaps xterm
- fix rxvt cursor fg issue (text under cursor can have non-white fg)
- should be able to move to a hidden pane and it would be moved into view. pane
@@ -38,8 +37,8 @@
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
$HOME/.tmux-session.conf
- get it passing all the vttest tests that don't require resizing the terminal
- esc seq to set window title should be documented and should set
automatic-rename
- esc seq to set window name and title should be documented, and name variant
should clear automatic-rename
- way to set socket path from config file
- XXX once env stuff is in, default-path and VISUAL/EDITOR should be picked up
when session is started
@@ -56,9 +55,6 @@
- a way for force-width/height to apply to only one pane (how?)
- command to list what is actually running in each window with command line,
pid (need some adaption of the osdep code)
- string option to change/remove the symbols (*-+ etc) in status line
* or to set entire format, eg window-list-format '#N:#W#P' or something,
then could use embedded colours
- support for bce
- it would be nice if the start/end line keys in copy mode were aware of
wrapped lines
@@ -68,7 +64,6 @@
for redraw
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- a way to address panes by name ("top-left") and position ("0,0")
- commands should be able to succeed or fail and have || or && for command
lists
- support the mouse wheel to scroll through history
@@ -78,20 +73,80 @@
- UTF-8 to a non-UTF-8 terminal should not be able to balls up
the terminal - www/ruby-addressable; make regress
- copy mode needs a tidy/cleanup
- things like display-message will leak job entries if #() is used
- message log
- an option to NOT remove message when key pressed
- would be nice to be able to press 0-9a-zA-Z to select window in choose-window
mode, also to start typing and it searches
- the wrapping stuff should work when redrawn from scroll mode too (screen_write_copy)
- ability to save history (to buffer?)
- multiple keys could be done with tables, ie have prefixes go and instead
bind -n ^A prefix-table "default"
where prefix-table sets command lookup table and sets prefix flag, then next key
is looked up in that table
- check fix UTF-8 and split-window? should be okay
where prefix-table sets command lookup table and sets prefix flag, then next
key is looked up in that table
- UTF-8 should be a pointer into a combined string buffer
- check irssi (term_charset) works with UTF-8
- rectangle copy/paste
- half page/up down are missing from key table
- support esc-esc to quit in modes
- fix ctrl+F1-F4 output. to what?
- look into xterm clearing its selection when scrolling etc
- better utf8 support:
window names
prompt input
message display
copy and paste cursor and wide characters
...?
- session history for client and last-session command
- option to change status line colour when current window is in a mode?
- option to move copy mode indicator into status line
- list-buffer/show-buffer should display UTF-8
- selection behaviour closer to vi in vi mode
- live update: server started with -U connects to server, requests sessions and
windows, receives fds
- convert status line history to be server global (anything else?)
- command to show a tree of sessions-windows-panes (active marked with *)
- sort out inheriting config from shell on new sessions/windows:
should pick up default-path/termios/etc from client if possible,
else leave empty/default
- link panes into multiple windows
- -h option to capture-pane to capture the history as well
- bells should be passed between sessions with visual-bell etc
- use screen-256color when started on 256 colour terminal??
- if-shell/run-shell should block further command execution in the same command
sequence until its shell exits, to allow them to be used from the config file
- better session sharing: create-socket command to create socket somewhere (-r
flag for readonly)
- allow buffer to be specified when copying in copy mode
- multiline status line
- flag for absolute pane size to resize-pane
- sanity check input to socket
- select-buffer command
- support title stack, both internally and externally
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
- copy buffers should be global, limit can be server option, nuke copy-buffer
command
- command to show status line information briefly when it is off
- some way to pad # stuff with spaces, #!2T maybe
- FreeBSD console problems
- a binding to "scroll down and exit at bottom" copy mode
- some way to pass keystrokes in copy mode through to underlying window
- last window update time and # replacement for it for display-message
- find-window across sessions - other ways to make session handling easier?
- ' and " should be parsed the same (eg "\e" vs '\e') in config and command
prompt?
- command to toggle selection not to move it in copy-mode
For 1.3 (not in order):
3 why are alerts per-winlink? try per window?
4 audit of escape sequence support vs xterm
6 rectangle copy: when selecting leftward, cursor should be inside block per
emacs key to rotate corner at which cursor is
9 something for -t "last window in session" so a session can be used as a stack
10 synchronous commands - client sends cmd and blocks, neww/splitw saves client
ptr then when program inside died, sends MSG_SOMETHING with wait status to
client
11 documentation improvements - rlpowell's tutorial
- build instructions
12 better configure? with-libevent
14 bind commands to key sequences?
16 monitor, bell etc should monitor /all/ panes in the window not just one
17 wd should be updated on attach etc. maybe lose default-path and use PWD
18 a history of commands that can be reversed (reverse member of each command, and a buffer)
19 info() when changing to same window
20 don't pass UTF-8 through vis for titles
...

View File

@@ -1,4 +1,4 @@
/* $Id: array.h,v 1.9 2009-11-02 21:34:32 tcunha Exp $ */
/* $Id: array.h,v 1.11 2010-06-06 00:27:08 tcunha Exp $ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,6 +19,8 @@
#ifndef ARRAY_H
#define ARRAY_H
#define ARRAY_INITIALIZER { NULL, 0, 0 }
#define ARRAY_DECL(n, c) \
struct n { \
c *list; \
@@ -45,7 +47,7 @@
} \
} while (0)
#define ARRAY_EMPTY(a) ((a) == NULL || (a)->num == 0)
#define ARRAY_EMPTY(a) (((void *) (a)) == NULL || (a)->num == 0)
#define ARRAY_LENGTH(a) ((a)->num)
#define ARRAY_DATA(a) ((a)->list)

View File

@@ -1,4 +1,4 @@
/* $Id: attributes.c,v 1.2 2009-06-25 15:25:45 nicm Exp $ */
/* $Id: attributes.c,v 1.4 2010-06-05 23:54:51 tcunha Exp $ */
/*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -23,29 +23,29 @@
#include "tmux.h"
const char *
attributes_tostring(u_char ch)
attributes_tostring(u_char attr)
{
static char buf[128];
if (ch == 0)
return ("default");
if (attr == 0)
return ("none");
buf[0] = '\0';
if (ch & GRID_ATTR_BRIGHT)
if (attr & GRID_ATTR_BRIGHT)
strlcat(buf, "bright,", sizeof (buf));
if (ch & GRID_ATTR_DIM)
if (attr & GRID_ATTR_DIM)
strlcat(buf, "dim,", sizeof (buf));
if (ch & GRID_ATTR_UNDERSCORE)
if (attr & GRID_ATTR_UNDERSCORE)
strlcat(buf, "underscore,", sizeof (buf));
if (ch & GRID_ATTR_BLINK)
if (attr & GRID_ATTR_BLINK)
strlcat(buf, "blink,", sizeof (buf));
if (ch & GRID_ATTR_REVERSE)
if (attr & GRID_ATTR_REVERSE)
strlcat(buf, "reverse,", sizeof (buf));
if (ch & GRID_ATTR_HIDDEN)
if (attr & GRID_ATTR_HIDDEN)
strlcat(buf, "hidden,", sizeof (buf));
if (ch & GRID_ATTR_ITALICS)
if (attr & GRID_ATTR_ITALICS)
strlcat(buf, "italics,", sizeof (buf));
if (*buf)
if (*buf != '\0')
*(strrchr(buf, ',')) = '\0';
return (buf);
@@ -55,7 +55,7 @@ int
attributes_fromstring(const char *str)
{
const char delimiters[] = " ,|";
u_char ch;
u_char attr;
size_t end;
if (*str == '\0' || strcspn(str, delimiters) == 0)
@@ -63,31 +63,31 @@ attributes_fromstring(const char *str)
if (strchr(delimiters, str[strlen(str) - 1]) != NULL)
return (-1);
if (strcasecmp(str, "default") == 0)
if (strcasecmp(str, "default") == 0 || strcasecmp(str, "none") == 0)
return (0);
ch = 0;
attr = 0;
do {
end = strcspn(str, delimiters);
if ((end == 6 && strncasecmp(str, "bright", end) == 0) ||
(end == 4 && strncasecmp(str, "bold", end) == 0))
ch |= GRID_ATTR_BRIGHT;
attr |= GRID_ATTR_BRIGHT;
else if (end == 3 && strncasecmp(str, "dim", end) == 0)
ch |= GRID_ATTR_DIM;
attr |= GRID_ATTR_DIM;
else if (end == 10 && strncasecmp(str, "underscore", end) == 0)
ch |= GRID_ATTR_UNDERSCORE;
attr |= GRID_ATTR_UNDERSCORE;
else if (end == 5 && strncasecmp(str, "blink", end) == 0)
ch |= GRID_ATTR_BLINK;
attr |= GRID_ATTR_BLINK;
else if (end == 7 && strncasecmp(str, "reverse", end) == 0)
ch |= GRID_ATTR_REVERSE;
attr |= GRID_ATTR_REVERSE;
else if (end == 6 && strncasecmp(str, "hidden", end) == 0)
ch |= GRID_ATTR_HIDDEN;
attr |= GRID_ATTR_HIDDEN;
else if (end == 7 && strncasecmp(str, "italics", end) == 0)
ch |= GRID_ATTR_ITALICS;
attr |= GRID_ATTR_ITALICS;
else
return (-1);
str += end + strspn(str + end, delimiters);
} while (*str != '\0');
return (ch);
return (attr);
}

View File

@@ -1,55 +0,0 @@
/* $Id: buffer-poll.c,v 1.18 2009-10-23 17:49:47 tcunha Exp $ */
/*
* 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 <errno.h>
#include <unistd.h>
#include "tmux.h"
/* Fill buffers from socket based on poll results. */
int
buffer_poll(int fd, int events, struct buffer *in, struct buffer *out)
{
ssize_t n;
if (events & (POLLERR|POLLNVAL))
return (-1);
if (in != NULL && events & POLLIN) {
buffer_ensure(in, BUFSIZ);
n = read(fd, BUFFER_IN(in), BUFFER_FREE(in));
if (n == 0)
return (-1);
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
return (-1);
} else
buffer_add(in, n);
} else if (events & POLLHUP)
return (-1);
if (out != NULL && BUFFER_USED(out) > 0 && events & POLLOUT) {
n = write(fd, BUFFER_OUT(out), BUFFER_USED(out));
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
return (-1);
} else
buffer_remove(out, n);
}
return (0);
}

139
buffer.c
View File

@@ -1,139 +0,0 @@
/* $Id: buffer.c,v 1.8 2009-08-21 21:09:13 tcunha Exp $ */
/*
* 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 <string.h>
#include "tmux.h"
/* Create a buffer. */
struct buffer *
buffer_create(size_t size)
{
struct buffer *b;
if (size == 0)
fatalx("zero size");
b = xcalloc(1, sizeof *b);
b->base = xmalloc(size);
b->space = size;
return (b);
}
/* Destroy a buffer. */
void
buffer_destroy(struct buffer *b)
{
xfree(b->base);
xfree(b);
}
/* Ensure free space for size in buffer. */
void
buffer_ensure(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (BUFFER_FREE(b) >= size)
return;
if (b->off > 0) {
if (b->size > 0)
memmove(b->base, b->base + b->off, b->size);
b->off = 0;
}
if (SIZE_MAX - b->size < size)
fatalx("size too big");
while (b->space < b->size + size) {
b->base = xrealloc(b->base, 2, b->space);
b->space *= 2;
}
}
/* Adjust buffer after data appended. */
void
buffer_add(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->space - b->size)
fatalx("overflow");
b->size += size;
}
/* Adjust buffer after data removed. */
void
buffer_remove(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
b->size -= size;
b->off += size;
}
/* Copy data into a buffer. */
void
buffer_write(struct buffer *b, const void *data, size_t size)
{
buffer_ensure(b, size);
memcpy(BUFFER_IN(b), data, size);
buffer_add(b, size);
}
/* Copy data out of a buffer. */
void
buffer_read(struct buffer *b, void *data, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
memcpy(data, BUFFER_OUT(b), size);
buffer_remove(b, size);
}
/* Store an 8-bit value. */
void
buffer_write8(struct buffer *b, uint8_t n)
{
buffer_ensure(b, 1);
BUFFER_IN(b)[0] = n;
b->size++;
}
/* Extract an 8-bit value. */
uint8_t
buffer_read8(struct buffer *b)
{
uint8_t n;
n = BUFFER_OUT(b)[0];
buffer_remove(b, 1);
return (n);
}

58
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.23 2009-10-28 23:12:38 tcunha Exp $ */
/* $Id: cfg.c,v 1.27 2010-06-06 00:04:18 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,13 +33,17 @@
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause;
char *cfg_cause;
int cfg_finished;
struct causelist cfg_causes = ARRAY_INITIALIZER;
/* ARGSUSED */
void printflike2
cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
{
}
/* ARGSUSED */
void printflike2
cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
{
@@ -50,19 +54,36 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
va_end(ap);
}
void printflike2
cfg_add_cause(struct causelist *causes, const char *fmt, ...)
{
char *cause;
va_list ap;
va_start(ap, fmt);
xvasprintf(&cause, fmt, ap);
va_end(ap);
ARRAY_ADD(causes, cause);
}
/*
* Load configuration file. Returns -1 for an error with a list of messages in
* causes. Note that causes must be initialised by the caller!
*/
int
load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
{
FILE *f;
u_int n;
char *buf, *line, *ptr;
char *buf, *line, *cause;
size_t len;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
if ((f = fopen(path, "rb")) == NULL) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (1);
cfg_add_cause(causes, "%s: %s", path, strerror(errno));
return (-1);
}
n = 0;
@@ -78,10 +99,12 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
}
n++;
if (cmd_string_parse(buf, &cmdlist, cause) != 0) {
if (*cause == NULL)
if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
if (cause == NULL)
continue;
goto error;
cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
xfree(cause);
continue;
}
if (cmdlist == NULL)
continue;
@@ -105,23 +128,16 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
if (cfg_cause != NULL) {
*cause = cfg_cause;
goto error;
cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause);
xfree(cfg_cause);
continue;
}
}
if (line != NULL)
xfree(line);
fclose(f);
if (ARRAY_LENGTH(causes) != 0)
return (-1);
return (0);
error:
if (line != NULL)
xfree(line);
fclose(f);
xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);
xfree(*cause);
*cause = ptr;
return (1);
}

240
client.c
View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.84 2009-11-02 21:41:16 tcunha Exp $ */
/* $Id: client.c,v 1.95 2010-07-02 02:52:13 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -17,13 +17,13 @@
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <errno.h>
#include <event.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
@@ -34,13 +34,17 @@
#include "tmux.h"
struct imsgbuf client_ibuf;
struct event client_event;
const char *client_exitmsg;
int client_exitval;
void client_send_identify(int);
void client_send_environ(void);
void client_write_server(enum msgtype, void *, size_t);
int client_dispatch(void);
void client_suspend(void);
void client_send_identify(int);
void client_send_environ(void);
void client_write_server(enum msgtype, void *, size_t);
void client_update_event(void);
void client_signal(int, short, void *);
void client_callback(int, short, void *);
int client_dispatch(void);
struct imsgbuf *
client_init(char *path, int cmdflags, int flags)
@@ -96,8 +100,7 @@ server_started:
if (cmdflags & CMD_SENDENVIRON)
client_send_environ();
if (isatty(STDIN_FILENO))
client_send_identify(flags);
client_send_identify(flags);
return (&client_ibuf);
@@ -114,17 +117,14 @@ void
client_send_identify(int flags)
{
struct msg_identify_data data;
struct winsize ws;
char *term;
int fd;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
data.flags = flags;
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0';
term = getenv("TERM");
if (term == NULL ||
strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
@@ -134,6 +134,14 @@ client_send_identify(int flags)
fatal("dup failed");
imsg_compose(&client_ibuf,
MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
if ((fd = dup(STDOUT_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf, MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 0);
if ((fd = dup(STDERR_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf, MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 0);
}
void
@@ -142,7 +150,7 @@ client_send_environ(void)
struct msg_environ_data data;
char **var;
for (var = environ; *var != NULL; var++) {
for (var = environ; *var != NULL; var++) {
if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
continue;
client_write_server(MSG_ENVIRON, &data, sizeof data);
@@ -152,99 +160,129 @@ client_send_environ(void)
void
client_write_server(enum msgtype type, void *buf, size_t len)
{
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
void
client_update_event(void)
{
short events;
event_del(&client_event);
events = EV_READ;
if (client_ibuf.w.queued > 0)
events |= EV_WRITE;
event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
event_add(&client_event, NULL);
}
__dead void
client_main(void)
{
struct pollfd pfd;
int n, nfds;
siginit();
logfile("client");
/* Note: event_init() has already been called. */
/* Set up signals. */
set_signals(client_signal);
/*
* Send a resize message immediately in case the terminal size has
* changed between the identify message to the server and the MSG_READY
* telling us to move into the client code.
*/
client_write_server(MSG_RESIZE, NULL, 0);
/*
* imsg_read in the first client poll loop (before the terminal has
* been initialiased) may have read messages into the buffer after the
* MSG_READY switched to here. Process anything outstanding now so poll
* doesn't hang waiting for messages that have already arrived.
* been initialised) may have read messages into the buffer after the
* MSG_READY switched to here. Process anything outstanding now to
* avoid hanging waiting for messages that have already arrived.
*/
if (client_dispatch() != 0)
goto out;
for (;;) {
if (sigterm) {
client_exitmsg = "terminated";
client_write_server(MSG_EXITING, NULL, 0);
}
if (sigchld) {
sigchld = 0;
waitpid(WAIT_ANY, NULL, WNOHANG);
continue;
}
if (sigwinch) {
sigwinch = 0;
client_write_server(MSG_RESIZE, NULL, 0);
continue;
}
if (sigcont) {
sigcont = 0;
siginit();
client_write_server(MSG_WAKEUP, NULL, 0);
continue;
}
pfd.fd = client_ibuf.fd;
pfd.events = POLLIN;
if (client_ibuf.w.queued > 0)
pfd.events |= POLLOUT;
if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
if (nfds == 0)
continue;
if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL))
fatalx("socket error");
if (pfd.revents & POLLIN) {
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0) {
client_exitmsg = "lost server";
break;
}
if (client_dispatch() != 0)
break;
}
if (pfd.revents & POLLOUT) {
if (msgbuf_write(&client_ibuf.w) < 0) {
client_exitmsg = "lost server";
break;
}
}
}
/* Set the event and dispatch. */
client_update_event();
event_dispatch();
out:
/* Print the exit message, if any, and exit. */
if (client_exitmsg != NULL) {
if (!login_shell)
printf("[%s]\n", client_exitmsg);
exit(1);
if (client_exitmsg != NULL && !login_shell)
printf("[%s]\n", client_exitmsg);
exit(client_exitval);
}
/* ARGSUSED */
void
client_signal(int sig, unused short events, unused void *data)
{
struct sigaction sigact;
switch (sig) {
case SIGHUP:
client_exitmsg = "lost tty";
client_exitval = 1;
client_write_server(MSG_EXITING, NULL, 0);
break;
case SIGTERM:
client_exitmsg = "terminated";
client_exitval = 1;
client_write_server(MSG_EXITING, NULL, 0);
break;
case SIGWINCH:
client_write_server(MSG_RESIZE, NULL, 0);
break;
case SIGCONT:
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_IGN;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
client_write_server(MSG_WAKEUP, NULL, 0);
break;
}
exit(0);
client_update_event();
}
/* ARGSUSED */
void
client_callback(unused int fd, short events, unused void *data)
{
ssize_t n;
if (events & EV_READ) {
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
goto lost_server;
if (client_dispatch() != 0) {
event_loopexit(NULL);
return;
}
}
if (events & EV_WRITE) {
if (msgbuf_write(&client_ibuf.w) < 0)
goto lost_server;
}
client_update_event();
return;
lost_server:
client_exitmsg = "lost server";
client_exitval = 1;
event_loopexit(NULL);
}
int
client_dispatch(void)
{
struct imsg imsg;
struct msg_lock_data lockdata;
ssize_t n, datalen;
struct imsg imsg;
struct msg_lock_data lockdata;
struct sigaction sigact;
ssize_t n, datalen;
for (;;) {
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
@@ -253,6 +291,7 @@ client_dispatch(void)
return (0);
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
log_debug("client got %d", imsg.hdr.type);
switch (imsg.hdr.type) {
case MSG_DETACH:
if (datalen != 0)
@@ -280,18 +319,25 @@ client_dispatch(void)
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "server exited";
client_exitval = 1;
break;
case MSG_SUSPEND:
if (datalen != 0)
fatalx("bad MSG_SUSPEND size");
client_suspend();
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
break;
case MSG_LOCK:
if (datalen != sizeof lockdata)
fatalx("bad MSG_LOCK size");
memcpy(&lockdata, imsg.data, sizeof lockdata);
lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
system(lockdata.cmd);
client_write_server(MSG_UNLOCK, NULL, 0);
@@ -303,23 +349,3 @@ client_dispatch(void)
imsg_free(&imsg);
}
}
void
client_suspend(void)
{
struct sigaction act;
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
act.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &act, NULL) != 0)
fatal("sigaction failed");
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
}

12
clock.c
View File

@@ -1,4 +1,4 @@
/* $Id: clock.c,v 1.7 2009-09-11 14:13:52 tcunha Exp $ */
/* $Id: clock.c,v 1.9 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -97,7 +97,7 @@ const char clock_table[14][5][5] = {
};
void
clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
clock_draw(struct screen_write_ctx *ctx, int colour, int style)
{
struct screen *s = ctx->s;
struct grid_cell gc;
@@ -134,13 +134,13 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
for (ptr = tim; *ptr != '\0'; ptr++) {
if (*ptr >= '0' && *ptr <= '9')
idx = *ptr - '0';
else if (*ptr == ':')
else if (*ptr == ':')
idx = 10;
else if (*ptr == 'A')
else if (*ptr == 'A')
idx = 11;
else if (*ptr == 'P')
else if (*ptr == 'P')
idx = 12;
else if (*ptr == 'M')
else if (*ptr == 'M')
idx = 13;
else {
x += 6;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-attach-session.c,v 1.32 2009-08-09 17:48:55 tcunha Exp $ */
/* $Id: cmd-attach-session.c,v 1.36 2010-02-08 18:27:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,8 +28,8 @@ int cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach",
"[-d] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, CMD_CHFLAG('d'),
"[-dr] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, "dr",
cmd_target_init,
cmd_target_parse,
cmd_attach_session_exec,
@@ -58,8 +58,8 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
if (ctx->cmdclient == NULL) {
if (data->chflags & CMD_CHFLAG('d')) {
/*
if (cmd_check_flag(data->chflags, 'd')) {
/*
* Can't use server_write_session in case attaching to
* the same session as currently attached to.
*/
@@ -72,7 +72,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
server_write_client(c, MSG_DETACH, NULL, 0);
}
}
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
} else {
@@ -89,7 +89,10 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
if (data->chflags & CMD_CHFLAG('d'))
if (cmd_check_flag(data->chflags, 'r'))
ctx->cmdclient->flags |= CLIENT_READONLY;
if (cmd_check_flag(data->chflags, 'd'))
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
@@ -101,6 +104,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_client(ctx->cmdclient);
}
recalculate_sizes();
server_update_socket();
return (1); /* 1 means don't tell command client to exit */
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-bind-key.c,v 1.25 2009-07-28 23:19:06 tcunha Exp $ */
/* $Id: cmd-bind-key.c,v 1.29 2010-07-02 02:43:01 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,7 +46,7 @@ struct cmd_bind_key_data {
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
"[-cnr] [-t key-table] key command [arguments]",
0, 0,
0, "",
NULL,
cmd_bind_key_parse,
cmd_bind_key_exec,
@@ -79,7 +79,8 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
data->can_repeat = 1;
break;
case 't':
data->tablename = xstrdup(optarg);
if (data->tablename == NULL)
data->tablename = xstrdup(optarg);
break;
default:
goto usage;
@@ -129,7 +130,7 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
return (cmd_bind_key_table(self, ctx));
key_bindings_add(data->key, data->can_repeat, data->cmdlist);
data->cmdlist = NULL; /* avoid free */
data->cmdlist->references++;
return (0);
}
@@ -152,7 +153,7 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "unknown command: %s", data->modecmd);
return (-1);
}
mtmp.key = data->key & ~KEYC_PREFIX;
mtmp.mode = data->command_key ? 1 : 0;
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
@@ -191,8 +192,17 @@ cmd_bind_key_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->command_key)
off += xsnprintf(buf + off, len - off, " -c");
if (off < len && !(data->key & KEYC_PREFIX))
off += xsnprintf(buf + off, len - off, " -n");
if (off < len && data->can_repeat)
off += xsnprintf(buf + off, len - off, " -r");
if (off < len && data->tablename != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->tablename);
if (off < len) {
skey = key_string_lookup_key(data->key);
skey = key_string_lookup_key(data->key & ~KEYC_PREFIX);
off += xsnprintf(buf + off, len - off, " %s ", skey);
}
if (off < len)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.9 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-break-pane.c,v 1.11 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp",
CMD_TARGET_PANE_USAGE " [-d]",
0, CMD_CHFLAG('d'),
0, "d",
cmd_target_init,
cmd_target_parse,
cmd_break_pane_exec,
@@ -64,18 +64,18 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl->window->active == NULL)
wl->window->active = TAILQ_NEXT(wp, entry);
}
layout_close_pane(wp);
layout_close_pane(wp);
w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
w->name = default_window_name(w);
w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
w->name = default_window_name(w);
layout_init(w);
base_idx = options_get_number(&s->options, "base-index");
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
if (!(data->chflags & CMD_CHFLAG('d')))
session_select(s, wl->idx);
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
if (!cmd_check_flag(data->chflags, 'd'))
session_select(s, wl->idx);
server_redraw_session(s);
server_status_session_group(s);

83
cmd-capture-pane.c Normal file
View File

@@ -0,0 +1,83 @@
/* $Id: cmd-capture-pane.c,v 1.3 2010-01-22 17:29:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Jonathan Alvarado <radobobo@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 "tmux.h"
/*
* Write the entire contents of a pane to a buffer.
*/
int cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_capture_pane_entry = {
"capture-pane", "capturep",
CMD_BUFFER_PANE_USAGE,
0, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_capture_pane_exec,
cmd_buffer_free,
cmd_buffer_print
};
int
cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct window_pane *wp;
char *buf, *line;
struct screen *s;
struct session *sess;
u_int i, limit;
size_t len, linelen;
if (cmd_find_pane(ctx, data->target, &sess, &wp) == NULL)
return (-1);
s = &wp->base;
buf = NULL;
len = 0;
for (i = 0; i < screen_size_y(s); i++) {
line = grid_view_string_cells(s->grid, 0, i, screen_size_x(s));
linelen = strlen(line);
buf = xrealloc(buf, 1, len + linelen + 1);
memcpy(buf + len, line, linelen);
len += linelen;
buf[len++] = '\n';
xfree(line);
}
limit = options_get_number(&sess->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&sess->buffers, buf, len, limit);
return (0);
}
if (paste_replace(&sess->buffers, data->buffer, buf, len) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf);
return (-1);
}
return (0);
}

146
cmd-choose-buffer.c Normal file
View File

@@ -0,0 +1,146 @@
/* $Id: cmd-choose-buffer.c,v 1.1 2010-06-22 23:35:20 tcunha Exp $ */
/*
* Copyright (c) 2010 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 <ctype.h>
#include "tmux.h"
/*
* Enter choice mode to choose a buffer.
*/
int cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_buffer_callback(void *, int);
void cmd_choose_buffer_free(void *);
const struct cmd_entry cmd_choose_buffer_entry = {
"choose-buffer", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, "",
cmd_target_init,
cmd_target_parse,
cmd_choose_buffer_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_choose_buffer_data {
struct client *client;
char *template;
};
int
cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_choose_buffer_data *cdata;
struct session *s;
struct winlink *wl;
struct paste_buffer *pb;
u_int idx;
char *tmp;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
s = ctx->curclient->session;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (paste_get_top(&s->buffers) == NULL)
return (0);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
idx = 0;
while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
tmp = paste_print(pb, 50);
window_choose_add(wl->window->active, idx - 1,
"%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp);
xfree(tmp);
}
cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL)
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("paste-buffer -b '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
0, cmd_choose_buffer_callback, cmd_choose_buffer_free, cdata);
return (0);
}
void
cmd_choose_buffer_callback(void *data, int idx)
{
struct cmd_choose_buffer_data *cdata = data;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause, tmp[16];
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
xsnprintf(tmp, sizeof tmp, "%u", idx);
template = cmd_template_replace(cdata->template, tmp, 1);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(cdata->client, "%s", cause);
xfree(cause);
}
xfree(template);
return;
}
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_buffer_free(void *data)
{
struct cmd_choose_buffer_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-client.c,v 1.3 2009-09-07 23:59:19 tcunha Exp $ */
/* $Id: cmd-choose-client.c,v 1.4 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_client_free(void *);
const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
CMD_ARG01, "",
cmd_target_init,
cmd_target_parse,
cmd_choose_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-session.c,v 1.14 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-choose-session.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_session_free(void *);
const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
CMD_ARG01, "",
cmd_target_init,
cmd_target_parse,
cmd_choose_session_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-window.c,v 1.18 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-choose-window.c,v 1.22 2010-06-22 23:26:18 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_window_free(void *);
const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
CMD_ARG01, "",
cmd_target_init,
cmd_target_parse,
cmd_choose_window_exec,
@@ -81,11 +81,11 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
idx++;
flag = ' ';
if (session_alert_has(s, wm, WINDOW_ACTIVITY))
if (wm->flags & WINLINK_ACTIVITY)
flag = '#';
else if (session_alert_has(s, wm, WINDOW_BELL))
else if (wm->flags & WINLINK_BELL)
flag = '!';
else if (session_alert_has(s, wm, WINDOW_CONTENT))
else if (wm->flags & WINLINK_CONTENT)
flag = '+';
else if (wm == s->curw)
flag = '*';
@@ -101,8 +101,9 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
left = right = "";
window_choose_add(wl->window->active,
wm->idx, "%3d: %s%c [%ux%u] (%u panes)%s%s%s",
wm->idx, "%3d: %s%c [%ux%u] (%u panes%s)%s%s%s",
wm->idx, w->name, flag, w->sx, w->sy, window_count_panes(w),
w->active->fd == -1 ? ", dead" : "",
left, title, right);
}
@@ -116,10 +117,10 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
window_choose_ready(wl->window->active,
cur, cmd_choose_window_callback, cmd_choose_window_free, cdata);
return (0);
return (0);
}
void
@@ -133,7 +134,7 @@ cmd_choose_window_callback(void *data, int idx)
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
return;
if (cdata->session->flags & SESSION_DEAD)
return;
if (cdata->client->session != cdata->session)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clear-history.c,v 1.7 2009-07-30 21:04:40 tcunha Exp $ */
/* $Id: cmd-clear-history.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
CMD_TARGET_PANE_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_clear_history_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clock-mode.c,v 1.6 2009-08-20 11:37:46 tcunha Exp $ */
/* $Id: cmd-clock-mode.c,v 1.7 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
CMD_TARGET_PANE_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_clock_mode_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-command-prompt.c,v 1.26 2009-09-22 14:06:40 tcunha Exp $ */
/* $Id: cmd-command-prompt.c,v 1.28 2010-05-14 14:33:39 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -39,7 +39,7 @@ void cmd_command_prompt_cfree(void *);
const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL,
CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]",
0, 0,
0, "",
cmd_command_prompt_init,
cmd_command_prompt_parse,
cmd_command_prompt_exec,
@@ -81,6 +81,10 @@ cmd_command_prompt_init(struct cmd *self, int key)
case 'f':
data->template = xstrdup("find-window '%%'");
break;
case '\'':
data->template = xstrdup("select-window -t ':%%'");
data->prompts = xstrdup("index");
break;
}
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-confirm-before.c,v 1.11 2009-08-24 16:24:18 tcunha Exp $ */
/* $Id: cmd-confirm-before.c,v 1.12 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -34,7 +34,7 @@ void cmd_confirm_before_free(void *);
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
CMD_TARGET_CLIENT_USAGE " command",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-buffer.c,v 1.5 2009-09-22 14:06:40 tcunha Exp $ */
/* $Id: cmd-copy-buffer.c,v 1.7 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -43,7 +43,7 @@ struct cmd_copy_buffer_data {
const struct cmd_entry cmd_copy_buffer_entry = {
"copy-buffer", "copyb",
"[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
0, 0,
0, "",
cmd_copy_buffer_init,
cmd_copy_buffer_parse,
cmd_copy_buffer_exec,
@@ -51,6 +51,7 @@ const struct cmd_entry cmd_copy_buffer_entry = {
cmd_copy_buffer_print
};
/* ARGSUSED */
void
cmd_copy_buffer_init(struct cmd *self, unused int arg)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-mode.c,v 1.24 2009-10-06 14:14:06 tcunha Exp $ */
/* $Id: cmd-copy-mode.c,v 1.27 2010-04-05 05:11:42 micahcowan Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,12 +30,12 @@ int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE,
0, CMD_CHFLAG('u'),
0, "u",
cmd_copy_mode_init,
cmd_target_parse,
cmd_copy_mode_exec,
cmd_target_free,
NULL
cmd_target_print
};
void
@@ -48,7 +48,7 @@ cmd_copy_mode_init(struct cmd *self, int key)
switch (key) {
case KEYC_PPAGE:
data->chflags |= CMD_CHFLAG('u');
cmd_set_flag(&data->chflags, 'u');
break;
}
}
@@ -63,7 +63,8 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
window_pane_set_mode(wp, &window_copy_mode);
if (wp->mode == &window_copy_mode && data->chflags & CMD_CHFLAG('u'))
window_copy_init_from_pane(wp);
if (wp->mode == &window_copy_mode && cmd_check_flag(data->chflags, 'u'))
window_copy_pageup(wp);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-delete-buffer.c,v 1.7 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-delete-buffer.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb",
CMD_BUFFER_SESSION_USAGE,
0, 0,
0, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_delete_buffer_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-detach-client.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-detach-client.c,v 1.11 2010-02-08 18:27:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_detach_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_detach_client_entry = {
"detach-client", "detach",
CMD_TARGET_CLIENT_USAGE,
0, 0,
CMD_READONLY, "",
cmd_target_init,
cmd_target_parse,
cmd_detach_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-display-message.c,v 1.3 2009-10-11 23:55:26 tcunha Exp $ */
/* $Id: cmd-display-message.c,v 1.7 2009-11-28 14:39:53 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -30,8 +30,8 @@ int cmd_display_message_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_message_entry = {
"display-message", "display",
CMD_TARGET_CLIENT_USAGE " [message]",
CMD_ARG01, 0,
"[-p] " CMD_TARGET_CLIENT_USAGE " [message]",
CMD_ARG01, "p",
cmd_target_init,
cmd_target_parse,
cmd_display_message_exec,
@@ -55,8 +55,11 @@ cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx)
else
template = data->arg;
msg = status_replace(c, template, time(NULL));
status_message_set(c, "%s", msg);
msg = status_replace(c, NULL, template, time(NULL), 0);
if (cmd_check_flag(data->chflags, 'p'))
ctx->print(ctx, "%s", msg);
else
status_message_set(c, "%s", msg);
xfree(msg);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-display-panes.c,v 1.1 2009-08-31 22:30:15 tcunha Exp $ */
/* $Id: cmd-display-panes.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_display_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
CMD_TARGET_CLIENT_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_display_panes_exec,

View File

@@ -1,59 +0,0 @@
/* $Id: cmd-down-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/*
* 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"
/*
* Move down a pane.
*/
int cmd_down_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_down_pane_entry = {
"down-pane", "downp",
CMD_TARGET_WINDOW_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_down_pane_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window *w;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
w = wl->window;
do {
w->active = TAILQ_NEXT(w->active, entry);
if (w->active == NULL)
w->active = TAILQ_FIRST(&w->panes);
} while (!window_pane_visible(w->active));
server_status_window(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-find-window.c,v 1.13 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-find-window.c,v 1.14 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_find_window_callback(void *, int);
const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw",
CMD_TARGET_WINDOW_USAGE " match-string",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_target_init,
cmd_target_parse,
cmd_find_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.34 2009-08-26 22:13:52 tcunha Exp $ */
/* $Id: cmd-generic.c,v 1.38 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,8 +23,8 @@
#include "tmux.h"
int cmd_getopt(int, char **, const char *, uint64_t);
int cmd_flags(int, uint64_t, uint64_t *);
int cmd_getopt(int, char **, const char *, const char *);
int cmd_parse_flags(int, const char *, uint64_t *);
size_t cmd_print_flags(char *, size_t, size_t, uint64_t);
int cmd_fill_argument(int, char **, char **, int, char **);
@@ -36,54 +36,56 @@ cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
return (xsnprintf(buf, len, "%s%s", prefix, arg));
}
/* Prepend flags from chflags onto flagstr and call getopt. */
/* Append two flag strings together and call getopt. */
int
cmd_getopt(int argc, char **argv, const char *flagstr, uint64_t chflags)
cmd_getopt(int argc, char **argv, const char *flagstr, const char *chflagstr)
{
u_char ch;
char buf[128];
size_t len, off;
char tmp[BUFSIZ];
*buf = '\0';
len = sizeof buf;
off = 0;
for (ch = 0; ch < 26; ch++) {
if (chflags & CMD_CHFLAG('a' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'a' + ch);
if (chflags & CMD_CHFLAG('A' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'A' + ch);
}
strlcat(buf, flagstr, sizeof buf);
return (getopt(argc, argv, buf));
if (strlcpy(tmp, flagstr, sizeof tmp) >= sizeof tmp)
fatalx("strlcpy overflow");
if (strlcat(tmp, chflagstr, sizeof tmp) >= sizeof tmp)
fatalx("strlcat overflow");
return (getopt(argc, argv, tmp));
}
/*
* If this option is expected (in ichflags), set it in ochflags, otherwise
* return -1.
*/
/* Return if flag character is set. */
int
cmd_flags(int opt, uint64_t ichflags, uint64_t *ochflags)
cmd_check_flag(uint64_t chflags, int flag)
{
u_char ch;
for (ch = 0; ch < 26; ch++) {
if (opt == 'a' + ch && ichflags & CMD_CHFLAG(opt)) {
(*ochflags) |= CMD_CHFLAG(opt);
return (0);
}
if (opt == 'A' + ch && ichflags & CMD_CHFLAG(opt)) {
(*ochflags) |= CMD_CHFLAG(opt);
return (0);
}
}
return (-1);
if (flag >= 'A' && flag <= 'Z')
flag = 26 + flag - 'A';
else if (flag >= 'a' && flag <= 'z')
flag = flag - 'a';
else
return (0);
return ((chflags & (1ULL << flag)) != 0);
}
/* Print the flags supported in chflags. */
/* Set flag character. */
void
cmd_set_flag(uint64_t *chflags, int flag)
{
if (flag >= 'A' && flag <= 'Z')
flag = 26 + flag - 'A';
else if (flag >= 'a' && flag <= 'z')
flag = flag - 'a';
else
return;
(*chflags) |= (1ULL << flag);
}
/* If this option is expected, set it in chflags, otherwise return -1. */
int
cmd_parse_flags(int opt, const char *chflagstr, uint64_t *chflags)
{
if (strchr(chflagstr, opt) == NULL)
return (-1);
cmd_set_flag(chflags, opt);
return (0);
}
/* Print the flags present in chflags. */
size_t
cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags)
{
@@ -95,9 +97,9 @@ cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags)
off += xsnprintf(buf + off, len - off, " -");
for (ch = 0; ch < 26; ch++) {
if (chflags & CMD_CHFLAG('a' + ch))
if (cmd_check_flag(chflags, 'a' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'a' + ch);
if (chflags & CMD_CHFLAG('A' + ch))
if (cmd_check_flag(chflags, 'A' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'A' + ch);
}
return (off - boff);
@@ -139,13 +141,14 @@ cmd_fill_argument(int flags, char **arg, char **arg2, int argc, char **argv)
if (argc == 2)
*arg2 = xstrdup(argv[1]);
return (0);
}
}
if (argc != 0)
return (-1);
return (0);
}
/* ARGSUSED */
void
cmd_target_init(struct cmd *self, unused int key)
{
@@ -170,7 +173,7 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
data = self->data;
while ((opt = cmd_getopt(argc, argv, "t:", entry->chflags)) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
switch (opt) {
case 't':
@@ -222,13 +225,14 @@ cmd_target_print(struct cmd *self, char *buf, size_t len)
off += cmd_print_flags(buf, len, off, data->chflags);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL)
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}
/* ARGSUSED */
void
cmd_srcdst_init(struct cmd *self, unused int key)
{
@@ -253,7 +257,7 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
data = self->data;
while ((opt = cmd_getopt(argc, argv, "s:t:", entry->chflags)) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
switch (opt) {
case 's':
@@ -313,13 +317,14 @@ cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf + off, len - off, " -s %s", data->src);
if (off < len && data->dst != NULL)
off += xsnprintf(buf + off, len - off, " -t %s", data->dst);
if (off < len && data->arg != NULL)
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}
/* ARGSUSED */
void
cmd_buffer_init(struct cmd *self, unused int key)
{
@@ -345,7 +350,7 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
data = self->data;
while ((opt = cmd_getopt(argc, argv, "b:t:", entry->chflags)) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
switch (opt) {
case 'b':
@@ -410,9 +415,9 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL)
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-has-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-has-session.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_has_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_has_session_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-if-shell.c,v 1.7 2009-11-02 21:38:26 tcunha Exp $ */
/* $Id: cmd-if-shell.c,v 1.9 2010-07-17 14:36:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -36,7 +36,7 @@ void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"shell-command command",
CMD_ARG2, 0,
CMD_ARG2, "",
cmd_target_init,
cmd_target_parse,
cmd_if_shell_exec,
@@ -104,10 +104,13 @@ cmd_if_shell_free(void *data)
{
struct cmd_if_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
struct msg_exit_data exitdata;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
exitdata.retcode = ctx->cmdclient->retcode;
server_write_client(
ctx->cmdclient, MSG_EXIT, &exitdata, sizeof exitdata);
}
if (ctx->curclient != NULL)
ctx->curclient->references--;

257
cmd-join-pane.c Normal file
View File

@@ -0,0 +1,257 @@
/* $Id: cmd-join-pane.c,v 1.4 2010-04-09 07:09:37 micahcowan Exp $ */
/*
* 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 <unistd.h>
#include "tmux.h"
/*
* Join a pane into another (like split/swap/kill).
*/
int cmd_join_pane_parse(struct cmd *, int, char **, char **);
int cmd_join_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_join_pane_free(struct cmd *);
void cmd_join_pane_init(struct cmd *, int);
size_t cmd_join_pane_print(struct cmd *, char *, size_t);
struct cmd_join_pane_data {
char *src;
char *dst;
int flag_detached;
int flag_horizontal;
int percentage;
int size;
};
const struct cmd_entry cmd_join_pane_entry = {
"join-pane", "joinp",
"[-dhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane] [command]",
0, "",
cmd_join_pane_init,
cmd_join_pane_parse,
cmd_join_pane_exec,
cmd_join_pane_free,
cmd_join_pane_print
};
void
cmd_join_pane_init(struct cmd *self, int key)
{
struct cmd_join_pane_data *data;
self->data = data = xmalloc(sizeof *data);
data->src = NULL;
data->dst = NULL;
data->flag_detached = 0;
data->flag_horizontal = 0;
data->percentage = -1;
data->size = -1;
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
case '"':
data->flag_horizontal = 0;
break;
}
}
int
cmd_join_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_join_pane_data *data;
int opt;
const char *errstr;
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dhl:p:s:t:v")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
break;
case 'h':
data->flag_horizontal = 1;
break;
case 's':
if (data->src == NULL)
data->src = xstrdup(optarg);
break;
case 't':
if (data->dst == NULL)
data->dst = xstrdup(optarg);
break;
case 'l':
if (data->percentage != -1 || data->size != -1)
break;
data->size = strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "size %s", errstr);
goto error;
}
break;
case 'p':
if (data->size != -1 || data->percentage != -1)
break;
data->percentage = strtonum(optarg, 1, 100, &errstr);
if (errstr != NULL) {
xasprintf(cause, "percentage %s", errstr);
goto error;
}
break;
case 'v':
data->flag_horizontal = 0;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 0)
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
}
int
cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_join_pane_data *data = self->data;
struct session *dst_s;
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w;
struct window_pane *src_wp, *dst_wp;
int size, dst_idx;
enum layout_type type;
struct layout_cell *lc;
if ((dst_wl = cmd_find_pane(ctx, data->dst, &dst_s, &dst_wp)) == NULL)
return (-1);
dst_w = dst_wl->window;
dst_idx = dst_wl->idx;
if ((src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp)) == NULL)
return (-1);
src_w = src_wl->window;
if (src_w == dst_w) {
ctx->error(ctx, "can't join a pane to its own window");
return (-1);
}
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1) {
if (type == LAYOUT_TOPBOTTOM)
size = (dst_wp->sy * data->percentage) / 100;
else
size = (dst_wp->sx * data->percentage) / 100;
}
if ((lc = layout_split_pane(dst_wp, type, size)) == NULL) {
ctx->error(ctx, "create pane failed: pane too small");
return (-1);
}
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);
}
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
if (window_count_panes(src_w) == 0)
server_kill_window(src_w);
src_wp->window = dst_w;
TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
layout_assign_pane(lc, src_wp);
recalculate_sizes();
server_redraw_window(src_w);
server_redraw_window(dst_w);
if (!data->flag_detached) {
window_set_active_pane(dst_w, src_wp);
session_select(dst_s, dst_idx);
server_redraw_session(dst_s);
} else
server_status_session(dst_s);
return (0);
}
void
cmd_join_pane_free(struct cmd *self)
{
struct cmd_join_pane_data *data = self->data;
if (data->src != NULL)
xfree(data->src);
if (data->dst != NULL)
xfree(data->dst);
xfree(data);
}
size_t
cmd_join_pane_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_join_pane_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->flag_horizontal)
off += xsnprintf(buf + off, len - off, " -h");
if (off < len && data->size > 0)
off += xsnprintf(buf + off, len - off, " -l %d", data->size);
if (off < len && data->percentage > 0) {
off += xsnprintf(
buf + off, len - off, " -p %d", data->percentage);
}
if (off < len && data->src != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->src);
if (off < len && data->dst != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->dst);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.14 2009-10-25 10:41:03 tcunha Exp $ */
/* $Id: cmd-kill-pane.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp",
"[-a] " CMD_TARGET_PANE_USAGE,
0, CMD_CHFLAG('a'),
0, "a",
cmd_target_init,
cmd_target_parse,
cmd_kill_pane_exec,
@@ -56,7 +56,7 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
if (data->chflags & CMD_CHFLAG('a')) {
if (cmd_check_flag(data->chflags, 'a')) {
loopwp = TAILQ_FIRST(&wl->window->panes);
while (loopwp != NULL) {
nextwp = TAILQ_NEXT(loopwp, entry);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-kill-server.c,v 1.11 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_kill_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_server_entry = {
"kill-server", NULL,
"",
0, 0,
0, "",
NULL,
NULL,
cmd_kill_server_exec,
@@ -40,10 +40,11 @@ const struct cmd_entry cmd_kill_server_entry = {
NULL
};
/* ARGSUSED */
int
cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{
sigterm = 1;
kill(getpid(), SIGTERM);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-session.c,v 1.15 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-kill-session.c,v 1.18 2010-07-02 02:43:50 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_kill_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL,
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_kill_session_exec,
@@ -45,21 +45,11 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct client *c;
u_int i;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
}
}
recalculate_sizes();
server_destroy_session(s);
session_destroy(s);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.20 2009-09-20 22:15:32 tcunha Exp $ */
/* $Id: cmd-kill-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_kill_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_kill_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-last-window.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-last-window.c,v 1.19 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_last_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_last_window_entry = {
"last-window", "last",
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_last_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-link-window.c,v 1.35 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-link-window.c,v 1.36 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
0, "dk",
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_link_window_exec,
@@ -53,8 +53,8 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
kflag = data->chflags & CMD_CHFLAG('k');
dflag = data->chflags & CMD_CHFLAG('d');
kflag = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't link window: %s", cause);
xfree(cause);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-buffers.c,v 1.12 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-list-buffers.c,v 1.16 2010-06-22 23:35:20 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_buffers_entry = {
"list-buffers", "lsb",
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_buffers_exec,
@@ -46,32 +46,17 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct paste_buffer *pb;
u_int idx;
char tmp[51 * 4 + 1];
size_t size, len;
char *tmp;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
idx = 0;
while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
size = pb->size;
/* Translate the first 50 characters. */
len = size;
if (len > 50)
len = 50;
strvisx(tmp, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL);
/*
* If the first 50 characterswere encoded as a longer string,
* or there is definitely more data, add "...".
*/
if (size > 50 || strlen(tmp) > 50) {
tmp[50 - 3] = '\0';
strlcat(tmp, "...", sizeof tmp);
}
ctx->print(ctx, "%u: %zu bytes: \"%s\"", idx - 1, size, tmp);
tmp = paste_print(pb, 50);
ctx->print(ctx,
"%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp);
xfree(tmp);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-clients.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-list-clients.c,v 1.20 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc",
"",
0, 0,
0, "",
NULL,
NULL,
cmd_list_clients_exec,
@@ -40,6 +40,7 @@ const struct cmd_entry cmd_list_clients_entry = {
NULL
};
/* ARGSUSED */
int
cmd_list_clients_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-commands.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-list-commands.c,v 1.7 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_list_commands_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm",
"",
0, 0,
0, "",
NULL,
NULL,
cmd_list_commands_exec,
@@ -37,6 +37,7 @@ const struct cmd_entry cmd_list_commands_entry = {
NULL
};
/* ARGSUSED */
int
cmd_list_commands_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-keys.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/* $Id: cmd-list-keys.c,v 1.24 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ int cmd_list_keys_table(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk",
"[-t key-table]",
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_keys_exec,
@@ -47,7 +47,8 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct key_binding *bd;
const char *key;
char tmp[BUFSIZ], keytmp[64];
char tmp[BUFSIZ];
size_t used;
int width, keywidth;
if (data->target != NULL)
@@ -70,14 +71,17 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
used = xsnprintf(tmp, sizeof tmp, "%*s: ", width, key);
if (used >= sizeof tmp)
continue;
*tmp = '\0';
cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
if (!(bd->key & KEYC_PREFIX)) {
xsnprintf(keytmp, sizeof keytmp, "[%s]", key);
key = keytmp;
used = strlcat(tmp, "(no prefix) ", sizeof tmp);
if (used >= sizeof tmp)
continue;
}
ctx->print(ctx, "%*s: %s", width, key, tmp);
cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
ctx->print(ctx, "%s", tmp);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-panes.c,v 1.2 2009-10-15 20:10:28 tcunha Exp $ */
/* $Id: cmd-list-panes.c,v 1.4 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,7 +23,7 @@
#include "tmux.h"
/*
* List panes on given window..
* List panes on given window.
*/
int cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
@@ -31,7 +31,7 @@ int cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_panes_exec,
@@ -56,7 +56,7 @@ cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
n = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
gd = wp->base.grid;
size = 0;
for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i];
@@ -64,7 +64,7 @@ cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
size += gl->utf8size * sizeof *gl->utf8data;
}
size += gd->hsize * sizeof *gd->linedata;
ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes]",
n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
n++;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-sessions.c,v 1.23 2009-11-04 22:42:31 tcunha Exp $ */
/* $Id: cmd-list-sessions.c,v 1.25 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", "",
0, 0,
0, "",
NULL,
NULL,
cmd_list_sessions_exec,
@@ -39,6 +39,7 @@ const struct cmd_entry cmd_list_sessions_entry = {
NULL
};
/* ARGSUSED */
int
cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.41 2009-10-12 00:08:12 tcunha Exp $ */
/* $Id: cmd-list-windows.c,v 1.43 2010-07-02 02:54:52 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw",
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_windows_exec,
@@ -45,6 +45,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct winlink *wl;
char *layout;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
@@ -52,6 +53,9 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
RB_FOREACH(wl, winlinks, &s->windows) {
ctx->print(ctx, "%d: %s [%ux%u]",
wl->idx, wl->window->name, wl->window->sx, wl->window->sy);
layout = layout_dump(wl->window);
ctx->print(ctx, " layout: %s", layout);
xfree(layout);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-list.c,v 1.9 2010-07-02 02:43:01 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,8 @@ cmd_list_parse(int argc, char **argv, char **cause)
char **new_argv;
cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist);
cmdlist->references = 1;
TAILQ_INIT(&cmdlist->list);
lastsplit = 0;
for (i = 0; i < argc; i++) {
@@ -54,7 +55,7 @@ cmd_list_parse(int argc, char **argv, char **cause)
cmd = cmd_parse(new_argc, new_argv, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
lastsplit = i + 1;
}
@@ -63,7 +64,7 @@ cmd_list_parse(int argc, char **argv, char **cause)
cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
}
return (cmdlist);
@@ -77,13 +78,36 @@ int
cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
{
struct cmd *cmd;
int n;
int n, retval;
TAILQ_FOREACH(cmd, cmdlist, qentry) {
if ((n = cmd_exec(cmd, ctx)) != 0)
return (n);
retval = 0;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if ((n = cmd_exec(cmd, ctx)) == -1)
return (-1);
/*
* A 1 return value means the command client is being attached
* (sent MSG_READY).
*/
if (n == 1) {
retval = 1;
/*
* The command client has been attached, so mangle the
* context to treat any following commands as if they
* were called from inside.
*/
if (ctx->curclient == NULL) {
ctx->curclient = ctx->cmdclient;
ctx->cmdclient = NULL;
ctx->error = key_bindings_error;
ctx->print = key_bindings_print;
ctx->info = key_bindings_info;
}
}
}
return (0);
return (retval);
}
void
@@ -91,9 +115,12 @@ cmd_list_free(struct cmd_list *cmdlist)
{
struct cmd *cmd;
while (!TAILQ_EMPTY(cmdlist)) {
cmd = TAILQ_FIRST(cmdlist);
TAILQ_REMOVE(cmdlist, cmd, qentry);
if (--cmdlist->references != 0)
return;
while (!TAILQ_EMPTY(&cmdlist->list)) {
cmd = TAILQ_FIRST(&cmdlist->list);
TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
cmd_free(cmd);
}
xfree(cmdlist);
@@ -106,7 +133,7 @@ cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
size_t off;
off = 0;
TAILQ_FOREACH(cmd, cmdlist, qentry) {
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (off >= len)
break;
off += cmd_print(cmd, buf + off, len - off);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.11 2009-10-28 23:10:05 tcunha Exp $ */
/* $Id: cmd-load-buffer.c,v 1.16 2010-07-02 02:52:13 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -17,9 +17,9 @@
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -35,7 +35,7 @@ int cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb",
CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_load_buffer_exec,
@@ -48,54 +48,71 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct session *s;
struct stat sb;
FILE *f;
u_char *buf;
FILE *f, *close_f;
char *pdata, *new_pdata;
size_t psize;
u_int limit;
int ch;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
if (strcmp(data->arg, "-") == 0 ) {
if (ctx->cmdclient == NULL) {
ctx->error(ctx, "%s: can't read from stdin", data->arg);
return (-1);
}
f = ctx->cmdclient->stdin_file;
if (isatty(fileno(ctx->cmdclient->stdin_file))) {
ctx->error(ctx, "%s: stdin is a tty", data->arg);
return (-1);
}
close_f = NULL;
} else {
if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
close_f = f;
}
if (fstat(fileno(f), &sb) < 0) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
fclose(f);
return (-1);
pdata = NULL;
psize = 0;
while ((ch = getc(f)) != EOF) {
/* Do not let the server die due to memory exhaustion. */
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
ctx->error(ctx, "realloc error: %s", strerror(errno));
goto error;
}
pdata = new_pdata;
pdata[psize++] = ch;
}
/*
* We don't want to die due to memory exhaustion, hence xmalloc can't
* be used here.
*/
if ((buf = malloc(sb.st_size + 1)) == NULL) {
ctx->error(ctx, "malloc error: %s", strerror(errno));
fclose(f);
return (-1);
if (ferror(f)) {
ctx->error(ctx, "%s: read error", data->arg);
goto error;
}
if (pdata != NULL)
pdata[psize] = '\0';
if (fread(buf, 1, sb.st_size, f) != (size_t) sb.st_size) {
ctx->error(ctx, "%s: fread error", data->arg);
xfree(buf);
fclose(f);
return (-1);
}
fclose(f);
if (close_f != NULL)
fclose(close_f);
limit = options_get_number(&s->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&s->buffers, buf, sb.st_size, limit);
paste_add(&s->buffers, pdata, psize, limit);
return (0);
}
if (paste_replace(&s->buffers, data->buffer, buf, sb.st_size) != 0) {
if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf);
return (-1);
goto error;
}
return (0);
error:
if (pdata != NULL)
xfree(pdata);
if (close_f != NULL)
fclose(close_f);
return (-1);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-client.c,v 1.1 2009-09-25 17:51:39 tcunha Exp $ */
/* $Id: cmd-lock-client.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_lock_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_client_entry = {
"lock-client", "lockc",
CMD_TARGET_CLIENT_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_lock_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-server.c,v 1.7 2009-09-25 17:47:42 tcunha Exp $ */
/* $Id: cmd-lock-server.c,v 1.9 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock",
"",
0, 0,
0, "",
NULL,
NULL,
cmd_lock_server_exec,
@@ -41,6 +41,7 @@ const struct cmd_entry cmd_lock_server_entry = {
NULL,
};
/* ARGSUSED */
int
cmd_lock_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-session.c,v 1.1 2009-09-25 17:51:39 tcunha Exp $ */
/* $Id: cmd-lock-session.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_lock_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_session_entry = {
"lock-session", "locks",
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_lock_session_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-move-window.c,v 1.12 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-move-window.c,v 1.13 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_move_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew",
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
0, "dk",
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_move_window_exec,
@@ -53,8 +53,8 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
kflag = data->chflags & CMD_CHFLAG('k');
dflag = data->chflags & CMD_CHFLAG('d');
kflag = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't move window: %s", cause);
xfree(cause);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.69 2009-10-12 00:49:06 tcunha Exp $ */
/* $Id: cmd-new-session.c,v 1.78 2010-07-02 02:49:19 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,10 @@
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "tmux.h"
@@ -44,7 +46,7 @@ struct cmd_new_session_data {
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"[-d] [-n window-name] [-s session-name] [-t target-session] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, 0,
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, "",
cmd_new_session_init,
cmd_new_session_parse,
cmd_new_session_exec,
@@ -52,6 +54,7 @@ const struct cmd_entry cmd_new_session_entry = {
cmd_new_session_print
};
/* ARGSUSED */
void
cmd_new_session_init(struct cmd *self, unused int arg)
{
@@ -121,12 +124,14 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_new_session_data *data = self->data;
struct session *s, *groupwith;
struct window *w;
struct window_pane *wp;
struct environ env;
struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
struct passwd *pw;
const char *update, *cwd;
char *overrides, *cmd, *cause;
int detached, idx;
u_int sx, sy;
u_int sx, sy, i;
if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname);
@@ -183,8 +188,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "not a terminal");
return (-1);
}
overrides =
overrides =
options_get_string(&global_s_options, "terminal-overrides");
if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause);
@@ -196,8 +201,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Get the new session working directory. */
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
cwd = ctx->cmdclient->cwd;
else
cwd = options_get_string(&global_s_options, "default-path");
else {
pw = getpwuid(getuid());
if (pw->pw_dir != NULL && *pw->pw_dir != '\0')
cwd = pw->pw_dir;
else
cwd = "/";
}
/* Find new session size. */
if (detached) {
@@ -266,17 +276,34 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
* Set the client to the new session. If a command client exists, it is
* taking this session and needs to get MSG_READY and stay around.
*/
if (!detached) {
if (!detached) {
if (ctx->cmdclient != NULL) {
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
ctx->cmdclient->session = s;
ctx->cmdclient->session = s;
server_redraw_client(ctx->cmdclient);
} else {
ctx->curclient->session = s;
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
}
}
recalculate_sizes();
server_update_socket();
/*
* If there are still configuration file errors to display, put the new
* session's current window into more mode and display them now.
*/
if (cfg_finished && !ARRAY_EMPTY(&cfg_causes)) {
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);
xfree(cause);
}
ARRAY_FREE(&cfg_causes);
}
return (!detached); /* 1 means don't tell command client to exit */
}
@@ -306,10 +333,12 @@ cmd_new_session_print(struct cmd *self, char *buf, size_t len)
return (off);
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->newname != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
if (off < len && data->winname != NULL)
off += cmd_prarg(buf + off, len - off, " -n ", data->winname);
if (off < len && data->newname != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-window.c,v 1.39 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-new-window.c,v 1.47 2010-07-02 02:49:19 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -36,14 +36,15 @@ struct cmd_new_window_data {
char *target;
char *name;
char *cmd;
int flag_insert_after;
int flag_detached;
int flag_kill;
};
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
"[-dk] [-n window-name] [-t target-window] [command]",
0, 0,
"[-adk] [-n window-name] [-t target-window] [command]",
0, "",
cmd_new_window_init,
cmd_new_window_parse,
cmd_new_window_exec,
@@ -51,6 +52,7 @@ const struct cmd_entry cmd_new_window_entry = {
cmd_new_window_print
};
/* ARGSUSED */
void
cmd_new_window_init(struct cmd *self, unused int arg)
{
@@ -60,6 +62,7 @@ cmd_new_window_init(struct cmd *self, unused int arg)
data->target = NULL;
data->name = NULL;
data->cmd = NULL;
data->flag_insert_after = 0;
data->flag_detached = 0;
data->flag_kill = 0;
}
@@ -73,8 +76,11 @@ cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause)
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dkt:n:")) != -1) {
while ((opt = getopt(argc, argv, "adkt:n:")) != -1) {
switch (opt) {
case 'a':
data->flag_insert_after = 1;
break;
case 'd':
data->flag_detached = 1;
break;
@@ -117,42 +123,66 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
char *cmd, *cwd, *cause;
int idx;
int idx, last;
if (data == NULL)
return (0);
if ((idx = cmd_find_index(ctx, data->target, &s)) == -2)
return (-1);
if (data->flag_insert_after) {
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
idx = wl->idx + 1;
/* Find the next free index. */
for (last = idx; last < INT_MAX; last++) {
if (winlink_find_by_index(&s->windows, last) == NULL)
break;
}
if (last == INT_MAX) {
ctx->error(ctx, "no free window indexes");
return (-1);
}
/* Move everything from last - 1 to idx up a bit. */
for (; last > idx; last--) {
wl = winlink_find_by_index(&s->windows, last - 1);
server_link_window(s, wl, s, last, 0, 0, NULL);
server_unlink_window(s, wl);
}
} else {
if ((idx = cmd_find_index(ctx, data->target, &s)) == -2)
return (-1);
}
wl = NULL;
if (idx != -1)
wl = winlink_find_by_index(&s->windows, idx);
if (wl != NULL) {
if (data->flag_kill) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(s, wl);
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
if (wl != NULL && data->flag_kill) {
/*
* Can't use session_detach as it will destroy session if this
* makes it empty.
*/
wl->flags &= ~WINLINK_ALERTFLAGS;
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
}
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
}
}
cmd = data->cmd;
if (cmd == NULL)
cmd = options_get_string(&s->options, "default-command");
if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
cwd = options_get_string(&s->options, "default-path");
else
cwd = ctx->cmdclient->cwd;
cwd = options_get_string(&s->options, "default-path");
if (*cwd == '\0') {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
cwd = ctx->cmdclient->cwd;
else
cwd = s->cwd;
}
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
@@ -165,7 +195,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (!data->flag_detached) {
session_select(s, wl->idx);
server_redraw_session_group(s);
} else
} else
server_status_session_group(s);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-layout.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-next-layout.c,v 1.6 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_next_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_layout_entry = {
"next-layout", "nextl",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_next_layout_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-next-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_next_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_window_entry = {
"next-window", "next",
"[-a] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('a'),
0, "a",
cmd_next_window_init,
cmd_target_parse,
cmd_next_window_exec,
@@ -47,7 +47,7 @@ cmd_next_window_init(struct cmd *self, int key)
data = self->data;
if (key == ('n' | KEYC_ESCAPE))
data->chflags |= CMD_CHFLAG('a');
cmd_set_flag(&data->chflags, 'a');
}
int
@@ -61,7 +61,7 @@ cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
activity = 0;
if (data->chflags & CMD_CHFLAG('a'))
if (cmd_check_flag(data->chflags, 'a'))
activity = 1;
if (session_next(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-paste-buffer.c,v 1.20 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-paste-buffer.c,v 1.28 2010-06-06 00:03:02 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -26,32 +27,112 @@
* Paste paste buffer if present.
*/
struct cmd_paste_buffer_data {
char *target;
int buffer;
int flag_delete;
char *sepstr;
};
void cmd_paste_buffer_init(struct cmd *, int);
int cmd_paste_buffer_parse(struct cmd *, int, char **, char **);
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_paste_buffer_lf2cr(struct buffer *, const char *, size_t);
void cmd_paste_buffer_filter(
struct window_pane *, const char *, size_t, char *);
void cmd_paste_buffer_free(struct cmd *);
size_t cmd_paste_buffer_print(struct cmd *, char *, size_t);
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
"[-dr] " CMD_BUFFER_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('r'),
cmd_buffer_init,
cmd_buffer_parse,
"[-dr] [-s separator] [-b buffer-index] [-t target-window]",
0, "",
cmd_paste_buffer_init,
cmd_paste_buffer_parse,
cmd_paste_buffer_exec,
cmd_buffer_free,
cmd_buffer_print
cmd_paste_buffer_free,
cmd_paste_buffer_print
};
/* ARGSUSED */
void
cmd_paste_buffer_init(struct cmd *self, unused int arg)
{
struct cmd_paste_buffer_data *data;
self->data = data = xmalloc(sizeof *data);
data->target = NULL;
data->buffer = -1;
data->flag_delete = 0;
data->sepstr = xstrdup("\r");
}
int
cmd_paste_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_paste_buffer_data *data;
int opt, n;
const char *errstr;
cmd_paste_buffer_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "b:ds:t:r")) != -1) {
switch (opt) {
case 'b':
if (data->buffer == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "buffer %s", errstr);
goto error;
}
data->buffer = n;
}
break;
case 'd':
data->flag_delete = 1;
break;
case 's':
if (data->sepstr != NULL)
xfree(data->sepstr);
data->sepstr = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'r':
if (data->sepstr != NULL)
xfree(data->sepstr);
data->sepstr = xstrdup("\n");
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
}
int
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct session *s;
struct paste_buffer *pb;
struct cmd_paste_buffer_data *data = self->data;
struct window_pane *wp;
struct session *s;
struct paste_buffer *pb;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
return (-1);
wp = wl->window->active;
if (data->buffer == -1)
pb = paste_get_top(&s->buffers);
@@ -62,39 +143,80 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (pb != NULL && *pb->data != '\0') {
/* -r means raw data without LF->CR conversion. */
if (data->chflags & CMD_CHFLAG('r'))
buffer_write(wp->out, pb->data, pb->size);
else
cmd_paste_buffer_lf2cr(wp->out, pb->data, pb->size);
}
if (pb != NULL)
cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr);
/* Delete the buffer if -d. */
if (data->chflags & CMD_CHFLAG('d')) {
if (data->flag_delete) {
if (data->buffer == -1)
paste_free_top(&s->buffers);
else
paste_free_index(&s->buffers, data->buffer);
}
return (0);
return (0);
}
/* Add bytes to a buffer but change every '\n' to '\r'. */
/* Add bytes to a buffer and filter '\n' according to separator. */
void
cmd_paste_buffer_lf2cr(struct buffer *b, const char *data, size_t size)
cmd_paste_buffer_filter(
struct window_pane *wp, const char *data, size_t size, char *sep)
{
const char *end = data + size;
const char *lf;
size_t seplen;
seplen = strlen(sep);
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
buffer_write(b, data, lf - data);
buffer_write8(b, '\r');
bufferevent_write(wp->event, data, lf - data);
bufferevent_write(wp->event, sep, seplen);
data = lf + 1;
}
if (end != data)
buffer_write(b, data, end - data);
bufferevent_write(wp->event, data, end - data);
}
void
cmd_paste_buffer_free(struct cmd *self)
{
struct cmd_paste_buffer_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
if (data->sepstr != NULL)
xfree(data->sepstr);
xfree(data);
}
size_t
cmd_paste_buffer_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_paste_buffer_data *data = self->data;
size_t off = 0;
char tmp[BUFSIZ];
int r_flag;
r_flag = 0;
if (data->sepstr != NULL)
r_flag = (data->sepstr[0] == '\n' && data->sepstr[1] == '\0');
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_delete)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && r_flag)
off += xsnprintf(buf + off, len - off, " -r");
if (off < len && data->buffer != -1)
off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
if (off < len && data->sepstr != NULL && !r_flag) {
strnvis(
tmp, data->sepstr, sizeof tmp, VIS_OCTAL|VIS_TAB|VIS_NL);
off += cmd_prarg(buf + off, len - off, " -s ", tmp);
}
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-pipe-pane.c,v 1.3 2009-10-23 17:26:40 tcunha Exp $ */
/* $Id: cmd-pipe-pane.c,v 1.13 2010-06-15 20:25:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -17,10 +17,12 @@
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "tmux.h"
@@ -31,10 +33,12 @@
int cmd_pipe_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
CMD_TARGET_PANE_USAGE "[-o] [command]",
CMD_ARG01, CMD_CHFLAG('o'),
CMD_ARG01, "o",
cmd_target_init,
cmd_target_parse,
cmd_pipe_pane_exec,
@@ -46,16 +50,21 @@ int
cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
struct window_pane *wp;
char *command;
int old_fd, pipe_fd[2], null_fd, mode;
if ((c = cmd_find_client(ctx, NULL)) == NULL)
return (-1);
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
/* Destroy the old pipe. */
old_fd = wp->pipe_fd;
if (wp->pipe_fd != -1) {
buffer_destroy(wp->pipe_buf);
bufferevent_free(wp->pipe_event);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}
@@ -70,12 +79,12 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
*
* bind ^p pipep -o 'cat >>~/output'
*/
if (data->chflags & CMD_CHFLAG('o') && old_fd != -1)
if (cmd_check_flag(data->chflags, 'o') && old_fd != -1)
return (0);
/* Open the new pipe. */
if (pipe(pipe_fd) != 0) {
ctx->error(ctx, "pipe error: %s", strerror(errno));
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
ctx->error(ctx, "socketpair error: %s", strerror(errno));
return (-1);
}
@@ -83,11 +92,11 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
switch (fork()) {
case -1:
ctx->error(ctx, "fork error: %s", strerror(errno));
return (-1);
return (-1);
case 0:
/* Child process. */
close(pipe_fd[0]);
sigreset();
clear_signals();
if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
_exit(1);
@@ -102,24 +111,38 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
close(null_fd);
execl(_PATH_BSHELL, "sh", "-c", data->arg, (char *) NULL);
command = status_replace(c, NULL, data->arg, time(NULL), 0);
execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
_exit(1);
default:
/* Parent process. */
close(pipe_fd[1]);
wp->pipe_fd = pipe_fd[0];
wp->pipe_buf = buffer_create(BUFSIZ);
wp->pipe_off = BUFFER_USED(wp->in);
wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
wp->pipe_event = bufferevent_new(wp->pipe_fd,
NULL, NULL, cmd_pipe_pane_error_callback, wp);
bufferevent_enable(wp->pipe_event, EV_WRITE);
if ((mode = fcntl(wp->pipe_fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(wp->pipe_fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(wp->pipe_fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
fatal("fcntl failed");
return (0);
}
return (0);
}
/* ARGSUSED */
void
cmd_pipe_pane_error_callback(
unused struct bufferevent *bufev, unused short what, void *data)
{
struct window_pane *wp = data;
bufferevent_free(wp->pipe_event);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-layout.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-previous-layout.c,v 1.6 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_previous_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_previous_layout_exec,
@@ -43,7 +43,7 @@ cmd_previous_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct winlink *wl;
u_int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-previous-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_previous_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev",
"[-a] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('a'),
0, "a",
cmd_previous_window_init,
cmd_target_parse,
cmd_previous_window_exec,
@@ -47,7 +47,7 @@ cmd_previous_window_init(struct cmd *self, int key)
data = self->data;
if (key == ('p' | KEYC_ESCAPE))
data->chflags |= CMD_CHFLAG('a');
cmd_set_flag(&data->chflags, 'a');
}
int
@@ -61,7 +61,7 @@ cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
activity = 0;
if (data->chflags & CMD_CHFLAG('a'))
if (cmd_check_flag(data->chflags, 'a'))
activity = 1;
if (session_previous(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-refresh-client.c,v 1.10 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-refresh-client.c,v 1.11 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh",
CMD_TARGET_CLIENT_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_refresh_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-session.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-rename-session.c,v 1.19 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_rename_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename",
CMD_TARGET_SESSION_USAGE " new-name",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_target_init,
cmd_target_parse,
cmd_rename_session_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.30 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-rename-window.c,v 1.31 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_rename_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew",
CMD_TARGET_WINDOW_USAGE " new-name",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_target_init,
cmd_target_parse,
cmd_rename_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-resize-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/* $Id: cmd-resize-pane.c,v 1.14 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,9 +31,8 @@ int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
"[-DU] " CMD_TARGET_PANE_USAGE " [adjustment]",
CMD_ARG01,
CMD_CHFLAG('D')|CMD_CHFLAG('L')|CMD_CHFLAG('R')|CMD_CHFLAG('U'),
"[-DLRU] " CMD_TARGET_PANE_USAGE " [adjustment]",
CMD_ARG01, "DLRU",
cmd_resize_pane_init,
cmd_target_parse,
cmd_resize_pane_exec,
@@ -50,28 +49,28 @@ cmd_resize_pane_init(struct cmd *self, int key)
data = self->data;
if (key == (KEYC_UP | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('U');
cmd_set_flag(&data->chflags, 'U');
if (key == (KEYC_DOWN | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('D');
cmd_set_flag(&data->chflags, 'D');
if (key == (KEYC_LEFT | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('L');
cmd_set_flag(&data->chflags, 'L');
if (key == (KEYC_RIGHT | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('R');
cmd_set_flag(&data->chflags, 'R');
if (key == (KEYC_UP | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('U');
cmd_set_flag(&data->chflags, 'U');
data->arg = xstrdup("5");
}
if (key == (KEYC_DOWN | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('D');
cmd_set_flag(&data->chflags, 'D');
data->arg = xstrdup("5");
}
if (key == (KEYC_LEFT | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('L');
cmd_set_flag(&data->chflags, 'L');
data->arg = xstrdup("5");
}
if (key == (KEYC_RIGHT | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('R');
cmd_set_flag(&data->chflags, 'R');
data->arg = xstrdup("5");
}
}
@@ -98,15 +97,14 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (data->chflags & (CMD_CHFLAG('L')|CMD_CHFLAG('R'))) {
if (data->chflags & CMD_CHFLAG('L'))
adjust = -adjust;
if (cmd_check_flag(data->chflags, 'L'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
else if (cmd_check_flag(data->chflags, 'R'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
} else {
if (data->chflags & CMD_CHFLAG('U'))
adjust = -adjust;
else if (cmd_check_flag(data->chflags, 'U'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust);
else if (cmd_check_flag(data->chflags, 'D'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
}
server_redraw_window(wl->window);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-respawn-window.c,v 1.22 2009-09-16 12:36:27 nicm Exp $ */
/* $Id: cmd-respawn-window.c,v 1.25 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_respawn_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw",
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
CMD_ARG01, CMD_CHFLAG('k'),
CMD_ARG01, "k",
cmd_target_init,
cmd_target_parse,
cmd_respawn_window_exec,
@@ -54,7 +54,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
w = wl->window;
if (!(data->chflags & CMD_CHFLAG('k'))) {
if (!cmd_check_flag(data->chflags, 'k')) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1)
continue;
@@ -72,7 +72,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry);
layout_free(w);
window_destroy_panes(w);
window_destroy_panes(w);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy);
if (window_pane_spawn(
@@ -80,6 +80,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "respawn window failed: %s", cause);
xfree(cause);
environ_free(&env);
server_destroy_pane(wp);
return (-1);
}
layout_init(w);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rotate-window.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-rotate-window.c,v 1.10 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew",
"[-DU] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('D')|CMD_CHFLAG('U'),
0, "DU",
cmd_rotate_window_init,
cmd_target_parse,
cmd_rotate_window_exec,
@@ -47,7 +47,7 @@ cmd_rotate_window_init(struct cmd *self, int key)
data = self->data;
if (key == ('o' | KEYC_ESCAPE))
data->chflags |= CMD_CHFLAG('D');
cmd_set_flag(&data->chflags, 'D');
}
int
@@ -64,7 +64,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
w = wl->window;
if (data->chflags & CMD_CHFLAG('D')) {
if (cmd_check_flag(data->chflags, 'D')) {
wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-run-shell.c,v 1.4 2009-11-02 21:38:26 tcunha Exp $ */
/* $Id: cmd-run-shell.c,v 1.8 2010-07-17 14:36:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -36,7 +36,7 @@ void cmd_run_shell_free(void *);
const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run",
"command",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_target_init,
cmd_target_parse,
cmd_run_shell_exec,
@@ -77,31 +77,38 @@ cmd_run_shell_callback(struct job *job)
{
struct cmd_run_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
char *cmd, *msg, *line, *buf;
size_t off, len, llen;
char *cmd, *msg, *line;
size_t size;
int retcode;
u_int lines;
buf = BUFFER_OUT(job->out);
len = BUFFER_USED(job->out);
if (ctx->cmdclient != NULL && ctx->cmdclient->flags & CLIENT_DEAD)
return;
if (ctx->curclient != NULL && ctx->curclient->flags & CLIENT_DEAD)
return;
lines = 0;
do {
if ((line = evbuffer_readline(job->event->input)) != NULL) {
ctx->print(ctx, "%s", line);
lines++;
}
} while (line != NULL);
size = EVBUFFER_LENGTH(job->event->input);
if (size != 0) {
line = xmalloc(size + 1);
memcpy(line, EVBUFFER_DATA(job->event->input), size);
line[size] = '\0';
ctx->print(ctx, "%s", line);
lines++;
xfree(line);
}
cmd = cdata->cmd;
if (len != 0) {
line = buf;
for (off = 0; off < len; off++) {
if (buf[off] == '\n') {
llen = buf + off - line;
if (llen > INT_MAX)
break;
ctx->print(ctx, "%.*s", (int) llen, line);
line = buf + off + 1;
}
}
llen = buf + len - line;
if (llen > 0 && llen < INT_MAX)
ctx->print(ctx, "%.*s", (int) llen, line);
}
msg = NULL;
if (WIFEXITED(job->status)) {
if ((retcode = WEXITSTATUS(job->status)) != 0)
@@ -111,7 +118,7 @@ cmd_run_shell_callback(struct job *job)
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL) {
if (len != 0)
if (lines != 0)
ctx->print(ctx, "%s", msg);
else
ctx->info(ctx, "%s", msg);
@@ -124,10 +131,13 @@ cmd_run_shell_free(void *data)
{
struct cmd_run_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
struct msg_exit_data exitdata;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
exitdata.retcode = ctx->cmdclient->retcode;
server_write_client(
ctx->cmdclient, MSG_EXIT, &exitdata, sizeof exitdata);
}
if (ctx->curclient != NULL)
ctx->curclient->references--;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-save-buffer.c,v 1.9 2009-10-28 23:08:52 tcunha Exp $ */
/* $Id: cmd-save-buffer.c,v 1.11 2010-07-02 02:52:13 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -33,7 +33,7 @@ int cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_save_buffer_entry = {
"save-buffer", "saveb",
"[-a] " CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, CMD_CHFLAG('a'),
CMD_ARG1, "a",
cmd_buffer_init,
cmd_buffer_parse,
cmd_save_buffer_exec,
@@ -48,7 +48,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct paste_buffer *pb;
mode_t mask;
FILE *f;
FILE *f, *close_f;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
@@ -65,15 +65,25 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
mask = umask(S_IRWXG | S_IRWXO);
if (data->chflags & CMD_CHFLAG('a'))
f = fopen(data->arg, "ab");
else
f = fopen(data->arg, "wb");
umask(mask);
if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
if (strcmp(data->arg, "-") == 0) {
if (ctx->cmdclient == NULL) {
ctx->error(ctx, "%s: can't write to stdout", data->arg);
return (-1);
}
f = ctx->cmdclient->stdout_file;
close_f = NULL;
} else {
mask = umask(S_IRWXG | S_IRWXO);
if (cmd_check_flag(data->chflags, 'a'))
f = fopen(data->arg, "ab");
else
f = fopen(data->arg, "wb");
umask(mask);
if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
close_f = f;
}
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
@@ -82,7 +92,8 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
fclose(f);
if (close_f != NULL)
fclose(close_f);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-layout.c,v 1.8 2009-07-28 23:04:29 tcunha Exp $ */
/* $Id: cmd-select-layout.c,v 1.12 2010-07-02 02:54:52 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
CMD_TARGET_WINDOW_USAGE " [layout-name]",
CMD_ARG01, 0,
CMD_ARG01, "",
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
@@ -52,13 +52,16 @@ cmd_select_layout_init(struct cmd *self, int key)
break;
case ('2' | KEYC_ESCAPE):
data->arg = xstrdup("even-vertical");
break;
break;
case ('3' | KEYC_ESCAPE):
data->arg = xstrdup("main-horizontal");
break;
case ('4' | KEYC_ESCAPE):
data->arg = xstrdup("main-vertical");
break;
case ('5' | KEYC_ESCAPE):
data->arg = xstrdup("tiled");
break;
}
}
@@ -76,13 +79,16 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
layout = wl->window->lastlayout;
if (layout == -1)
return (0);
} else if ((layout = layout_set_lookup(data->arg)) == -1) {
ctx->error(ctx, "unknown layout or ambiguous: %s", data->arg);
return (-1);
} else if ((layout = layout_set_lookup(data->arg)) != -1) {
layout = layout_set_select(wl->window, layout);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
} else {
if (layout_parse(wl->window, data->arg) == -1) {
ctx->error(ctx, "can't set layout: %s", data->arg);
return (-1);
}
ctx->info(ctx, "arranging in: %s", data->arg);
}
layout = layout_set_select(wl->window, layout);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-pane.c,v 1.10 2009-07-30 20:45:20 tcunha Exp $ */
/* $Id: cmd-select-pane.c,v 1.13 2010-03-15 22:03:38 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,19 +24,40 @@
* Select pane.
*/
void cmd_select_pane_init(struct cmd *, int);
int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
CMD_TARGET_PANE_USAGE,
0, 0,
cmd_target_init,
"[-DLRU] " CMD_TARGET_PANE_USAGE,
0, "DLRU",
cmd_select_pane_init,
cmd_target_parse,
cmd_select_pane_exec,
cmd_target_free,
cmd_target_print
};
void
cmd_select_pane_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
if (key == KEYC_UP)
cmd_set_flag(&data->chflags, 'U');
if (key == KEYC_DOWN)
cmd_set_flag(&data->chflags, 'D');
if (key == KEYC_LEFT)
cmd_set_flag(&data->chflags, 'L');
if (key == KEYC_RIGHT)
cmd_set_flag(&data->chflags, 'R');
if (key == 'o')
data->target = xstrdup(":.+");
}
int
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
@@ -51,8 +72,23 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "pane not visible: %s", data->target);
return (-1);
}
if (cmd_check_flag(data->chflags, 'L'))
wp = window_pane_find_left(wp);
else if (cmd_check_flag(data->chflags, 'R'))
wp = window_pane_find_right(wp);
else if (cmd_check_flag(data->chflags, 'U'))
wp = window_pane_find_up(wp);
else if (cmd_check_flag(data->chflags, 'D'))
wp = window_pane_find_down(wp);
if (wp == NULL) {
ctx->error(ctx, "pane not found");
return (-1);
}
window_set_active_pane(wl->window, wp);
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

View File

@@ -1,91 +0,0 @@
/* $Id: cmd-select-prompt.c,v 1.12 2009-08-16 19:29:24 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Prompt for window index and select it.
*/
int cmd_select_prompt_exec(struct cmd *, struct cmd_ctx *);
int cmd_select_prompt_callback(void *, const char *);
const struct cmd_entry cmd_select_prompt_entry = {
"select-prompt", NULL,
CMD_TARGET_CLIENT_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_select_prompt_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_select_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
if (c->prompt_string != NULL)
return (0);
status_prompt_set(c, "index ", cmd_select_prompt_callback, NULL, c, 0);
return (0);
}
int
cmd_select_prompt_callback(void *data, const char *s)
{
struct client *c = data;
const char *errstr;
char msg[128];
u_int idx;
if (s == NULL || *s == '\0')
return (0);
idx = strtonum(s, 0, UINT_MAX, &errstr);
if (errstr != NULL) {
xsnprintf(msg, sizeof msg, "Index %s: %s", errstr, s);
status_message_set(c, "%s", msg);
return (0);
}
if (winlink_find_by_index(&c->session->windows, idx) == NULL) {
xsnprintf(msg, sizeof msg,
"Window not found: %s:%d", c->session->name, idx);
status_message_set(c, "%s", msg);
return (0);
}
if (session_select(c->session, idx) == 0)
server_redraw_session(c->session);
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-window.c,v 1.23 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-select-window.c,v 1.24 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_select_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_select_window_init,
cmd_target_parse,
cmd_select_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-keys.c,v 1.22 2009-09-22 14:03:11 tcunha Exp $ */
/* $Id: cmd-send-keys.c,v 1.25 2010-05-22 21:56:04 micahcowan Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,14 +33,14 @@ size_t cmd_send_keys_print(struct cmd *, char *, size_t);
struct cmd_send_keys_data {
char *target;
u_int nkeys;
u_int nkeys;
int *keys;
};
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"[-t target-pane] key ...",
0, 0,
0, "",
NULL,
cmd_send_keys_parse,
cmd_send_keys_exec,
@@ -105,16 +105,17 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_send_keys_data *data = self->data;
struct window_pane *wp;
struct session *s;
u_int i;
if (data == NULL)
return (-1);
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
return (-1);
for (i = 0; i < data->nkeys; i++)
window_pane_key(wp, ctx->curclient, data->keys[i]);
window_pane_key(wp, s, data->keys[i]);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-prefix.c,v 1.27 2009-09-22 14:22:20 tcunha Exp $ */
/* $Id: cmd-send-prefix.c,v 1.29 2010-05-22 21:56:04 micahcowan Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
CMD_TARGET_PANE_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_send_prefix_exec,
@@ -49,7 +49,7 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
keylist = options_get_data(&s->options, "prefix");
window_pane_key(wp, ctx->curclient, ARRAY_FIRST(keylist));
window_pane_key(wp, s, ARRAY_FIRST(keylist));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.33 2009-11-04 22:42:31 tcunha Exp $ */
/* $Id: cmd-server-info.c,v 1.37 2009-12-10 16:59:02 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,7 +35,7 @@ int cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
"",
0, 0,
0, "",
NULL,
NULL,
cmd_server_info_exec,
@@ -43,6 +43,7 @@ const struct cmd_entry cmd_server_info_entry = {
NULL
};
/* ARGSUSED */
int
cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
@@ -69,8 +70,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
*strchr(tim, '\n') = '\0';
ctx->print(ctx,
"tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(ctx, "socket path %s, debug level %d%s",
socket_path, debug_level, be_quiet ? ", quiet" : "");
ctx->print(
ctx, "socket path %s, debug level %d", socket_path, debug_level);
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine);
@@ -93,12 +94,12 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x, references=%u]", i, c->tty.path,
c->ibuf.fd, c->tty.fd, c->session->name,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags,
c->tty.flags, c->references);
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Sessions: [%zu/%zu]",
ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8));
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
@@ -147,7 +148,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Terminals:");
ctx->print(ctx, "Terminals:");
SLIST_FOREACH(term, &tty_terms, entry) {
ctx->print(ctx, "%s [references=%u, flags=0x%x]:",
term->name, term->references, term->flags);
@@ -179,7 +180,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Jobs:");
ctx->print(ctx, "Jobs:");
SLIST_FOREACH(job, &all_jobs, lentry) {
ctx->print(ctx, "%s [fd=%d, pid=%d, status=%d, flags=0x%x]",
job->cmd, job->fd, job->pid, job->status, job->flags);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-set-buffer.c,v 1.12 2009-11-28 14:54:12 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_set_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb",
CMD_BUFFER_SESSION_USAGE " data",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_set_buffer_exec,
@@ -45,7 +45,7 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_buffer_data *data = self->data;
struct session *s;
u_int limit;
u_char *pdata;
char *pdata;
size_t psize;
if ((s = cmd_find_session(ctx, data->target)) == NULL)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-environment.c,v 1.2 2009-08-11 14:42:59 nicm Exp $ */
/* $Id: cmd-set-environment.c,v 1.3 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_set_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv",
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
CMD_ARG12, CMD_CHFLAG('g')|CMD_CHFLAG('r')|CMD_CHFLAG('u'),
CMD_ARG12, "gru",
NULL,
cmd_target_parse,
cmd_set_environment_exec,
@@ -56,7 +56,7 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
if (data->chflags & CMD_CHFLAG('g'))
if (cmd_check_flag(data->chflags, 'g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
@@ -64,13 +64,13 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
env = &s->environ;
}
if (data->chflags & CMD_CHFLAG('u')) {
if (cmd_check_flag(data->chflags, 'u')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -u");
return (-1);
}
environ_unset(env, data->arg);
} else if (data->chflags & CMD_CHFLAG('r')) {
} else if (cmd_check_flag(data->chflags, 'r')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -r");
return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.85 2009-11-02 21:38:26 tcunha Exp $ */
/* $Id: cmd-set-option.c,v 1.98 2010-07-02 02:45:52 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,27 @@
int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const char *cmd_set_option_print(
const struct set_option_entry *, struct options_entry *);
void cmd_set_option_string(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *, int);
void cmd_set_option_number(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_keys(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_colour(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_attributes(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_flag(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_choice(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
"[-agu] " CMD_TARGET_SESSION_USAGE " option [value]",
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'),
"[-agsuw] [-t target-session|target-window] option [value]",
CMD_ARG12, "agsuw",
NULL,
cmd_target_parse,
cmd_set_option_exec,
@@ -40,6 +57,12 @@ const struct cmd_entry cmd_set_option_entry = {
cmd_target_print
};
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL
};
@@ -49,7 +72,14 @@ const char *set_option_status_justify_list[] = {
const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL
};
const struct set_option_entry set_option_table[] = {
{ "escape-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "quiet", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_session_option_table[] = {
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
@@ -57,7 +87,9 @@ const struct set_option_entry set_option_table[] = {
{ "default-path", SET_OPTION_STRING, 0, 0, NULL },
{ "default-shell", SET_OPTION_STRING, 0, 0, NULL },
{ "default-terminal", SET_OPTION_STRING, 0, 0, NULL },
{ "detach-on-destroy", SET_OPTION_FLAG, 0, 0, NULL },
{ "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-active-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
@@ -67,7 +99,12 @@ const struct set_option_entry set_option_table[] = {
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "mouse-select-pane", SET_OPTION_FLAG, 0, 0, NULL },
{ "pane-active-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-active-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "prefix", SET_OPTION_KEYS, 0, 0, NULL },
{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
@@ -78,7 +115,7 @@ const struct set_option_entry set_option_table[] = {
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "status-justify",
{ "status-justify",
SET_OPTION_CHOICE, 0, 0, set_option_status_justify_list },
{ "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list },
{ "status-left", SET_OPTION_STRING, 0, 0, NULL },
@@ -91,20 +128,59 @@ const struct set_option_entry set_option_table[] = {
{ "status-right-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL },
{ "update-environment", SET_OPTION_STRING, 0, 0, NULL },
{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "alternate-screen", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-alert-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-alert-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-alert-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
{ "word-separators", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry, *opt;
@@ -113,12 +189,29 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
u_int i;
int try_again;
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_s_options;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
oo = &s->options;
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
table = set_option_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
}
if (*data->arg == '\0') {
@@ -127,7 +220,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
}
entry = NULL;
for (opt = set_option_table; opt->name != NULL; opt++) {
for (opt = table; opt->name != NULL; opt++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
continue;
if (entry != NULL) {
@@ -145,8 +238,8 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
if (data->chflags & CMD_CHFLAG('u')) {
if (data->chflags & CMD_CHFLAG('g')) {
if (cmd_check_flag(data->chflags, 'u')) {
if (cmd_check_flag(data->chflags, 'g')) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
return (-1);
@@ -162,40 +255,46 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else {
switch (entry->type) {
case SET_OPTION_STRING:
set_option_string(ctx, oo, entry,
data->arg2, data->chflags & CMD_CHFLAG('a'));
cmd_set_option_string(ctx, oo, entry,
data->arg2, cmd_check_flag(data->chflags, 'a'));
break;
case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2);
cmd_set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEYS:
set_option_keys(ctx, oo, entry, data->arg2);
cmd_set_option_keys(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2);
cmd_set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2);
cmd_set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2);
cmd_set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2);
cmd_set_option_choice(ctx, oo, entry, data->arg2);
break;
}
}
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
server_redraw_client(c);
}
/*
/*
* Special-case: kill all persistent jobs if status-left, status-right
* or set-titles-string have changed. Persistent jobs are only used by
* the status line at the moment so this works XXX.
*/
if (strcmp(entry->name, "status-left") == 0 ||
strcmp(entry->name, "status-right") == 0 ||
strcmp(entry->name, "set-titles-string") == 0) {
strcmp(entry->name, "set-titles-string") == 0 ||
strcmp(entry->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
@@ -203,7 +302,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
jobs = &c->status_jobs;
do {
try_again = 0;
try_again = 0;
job = RB_ROOT(jobs);
while (job != NULL) {
nextjob = RB_NEXT(jobs, jobs, job);
@@ -221,3 +320,243 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
const char *
cmd_set_option_print(
const struct set_option_entry *entry, struct options_entry *o)
{
static char out[BUFSIZ];
const char *s;
struct keylist *keylist;
u_int i;
*out = '\0';
switch (entry->type) {
case SET_OPTION_STRING:
xsnprintf(out, sizeof out, "\"%s\"", o->str);
break;
case SET_OPTION_NUMBER:
xsnprintf(out, sizeof out, "%lld", o->num);
break;
case SET_OPTION_KEYS:
keylist = o->data;
for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
strlcat(out, key_string_lookup_key(
ARRAY_ITEM(keylist, i)), sizeof out);
if (i != ARRAY_LENGTH(keylist) - 1)
strlcat(out, ",", sizeof out);
}
break;
case SET_OPTION_COLOUR:
s = colour_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_ATTRIBUTES:
s = attributes_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_FLAG:
if (o->num)
strlcpy(out, "on", sizeof out);
else
strlcpy(out, "off", sizeof out);
break;
case SET_OPTION_CHOICE:
s = entry->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
}
return (out);
}
void
cmd_set_option_string(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value, int append)
{
struct options_entry *o;
char *oldvalue, *newvalue;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if (append) {
oldvalue = options_get_string(oo, entry->name);
xasprintf(&newvalue, "%s%s", oldvalue, value);
} else
newvalue = value;
o = options_set_string(oo, entry->name, "%s", newvalue);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
if (newvalue != value)
xfree(newvalue);
}
void
cmd_set_option_number(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
long long number;
const char *errstr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
number = strtonum(value, entry->minimum, entry->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
return;
}
o = options_set_number(oo, entry->name, number);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
struct keylist *keylist;
char *copyvalue, *ptr, *str;
int key;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ptr = copyvalue = xstrdup(value);
while ((str = strsep(&ptr, ",")) != NULL) {
if ((key = key_string_lookup_string(str)) == KEYC_NONE) {
xfree(keylist);
ctx->error(ctx, "unknown key: %s", str);
xfree(copyvalue);
return;
}
ARRAY_ADD(keylist, key);
}
xfree(copyvalue);
o = options_set_data(oo, entry->name, keylist, xfree);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_colour(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int colour;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
return;
}
o = options_set_number(oo, entry->name, colour);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int attr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
return;
}
o = options_set_number(oo, entry->name, attr);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int flag;
if (value == NULL || *value == '\0')
flag = !options_get_number(oo, entry->name);
else {
if ((value[0] == '1' && value[1] == '\0') ||
strcasecmp(value, "on") == 0 ||
strcasecmp(value, "yes") == 0)
flag = 1;
else if ((value[0] == '0' && value[1] == '\0') ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
return;
}
}
o = options_set_number(oo, entry->name, flag);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_choice(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
const char **choicep;
int n, choice = -1;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
n = 0;
for (choicep = entry->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (choice != -1) {
ctx->error(ctx, "ambiguous option value: %s", value);
return;
}
choice = n - 1;
}
if (choice == -1) {
ctx->error(ctx, "unknown option value: %s", value);
return;
}
o = options_set_number(oo, entry->name, choice);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.40 2009-10-09 13:07:04 tcunha Exp $ */
/* $Id: cmd-set-window-option.c,v 1.43 2009-12-04 22:11:23 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,13 +18,10 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Set a window option.
* Set a window option. This is just an alias for set-option -w.
*/
int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
@@ -32,7 +29,7 @@ int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw",
"[-agu] " CMD_TARGET_WINDOW_USAGE " option [value]",
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'),
CMD_ARG12, "agu",
NULL,
cmd_target_parse,
cmd_set_window_option_exec,
@@ -40,131 +37,11 @@ const struct cmd_entry cmd_set_window_option_entry = {
cmd_target_print
};
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry, *opt;
u_int i;
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_w_options;
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
if (*data->arg == '\0') {
ctx->error(ctx, "invalid option");
return (-1);
}
entry = NULL;
for (opt = set_window_option_table; opt->name != NULL; opt++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
continue;
if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg);
return (-1);
}
entry = opt;
/* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0)
break;
}
if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg);
return (-1);
}
if (data->chflags & CMD_CHFLAG('u')) {
if (data->chflags & CMD_CHFLAG('g')) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
return (-1);
}
if (data->arg2 != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
}
options_remove(oo, entry->name);
ctx->info(ctx, "unset option: %s", entry->name);
} else {
switch (entry->type) {
case SET_OPTION_STRING:
set_option_string(ctx, oo, entry,
data->arg2, data->chflags & CMD_CHFLAG('a'));
break;
case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEYS:
set_option_keys(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2);
break;
}
}
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
server_redraw_client(c);
}
return (0);
cmd_set_flag(&data->chflags, 'w');
return (cmd_set_option_entry.exec(self, ctx));
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-show-buffer.c,v 1.12 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_show_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_buffer_entry = {
"show-buffer", "showb",
CMD_BUFFER_SESSION_USAGE,
0, 0,
0, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_show_buffer_exec,
@@ -71,24 +71,24 @@ cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
width = s->sx;
if (ctx->cmdclient != NULL)
width = ctx->cmdclient->tty.sx;
buf = xmalloc(width + 1);
len = 0;
ptr = in;
do {
buf[len++] = *ptr++;
if (len == width || buf[len - 1] == '\n') {
if (buf[len - 1] == '\n')
len--;
buf[len] = '\0';
ctx->print(ctx, "%s", buf);
ctx->print(ctx, "%s", buf);
len = 0;
}
} while (*ptr != '\0');
if (len != 0) {
buf[len] = '\0';
ctx->print(ctx, "%s", buf);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-environment.c,v 1.1 2009-08-09 17:48:55 tcunha Exp $ */
/* $Id: cmd-show-environment.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_show_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv",
"[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'),
0, "g",
cmd_target_init,
cmd_target_parse,
cmd_show_environment_exec,
@@ -48,7 +48,7 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
struct environ *env;
struct environ_entry *envent;
if (data->chflags & CMD_CHFLAG('g'))
if (cmd_check_flag(data->chflags, 'g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-up-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-show-messages.c,v 1.2 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,42 +18,48 @@
#include <sys/types.h>
#include <string.h>
#include <time.h>
#include "tmux.h"
/*
* Move up a pane.
* Show client message log.
*/
int cmd_up_pane_exec(struct cmd *, struct cmd_ctx *);
int cmd_show_messages_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_up_pane_entry = {
"up-pane", "upp",
CMD_TARGET_WINDOW_USAGE,
0, 0,
const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
CMD_TARGET_CLIENT_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_up_pane_exec,
cmd_show_messages_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_show_messages_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window *w;
struct cmd_target_data *data = self->data;
struct client *c;
struct message_entry *msg;
char *tim;
u_int i;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
w = wl->window;
do {
w->active = TAILQ_PREV(w->active, window_panes, entry);
if (w->active == NULL)
w->active = TAILQ_LAST(&w->panes, window_panes);
} while (!window_pane_visible(w->active));
server_status_window(wl->window);
for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
msg = &ARRAY_ITEM(&c->message_log, i);
tim = ctime(&msg->msg_time);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%s %s", tim, msg->msg);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.17 2009-09-22 13:56:02 tcunha Exp $ */
/* $Id: cmd-show-options.c,v 1.21 2009-12-10 16:59:02 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,8 +31,8 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_options_entry = {
"show-options", "show",
"[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'),
"[-gsw] [-t target-session|target-window]",
0, "gsw",
cmd_target_init,
cmd_target_parse,
cmd_show_options_exec,
@@ -44,24 +44,43 @@ int
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
const char *optval;
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_s_options;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
oo = &s->options;
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
table = set_option_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
}
for (entry = set_option_table; entry->name != NULL; entry++) {
for (entry = table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
continue;
optval = set_option_print(entry, o);
optval = cmd_set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-window-options.c,v 1.13 2009-09-22 13:56:02 tcunha Exp $ */
/* $Id: cmd-show-window-options.c,v 1.15 2009-12-04 22:11:23 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,7 +24,7 @@
#include "tmux.h"
/*
* Show window options.
* Show window options. This is an alias for show-options -w.
*/
int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
@@ -32,7 +32,7 @@ int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw",
"[-g] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('g'),
0, "g",
cmd_target_init,
cmd_target_parse,
cmd_show_window_options_exec,
@@ -44,26 +44,7 @@ int
cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
const char *optval;
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_w_options;
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
for (entry = set_window_option_table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
continue;
optval = set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
}
return (0);
cmd_set_flag(&data->chflags, 'w');
return (cmd_show_options_entry.exec(self, ctx));
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-source-file.c,v 1.9 2009-09-22 14:06:40 tcunha Exp $ */
/* $Id: cmd-source-file.c,v 1.13 2010-02-08 18:29:32 tcunha Exp $ */
/*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -37,7 +37,7 @@ struct cmd_source_file_data {
const struct cmd_entry cmd_source_file_entry = {
"source-file", "source",
"path",
0, 0,
0, "",
cmd_source_file_init,
cmd_source_file_parse,
cmd_source_file_exec,
@@ -45,6 +45,7 @@ const struct cmd_entry cmd_source_file_entry = {
cmd_source_file_print
};
/* ARGSUSED */
void
cmd_source_file_init(struct cmd *self, unused int arg)
{
@@ -88,12 +89,18 @@ int
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_source_file_data *data = self->data;
struct causelist causes;
char *cause;
u_int i;
if (load_cfg(data->path, ctx, &cause) != 0) {
ctx->error(ctx, "%s", cause);
xfree(cause);
return (-1);
ARRAY_INIT(&causes);
if (load_cfg(data->path, ctx, &causes) != 0) {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
xfree(cause);
}
ARRAY_FREE(&causes);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-split-window.c,v 1.28 2009-09-22 14:06:40 tcunha Exp $ */
/* $Id: cmd-split-window.c,v 1.35 2010-07-02 02:49:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,8 +44,8 @@ struct cmd_split_window_data {
const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"[-dhv] [-p percentage|-l size] [-t target-window] [command]",
0, 0,
"[-dhv] [-p percentage|-l size] [-t target-pane] [command]",
0, "",
cmd_split_window_init,
cmd_split_window_parse,
cmd_split_window_exec,
@@ -69,7 +69,7 @@ cmd_split_window_init(struct cmd *self, int key)
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
break;
case '"':
data->flag_horizontal = 0;
break;
@@ -148,15 +148,16 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct window_pane *wp, *new_wp = NULL;
struct environ env;
char *cmd, *cwd, *cause;
const char *shell;
u_int hlimit;
int size;
enum layout_type type;
struct layout_cell *lc;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
return (-1);
w = wl->window;
@@ -168,38 +169,47 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd = data->cmd;
if (cmd == NULL)
cmd = options_get_string(&s->options, "default-command");
if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
cwd = options_get_string(&s->options, "default-path");
else
cwd = ctx->cmdclient->cwd;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1)
size = (w->active->sy * data->percentage) / 100;
hlimit = options_get_number(&s->options, "history-limit");
cwd = options_get_string(&s->options, "default-path");
if (*cwd == '\0') {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
cwd = ctx->cmdclient->cwd;
else
cwd = s->cwd;
}
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1) {
if (type == LAYOUT_TOPBOTTOM)
size = (wp->sy * data->percentage) / 100;
else
size = (wp->sx * data->percentage) / 100;
}
hlimit = options_get_number(&s->options, "history-limit");
shell = options_get_string(&s->options, "default-shell");
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
wp = window_add_pane(w, hlimit);
if (window_pane_spawn(wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
if (layout_split_pane(w->active, type, size, wp) != 0) {
if ((lc = layout_split_pane(wp, type, size)) == 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);
server_redraw_window(w);
if (!data->flag_detached) {
window_set_active_pane(w, wp);
window_set_active_pane(w, new_wp);
session_select(s, wl->idx);
server_redraw_session(s);
} else
@@ -210,8 +220,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
error:
environ_free(&env);
if (wp != NULL)
window_remove_pane(w, wp);
if (new_wp != NULL)
window_remove_pane(w, new_wp);
ctx->error(ctx, "create pane failed: %s", cause);
xfree(cause);
return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-start-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-start-server.c,v 1.10 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_start_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_start_server_entry = {
"start-server", "start",
"",
CMD_STARTSERVER, 0,
CMD_STARTSERVER, "",
NULL,
NULL,
cmd_start_server_exec,
@@ -37,6 +37,7 @@ const struct cmd_entry cmd_start_server_entry = {
NULL
};
/* ARGSUSED */
int
cmd_start_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.24 2009-10-28 23:12:38 tcunha Exp $ */
/* $Id: cmd-string.c,v 1.31 2010-02-26 13:27:38 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@
*/
int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(const char *, size_t *);
void cmd_string_ungetc(size_t *);
char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *);
char *cmd_string_expand_tilde(const char *, size_t *);
@@ -40,13 +40,15 @@ char *cmd_string_expand_tilde(const char *, size_t *);
int
cmd_string_getc(const char *s, size_t *p)
{
if (s[*p] == '\0')
const u_char *ucs = s;
if (ucs[*p] == '\0')
return (EOF);
return (s[(*p)++]);
return (ucs[(*p)++]);
}
void
cmd_string_ungetc(unused const char *s, size_t *p)
cmd_string_ungetc(size_t *p)
{
(*p)--;
}
@@ -59,7 +61,7 @@ int
cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
{
size_t p;
int ch, i, argc, rval, have_arg;
int ch, i, argc, rval;
char **argv, *buf, *t;
const char *whitespace, *equals;
size_t len;
@@ -70,8 +72,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = NULL;
len = 0;
have_arg = 0;
*cause = NULL;
*cmdlist = NULL;
@@ -88,8 +88,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '"':
if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
@@ -98,8 +96,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '$':
if ((t = cmd_string_variable(s, &p)) == NULL)
@@ -108,8 +104,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '#':
/* Comment: discard rest of line. */
@@ -119,7 +113,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
case EOF:
case ' ':
case '\t':
if (have_arg) {
if (buf != NULL) {
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
@@ -128,23 +122,19 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = NULL;
len = 0;
have_arg = 0;
}
if (ch != EOF)
break;
if (argc == 0)
goto out;
for (i = 0; i < argc; i++) {
equals = strchr(argv[i], '=');
whitespace = argv[i] + strcspn(argv[i], " \t");
while (argc != 0) {
equals = strchr(argv[0], '=');
whitespace = argv[0] + strcspn(argv[0], " \t");
if (equals == NULL || equals > whitespace)
break;
environ_put(&global_environ, argv[i]);
memmove(&argv[i], &argv[i + 1], argc - i - 1);
environ_put(&global_environ, argv[0]);
argc--;
memmove(argv, argv + 1, argc * (sizeof *argv));
}
if (argc == 0)
goto out;
@@ -153,14 +143,10 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
if (*cmdlist == NULL)
goto out;
do
xfree(argv[argc - 1]);
while (--argc > 0);
rval = 0;
goto out;
case '~':
if (have_arg == 0) {
if (buf == NULL) {
if ((t = cmd_string_expand_tilde(s, &p)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
@@ -176,8 +162,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch;
have_arg = 1;
break;
}
}
@@ -189,10 +173,11 @@ out:
if (buf != NULL)
xfree(buf);
while (--argc >= 0)
xfree(argv[argc]);
if (argv != NULL)
if (argv != NULL) {
for (i = 0; i < argc; i++)
xfree(argv[i]);
xfree(argv);
}
return (rval);
}
@@ -311,7 +296,7 @@ cmd_string_variable(const char *s, size_t *p)
if (fch == '{' && ch != '}')
goto error;
if (ch != EOF && fch != '{')
cmd_string_ungetc(s, p); /* ch */
cmd_string_ungetc(p); /* ch */
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
@@ -337,18 +322,17 @@ cmd_string_expand_tilde(const char *s, size_t *p)
home = NULL;
if (cmd_string_getc(s, p) == '/') {
if ((home = getenv("HOME")) == NULL) {
if ((home = getenv("HOME")) == NULL || *home == '\0') {
if ((pw = getpwuid(getuid())) != NULL)
home = pw->pw_dir;
}
} else {
cmd_string_ungetc(s, p);
cmd_string_ungetc(p);
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
return (NULL);
if ((pw = getpwnam(username)) != NULL)
home = pw->pw_dir;
if (username != NULL)
xfree(username);
xfree(username);
}
if (home == NULL)
return (NULL);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-suspend-client.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-suspend-client.c,v 1.5 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -37,7 +37,7 @@ struct cmd_suspend_client_data {
const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
"[-c target-client]",
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_suspend_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-pane.c,v 1.13 2009-07-30 21:04:40 tcunha Exp $ */
/* $Id: cmd-swap-pane.c,v 1.15 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp",
"[-dDU] " CMD_SRCDST_PANE_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('D')|CMD_CHFLAG('U'),
0, "dDU",
cmd_swap_pane_init,
cmd_srcdst_parse,
cmd_swap_pane_exec,
@@ -49,11 +49,12 @@ cmd_swap_pane_init(struct cmd *self, int key)
data = self->data;
if (key == '{')
data->chflags |= CMD_CHFLAG('U');
cmd_set_flag(&data->chflags, 'U');
else if (key == '}')
data->chflags |= CMD_CHFLAG('D');
cmd_set_flag(&data->chflags, 'D');
}
int
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
@@ -73,11 +74,11 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (data->src == NULL) {
src_w = dst_w;
if (data->chflags & CMD_CHFLAG('D')) {
if (cmd_check_flag(data->chflags, 'D')) {
src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes);
} else if (data->chflags & CMD_CHFLAG('U')) {
} else if (cmd_check_flag(data->chflags, 'U')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
@@ -109,7 +110,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
dst_wp->layout_cell = src_lc;
dst_lc->wp = src_wp;
src_wp->layout_cell = dst_lc;
src_wp->window = dst_w;
dst_wp->window = src_w;
@@ -120,7 +121,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
dst_wp->xoff = xoff; dst_wp->yoff = yoff;
window_pane_resize(dst_wp, sx, sy);
if (!(data->chflags & CMD_CHFLAG('d'))) {
if (!cmd_check_flag(data->chflags, 'd')) {
if (src_w != dst_w) {
window_set_active_pane(src_w, dst_wp);
window_set_active_pane(dst_w, src_wp);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-window.c,v 1.18 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-swap-window.c,v 1.19 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw",
"[-d] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d'),
0, "d",
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_swap_window_exec,
@@ -68,7 +68,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl_dst->window = wl_src->window;
wl_src->window = w;
if (!(data->chflags & CMD_CHFLAG('d'))) {
if (!cmd_check_flag(data->chflags, 'd')) {
session_select(dst, wl_dst->idx);
if (src != dst)
session_select(src, wl_src->idx);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-switch-client.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-switch-client.c,v 1.19 2010-01-25 17:12:44 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -40,7 +40,7 @@ struct cmd_switch_client_data {
const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc",
"[-c target-client] [-t target-session]",
0, 0,
0, "",
NULL,
cmd_switch_client_parse,
cmd_switch_client_exec,
@@ -61,10 +61,12 @@ cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause)
while ((opt = getopt(argc, argv, "c:t:")) != -1) {
switch (opt) {
case 'c':
data->name = xstrdup(optarg);
if (data->name == NULL)
data->name = xstrdup(optarg);
break;
case 't':
data->target = xstrdup(optarg);
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
default:
goto usage;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unbind-key.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/* $Id: cmd-unbind-key.c,v 1.22 2010-01-25 17:12:44 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -40,7 +40,7 @@ struct cmd_unbind_key_data {
const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind",
"[-cn] [-t key-table] key",
0, 0,
0, "",
NULL,
cmd_unbind_key_parse,
cmd_unbind_key_exec,
@@ -67,7 +67,8 @@ cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
no_prefix = 1;
break;
case 't':
data->tablename = xstrdup(optarg);
if (data->tablename == NULL)
data->tablename = xstrdup(optarg);
break;
default:
goto usage;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unlink-window.c,v 1.19 2009-10-11 23:38:16 tcunha Exp $ */
/* $Id: cmd-unlink-window.c,v 1.21 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
"[-k] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('k'),
0, "k",
cmd_target_init,
cmd_target_parse,
cmd_unlink_window_exec,
@@ -59,11 +59,11 @@ cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
} else
references = 1;
if (!(data->chflags & CMD_CHFLAG('k')) && w->references == references) {
if (!cmd_check_flag(data->chflags, 'k') && w->references == references) {
ctx->error(ctx, "window is only linked to one session");
return (-1);
}
server_unlink_window(s, wl);
recalculate_sizes();

241
cmd.c
View File

@@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.130 2009-11-04 22:46:25 tcunha Exp $ */
/* $Id: cmd.c,v 1.142 2010-07-17 14:38:13 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,6 +30,8 @@ const struct cmd_entry *cmd_table[] = {
&cmd_attach_session_entry,
&cmd_bind_key_entry,
&cmd_break_pane_entry,
&cmd_capture_pane_entry,
&cmd_choose_buffer_entry,
&cmd_choose_client_entry,
&cmd_choose_session_entry,
&cmd_choose_window_entry,
@@ -43,10 +45,10 @@ const struct cmd_entry *cmd_table[] = {
&cmd_detach_client_entry,
&cmd_display_message_entry,
&cmd_display_panes_entry,
&cmd_down_pane_entry,
&cmd_find_window_entry,
&cmd_has_session_entry,
&cmd_if_shell_entry,
&cmd_join_pane_entry,
&cmd_kill_pane_entry,
&cmd_kill_server_entry,
&cmd_kill_session_entry,
@@ -83,7 +85,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_save_buffer_entry,
&cmd_select_layout_entry,
&cmd_select_pane_entry,
&cmd_select_prompt_entry,
&cmd_select_window_entry,
&cmd_send_keys_entry,
&cmd_send_prefix_entry,
@@ -94,6 +95,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_set_window_option_entry,
&cmd_show_buffer_entry,
&cmd_show_environment_entry,
&cmd_show_messages_entry,
&cmd_show_options_entry,
&cmd_show_window_options_entry,
&cmd_source_file_entry,
@@ -105,7 +107,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_switch_client_entry,
&cmd_unbind_key_entry,
&cmd_unlink_window_entry,
&cmd_up_pane_entry,
NULL
};
@@ -115,6 +116,9 @@ struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(const char *, int *);
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
int cmd_lookup_index(struct session *, const char *, int *);
struct winlink *cmd_find_window_offset(const char *, struct session *, int *);
int cmd_find_index_offset(const char *, struct session *, int *);
struct window_pane *cmd_find_pane_offset(const char *, struct winlink *);
int
cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
@@ -166,7 +170,7 @@ cmd_free_argv(int argc, char **argv)
int i;
if (argc == 0)
return;
return;
for (i = 0; i < argc; i++) {
if (argv[i] != NULL)
xfree(argv[i]);
@@ -276,9 +280,8 @@ cmd_free(struct cmd *cmd)
size_t
cmd_print(struct cmd *cmd, char *buf, size_t len)
{
if (cmd->entry->print == NULL) {
if (cmd->entry->print == NULL)
return (xsnprintf(buf, len, "%s", cmd->entry->name));
}
return (cmd->entry->print(cmd, buf, len));
}
@@ -508,7 +511,7 @@ cmd_lookup_session(const char *name, int *ambiguous)
* be unique so an exact match can't be ambigious and can just be
* returned.
*/
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
if (strcmp(name, s->name) == 0)
@@ -520,7 +523,7 @@ cmd_lookup_session(const char *name, int *ambiguous)
* be ambiguous.
*/
sfound = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
if (strncmp(name, s->name, strlen(name)) == 0 ||
@@ -532,13 +535,13 @@ cmd_lookup_session(const char *name, int *ambiguous)
sfound = s;
}
}
return (sfound);
return (sfound);
}
/*
* Lookup a window or return -1 if not found or ambigious. First try as an
* index and if invalid, use fnmatch or leading prefix. Return NULL but fill in
* idx if the window index is a valid number but there is now window with that
* idx if the window index is a valid number but there is no window with that
* index.
*/
struct winlink *
@@ -556,7 +559,7 @@ cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
if ((wl = winlink_find_by_index(&s->windows, idx)) != NULL)
return (wl);
}
/* Look for exact matches, error if more than one. */
wlfound = NULL;
RB_FOREACH(wl, winlinks, &s->windows) {
@@ -582,7 +585,7 @@ cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
}
wlfound = wl;
}
}
}
if (wlfound != NULL)
return (wlfound);
@@ -699,32 +702,53 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
/*
* Then work out the window. An empty string is the current window,
* otherwise try to look it up in the session.
* otherwise try special cases then to look it up in the session.
*/
if (*winptr == '\0')
wl = s->curw;
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL)
else if (winptr[0] == '!' && winptr[1] == '\0')
wl = TAILQ_FIRST(&s->lastw);
else if (winptr[0] == '+' || winptr[0] == '-')
wl = cmd_find_window_offset(winptr, s, &ambiguous);
else
wl = cmd_lookup_window(s, winptr, &ambiguous);
if (wl == NULL)
goto not_found;
if (sessptr != NULL)
xfree(sessptr);
return (wl);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) {
if (ambiguous)
/*
* No colon in the string, first try special cases, then as a window
* and lastly as a session.
*/
if (arg[0] == '!' && arg[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
wl = s->curw;
}
} else if (arg[0] == '+' || arg[0] == '-') {
if ((wl = cmd_find_window_offset(arg, s, &ambiguous)) == NULL)
goto lookup_session;
} else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL)
goto lookup_session;
if (sp != NULL)
*sp = s;
return (wl);
lookup_session:
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
if (sp != NULL)
*sp = s;
return (s->curw);
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
@@ -744,6 +768,26 @@ not_found:
return (NULL);
}
struct winlink *
cmd_find_window_offset(const char *winptr, struct session *s, int *ambiguous)
{
struct winlink *wl;
int offset = 1;
if (winptr[1] != '\0')
offset = strtonum(winptr + 1, 1, INT_MAX, NULL);
if (offset == 0)
wl = cmd_lookup_window(s, winptr, ambiguous);
else {
if (winptr[0] == '+')
wl = winlink_next_by_number(s->curw, s, offset);
else
wl = winlink_previous_by_number(s->curw, s, offset);
}
return (wl);
}
/*
* Find the target session and window index, whether or not it exists in the
* session. Return -2 on error or -1 if no window index is specified. This is
@@ -754,6 +798,7 @@ int
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
{
struct session *s;
struct winlink *wl;
const char *winptr;
char *sessptr = NULL;
int idx, ambiguous = 0;
@@ -799,42 +844,70 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
* try to look it up in the session.
*/
if (*winptr == '\0')
idx = -1;
else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) {
if (ambiguous)
idx = -1;
else if (winptr[0] == '!' && winptr[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
ctx->error(ctx, "invalid index: %s", arg);
idx = -2;
}
idx = wl->idx;
} else if (winptr[0] == '+' || winptr[0] == '-') {
if ((idx = cmd_find_index_offset(winptr, s, &ambiguous)) < 0)
goto invalid_index;
} else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1)
goto invalid_index;
if (sessptr != NULL)
xfree(sessptr);
return (idx);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) {
if (ambiguous)
/*
* No colon in the string, first try special cases, then as a window
* and lastly as a session.
*/
if (arg[0] == '!' && arg[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
idx = -1;
}
idx = wl->idx;
} else if (arg[0] == '+' || arg[0] == '-') {
if ((idx = cmd_find_index_offset(arg, s, &ambiguous)) < 0)
goto lookup_session;
} else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1)
goto lookup_session;
if (sp != NULL)
*sp = s;
return (idx);
lookup_session:
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
if (sp != NULL)
*sp = s;
return (-1);
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
ctx->error(ctx, "multiple sessions: %s", arg);
else
ctx->error(ctx, "session not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (-2);
invalid_index:
if (ambiguous)
goto not_found;
ctx->error(ctx, "invalid index: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (-2);
not_found:
if (ambiguous)
ctx->error(ctx, "multiple windows: %s", arg);
@@ -845,6 +918,32 @@ not_found:
return (-2);
}
int
cmd_find_index_offset(const char *winptr, struct session *s, int *ambiguous)
{
int idx, offset = 1;
if (winptr[1] != '\0')
offset = strtonum(winptr + 1, 1, INT_MAX, NULL);
if (offset == 0)
idx = cmd_lookup_index(s, winptr, ambiguous);
else {
if (winptr[0] == '+') {
if (s->curw->idx == INT_MAX)
idx = cmd_lookup_index(s, winptr, ambiguous);
else
idx = s->curw->idx + offset;
} else {
if (s->curw->idx == 0)
idx = cmd_lookup_index(s, winptr, ambiguous);
else
idx = s->curw->idx - offset;
}
}
return (idx);
}
/*
* Find the target session, window and pane number or report an error and
* return NULL. The pane number is separated from the session:window by a .,
@@ -854,12 +953,12 @@ struct winlink *
cmd_find_pane(struct cmd_ctx *ctx,
const char *arg, struct session **sp, struct window_pane **wpp)
{
struct session *s;
struct winlink *wl;
const char *period;
char *winptr, *paneptr;
const char *errstr;
u_int idx;
struct session *s;
struct winlink *wl;
struct layout_cell *lc;
const char *period, *errstr;
char *winptr, *paneptr;
u_int idx;
/* Get the current session. */
if ((s = cmd_current_session(ctx)) == NULL) {
@@ -891,22 +990,31 @@ cmd_find_pane(struct cmd_ctx *ctx,
paneptr = winptr + (period - arg) + 1;
if (*paneptr == '\0')
*wpp = wl->window->active;
else if (paneptr[0] == '+' || paneptr[0] == '-')
*wpp = cmd_find_pane_offset(paneptr, wl);
else {
idx = strtonum(paneptr, 0, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "pane %s: %s", errstr, paneptr);
goto error;
}
if (errstr != NULL)
goto lookup_string;
*wpp = window_pane_at_index(wl->window, idx);
if (*wpp == NULL) {
ctx->error(ctx, "no such pane: %u", idx);
goto error;
}
if (*wpp == NULL)
goto lookup_string;
}
xfree(winptr);
return (wl);
lookup_string:
/* Try pane string description. */
if ((lc = layout_find_string(wl->window, paneptr)) == NULL) {
ctx->error(ctx, "can't find pane: %s", paneptr);
goto error;
}
*wpp = lc->wp;
xfree(winptr);
return (wl);
no_period:
/* Try as a pane number alone. */
idx = strtonum(arg, 0, INT_MAX, &errstr);
@@ -916,20 +1024,45 @@ no_period:
/* Try index in the current session and window. */
if ((*wpp = window_pane_at_index(s->curw->window, idx)) == NULL)
goto lookup_window;
return (s->curw);
lookup_window:
/* Try pane string description. */
if ((lc = layout_find_string(s->curw->window, arg)) != NULL) {
*wpp = lc->wp;
return (s->curw);
}
/* Try as a window and use the active pane. */
if ((wl = cmd_find_window(ctx, arg, sp)) != NULL)
*wpp = wl->window->active;
return (wl);
error:
xfree(winptr);
return (NULL);
}
struct window_pane *
cmd_find_pane_offset(const char *paneptr, struct winlink *wl)
{
struct window *w = wl->window;
struct window_pane *wp = w->active;
u_int offset = 1;
if (paneptr[1] != '\0')
offset = strtonum(paneptr + 1, 1, INT_MAX, NULL);
if (offset > 0) {
if (paneptr[0] == '+')
wp = window_pane_next_by_number(w, wp, offset);
else
wp = window_pane_previous_by_number(w, wp, offset);
}
return (wp);
}
/* Replace the first %% or %idx in template by s. */
char *
cmd_template_replace(char *template, const char *s, int idx)

View File

@@ -1,4 +1,4 @@
/* $Id: compat.h,v 1.19 2009-10-06 15:32:21 tcunha Exp $ */
/* $Id: compat.h,v 1.25 2010-06-06 13:00:46 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -42,21 +42,13 @@ typedef uint64_t u_int64_t;
#else
#include "compat/tree.h"
#endif
#ifdef HAVE_BITSTRING_H
#include <bitstring.h>
#else
#include "compat/bitstring.h"
#endif
#ifdef HAVE_POLL
#include <poll.h>
#else
#define POLLNVAL 0
#define POLLHUP 0
#include "compat/bsd-poll.h"
#endif
#ifdef HAVE_GETOPT
#include <getopt.h>
#endif
@@ -89,17 +81,36 @@ typedef uint64_t u_int64_t;
#ifndef HAVE_IMSG
#include "compat/imsg.h"
#else
#include <imsg.h>
#endif
#ifdef HAVE_BROKEN_CMSG_FIRSTHDR
/* Broken on OS X. */
/* CMSG_FIRSTHDR broken on OS X. */
#undef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(mhdr) \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(mhdr)->msg_control : \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(mhdr)->msg_control : \
(struct cmsghdr *)NULL)
#endif
/* CMSG_ALIGN, CMSG_SPACE, CMSG_LEN missing from Solaris 9. */
#ifndef CMSG_ALIGN
#ifdef __sun
#define CMSG_ALIGN _CMSG_DATA_ALIGN
#else
#define CMSG_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1))
#endif
#endif
#ifndef CMSG_SPACE
#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
#endif
#ifndef CMSG_LEN
#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
#endif
#ifndef INFTIM
#define INFTIM -1
#endif
@@ -143,7 +154,7 @@ typedef uint64_t u_int64_t;
#endif
#ifndef HAVE_BZERO
#define bzero(buf, len) memset((buf), 0, (len));
#define bzero(buf, len) memset(buf, 0, len);
#endif
#ifndef HAVE_STRCASESTR
@@ -183,13 +194,19 @@ pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#ifndef HAVE_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_SETENV
/* setenv.c */
int setenv(const char *, const char *, int);
int unsetenv(const char *);
#endif
#ifndef HAVE_GETOPT

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