591 Commits
0.9 ... 1.1

Author SHA1 Message Date
no_author
09c558685a This commit was manufactured by cvs2svn to create tag 'TMUX_1_1'. 2009-11-05 12:35:48 +00:00
Tiago Cunha
e4b743cced Update CHANGES, and NOTES for the 1.1 release. 2009-11-05 12:35:47 +00:00
Tiago Cunha
9128b7df7f Bump VERSION. 2009-11-05 12:32:46 +00:00
Tiago Cunha
90d4cbe67e Prepare the tree for the 1.1 release. 2009-11-05 12:30:55 +00:00
Tiago Cunha
625348122c Sync OpenBSD patchset 490:
Unused (but assigned to) variable, found by lint.
2009-11-04 23:12:32 +00:00
Tiago Cunha
27c2b98f5f Sync OpenBSD patchset 489:
Ignore the colour on space, /not/ the attributes.
2009-11-04 23:10:43 +00:00
Tiago Cunha
344a241c28 Sync OpenBSD patchset 488:
Fix the reverse emulation when a terminal doesn't have setab to use the correct
fg/bg (adjusted if spaces) and happen before attribute setting.
2009-11-04 23:09:48 +00:00
Tiago Cunha
fdda6ef8bd Adjust OpenBSD patchset 487 to the portable version, and while there drop
malloc_options on DragonFlyBSD, and FreeBSD.
2009-11-04 23:09:09 +00:00
Tiago Cunha
c78426f033 Sync OpenBSD patchset 487:
Change declaration and use of malloc_options to be more standard, from Tim van
der Molen.
2009-11-04 22:49:27 +00:00
Tiago Cunha
9e208584ed Sync OpenBSD patchset 486:
Don't backoff based on suspended or deda clients as they are always likely to
have data backed up.
2009-11-04 22:47:29 +00:00
Tiago Cunha
5be38f2b3a Sync OpenBSD patchset 485:
Add an activity time for clients, like for sessions, and change session and
client lookup to pick the most recently used rather than the most recently
created - this is much more useful when used interactively and (because the
activity time is set at creation) should have no effect on source-file.

Based on a problem reported by Jan Johansson.
2009-11-04 22:46:25 +00:00
Tiago Cunha
b7fc4f3760 Sync OpenBSD patchset 484:
If it isn't available explicitly, work out the current client in a similar way
to the current session - build a list of the possibilities then pick the
newest.
2009-11-04 22:44:01 +00:00
Tiago Cunha
bbad75fb6c Sync OpenBSD patchset 483:
Change session and client activity and creation time members to have more
meaningful names.

Also, remove the code to try and update the session activity time for the
command client when a command message is received as is pointless because it
des not have a session.
2009-11-04 22:42:31 +00:00
Tiago Cunha
a090b78e8d Sync OpenBSD patchset 482:
tv member of struct paste_buffer is updated but not otherwise used, so remove
it.
2009-11-04 22:39:20 +00:00
Tiago Cunha
0a4d830ee1 Sync OpenBSD patchset 481:
Fix vi page up mode key (from naddy), add missing half page keys, and sort.
2009-11-04 22:38:16 +00:00
Tiago Cunha
f3b4b60aa8 Sync OpenBSD patchset 480:
Double the escape timer (the time after a \033 is received before tmux gives up
waiting to see if it is part of a key sequence and passes it through) to 500
ms, the previous setting was too fast. Suggested by naddy.
2009-11-04 22:37:18 +00:00
Tiago Cunha
012e7106de Sync OpenBSD patchset 479:
When matching the session names with -t, look for exact matches first before
trying partial matches.

Avoids problems where two ambiguous matches are present before an exact match
(eg foo1, foo2, foo would give an error on trying -tfoo), reported by Natacha
Port? natbsd at instinctive dot eu.
2009-11-02 21:42:27 +00:00
Tiago Cunha
bbdf78cd97 Sync OpenBSD patchset 478:
Leftover unused variable :-/.
2009-11-02 21:41:16 +00:00
Tiago Cunha
6b4b4c78cf Sync OpenBSD patchset 477:
There isn't much point in doing lstat before connect so instead just do connect
and handle ENOENT from it which is a little tidier.
2009-11-02 21:40:44 +00:00
Tiago Cunha
ee1cc9f415 Sync OpenBSD patchset 476:
Reorder slightly to tidy code.
2009-11-02 21:39:34 +00:00
Tiago Cunha
053e40572c Sync OpenBSD patchset 475:
Add a flag for jobs that shouldn't be freed after they've died and use it for
status jobs, then only kill those jobs when status-left, status-right or
set-titles-string is changed.

Fixes problems with changing options from inside #().
2009-11-02 21:38:27 +00:00
Tiago Cunha
47f69075a0 Sync OpenBSD patchset 474:
Missing setenv/showenv aliases.
2009-11-02 21:35:40 +00:00
Tiago Cunha
b4beb1a5cb Sync OpenBSD patchset 473:
Missing ;. From eric@ ages ago.
2009-11-02 21:34:32 +00:00
Tiago Cunha
738489f2bb Sync OpenBSD patchset 472:
If any client currently displaying a window pane has more than 1 KB of output
buffered, don't accept any further data from the process running in the pane.

This makes tmux much more responsive when flooded with output, although other
buffers can still have an impact when running remotely.

Prompted by a query from Ranganathan Sankaralingam.
2009-11-02 21:32:52 +00:00
Nicholas Marriott
d57ba5e30b +. 2009-11-02 20:24:07 +00:00
Nicholas Marriott
ca24e00d75 Example from Thayer Williams. 2009-11-02 18:59:28 +00:00
Nicholas Marriott
513c1cf0c7 +-. 2009-11-01 18:48:20 +00:00
Tiago Cunha
d13d3a9902 Sync OpenBSD patchset 471:
Add a minor optimisatin: if the character being printed is space, don't worry
about setting the background colour or attributes (except reverse).
2009-10-28 23:17:28 +00:00
Tiago Cunha
c529c02ac0 Sync OpenBSD patchset 470:
Twaek this slightly to avoid confusing use of flags variable.
2009-10-28 23:16:30 +00:00
Tiago Cunha
745fd16452 Sync OpenBSD patchset 469:
Setting SGR0 when setting the fg and bg has problems if only one of the two is
meant to be default, so rewrite the code to move this outside, move setting
colours before attributes and generally clean up.

Tested by sthen@, fixes problems he was seeing with mutt and should fix some
existing problems with (rarely) lost attributes.
2009-10-28 23:15:32 +00:00
Tiago Cunha
f4514f5c60 Sync OpenBSD patchset 468:
Move the poll registration functions into the server-*.c files.
2009-10-28 23:14:15 +00:00
Tiago Cunha
a5acabd923 Sync OpenBSD patchset 467:
tabs are better; ok nicm
2009-10-28 23:12:38 +00:00
Tiago Cunha
e65aa04ad7 Sync OpenBSD patchset 466:
Clear signal flags /before/ taking action and continue afterwards to reduce
chance of dropping signals. Pointed out by deraadt@.
2009-10-28 23:11:07 +00:00
Tiago Cunha
d0afc47bfb Sync OpenBSD patchset 465:
Call fstat() after fopen() rather than stat() before.
2009-10-28 23:10:05 +00:00
Tiago Cunha
ce743b2058 Sync OpenBSD patchset 464:
Reset the umask right after fopen to avoid leaving it changed on error, noticed
by deraadt@.
2009-10-28 23:08:52 +00:00
Tiago Cunha
88bb9381b2 Sync OpenBSD patchset 463:
Use strlcpy instead of strncpy, pointed out by deraadt.
2009-10-28 23:08:04 +00:00
Tiago Cunha
876ded6dfe Sync OpenBSD patchset 462:
Don't do anything in the client callback if the client has already died to
avoid a use-after-free (the callback is used twice, once for the client itself
and once for the tty). Fixes crashes seen by Han Boetes.
2009-10-28 23:06:41 +00:00
Tiago Cunha
5a4ba76293 Sync OpenBSD patchset 461:
Nuke accidentally-committed debugging statement.
2009-10-28 23:05:43 +00:00
Tiago Cunha
31bb577075 Sync OpenBSD patchset 460:
Not all terminals swap CSI and SS3 on ctrl, so remove that.

Also mark the rxvt special-cases as such until terminfo is updated to have
kLFT5, kRIT5 etc.
2009-10-28 23:05:01 +00:00
Tiago Cunha
10aab82539 Sync OpenBSD patchset 459:
Rewrite xterm-keys code (both input and output) so that works (doesn't always
output the same modifiers, accepts all the possible input keys) and is more
understandable.
2009-10-28 23:03:51 +00:00
Tiago Cunha
1c4b7d33b1 Sync OpenBSD patchset 458:
Support the (mostly new) function key+modifier caps (kIC-kIC7). Most of these
will be caught (soon) by the xterm keys code in xterm itself but some other
descriptions such as rxvt define them as well.
2009-10-28 23:01:44 +00:00
Tiago Cunha
8ff0d06d34 Sync OpenBSD patchset 457:
On second thoughts, drop the rxvt output entirely.
2009-10-28 23:00:21 +00:00
Tiago Cunha
6cf9965e42 Sync OpenBSD patchset 456:
Set the output code for ctrl+cursor keys correctly, and disable (comment)
rxvt-style output.
2009-10-28 22:59:01 +00:00
Tiago Cunha
c45a56d66b Sync OpenBSD patchset 455:
As we always put the cursor keys into application mode, assume keys sent
with CSI have ctrl.

Also add a couple of comments.
2009-10-28 22:57:55 +00:00
Tiago Cunha
a8300b7a44 Sync OpenBSD patchset 454:
Tidy up table.
2009-10-28 22:56:50 +00:00
Tiago Cunha
98122860cc Sync OpenBSD patchset 453:
Drop INPUTKEY_CTRL and just handle it as part of the table.
2009-10-28 22:56:05 +00:00
Tiago Cunha
dd8174f545 Sync OpenBSD patchset 452:
Add or fix some comments.
2009-10-28 22:54:54 +00:00
Tiago Cunha
5350212e53 Sync OpenBSD patchset 451:
Tidy up table.
2009-10-28 22:54:00 +00:00
Tiago Cunha
4f7e669271 Sync OpenBSD patchset 450:
Rename keypad keys to something more useful.
2009-10-28 22:53:03 +00:00
Tiago Cunha
165538b4bd Sync OpenBSD patchset 449:
Remove the xterm-keys code which is broken (a replacement is coming but some
more cleanup is needed first).
2009-10-28 22:51:55 +00:00
Tiago Cunha
6338fd78f7 Sync OpenBSD patchset 448:
Don't try to continue processing a client if the session has been destroyed.
2009-10-28 22:50:24 +00:00
Tiago Cunha
181f7722b3 Sync OpenBSD patchset 447:
Remove -d from tmux.1 as well.
2009-10-28 22:49:22 +00:00
Tiago Cunha
41863470ba Sync OpenBSD patchset 446:
Remove the -d flag to tmux and just use op/AX to detect default colours.

Irritatingly, although op can be used to tell if a terminal supports default
colours, it can't be used to set them because in some terminfo descriptions it
resets attributes as a side-effect (acts as sgr0) and in others it doesn't, so
it is not possible to determine reliably what the terminal state will be
afterwards. So if AX is missing and op is present, tmux just sends sgr0.

Anyone using -d for a terminal who finds they actually needed it can replace it
using terminal-overrides, but please let me know as it is probably an omission
from terminfo.
2009-10-28 22:48:35 +00:00
Tiago Cunha
c4637da860 Sync OpenBSD patchset 445:
+time.h.
2009-10-28 22:46:15 +00:00
Nicholas Marriott
382aa8f6de RHS spacing. 2009-10-26 15:07:52 +00:00
Nicholas Marriott
a460e1ada3 Fix in IE6. 2009-10-26 15:04:45 +00:00
Nicholas Marriott
aaef0d316f Spacing tweaks. 2009-10-26 14:53:30 +00:00
Tiago Cunha
76bb6d6138 Add missing license. 2009-10-25 22:16:55 +00:00
Nicholas Marriott
2536ea12cb +confirm-before. 2009-10-25 21:58:05 +00:00
Nicholas Marriott
cb3b0e661d Add or clarify licenses where appropriate. 2009-10-25 21:45:26 +00:00
Nicholas Marriott
2cee0139e4 +. 2009-10-25 18:23:14 +00:00
Tiago Cunha
132485a660 Sync OpenBSD patchset 444:
[ is a punctuation character and should be escaped with Ql. Although the
current groff version we have seems to handle it fine, other versions are not
so tolerant.
2009-10-25 10:42:56 +00:00
Tiago Cunha
d55ee38c7f Sync OpenBSD patchset 443:
Bring a comment into line with reality.
2009-10-25 10:42:08 +00:00
Tiago Cunha
e214ea1c59 Update. 2009-10-25 10:41:25 +00:00
Tiago Cunha
85ae64b981 Sync OpenBSD patchset 442:
-a option to kill all except current pane. From Tiago Cunha, thanks!
2009-10-25 10:41:03 +00:00
Tiago Cunha
4a87cef46f Sync OpenBSD patchset 441:
Support the bright fg/bg colour SGR 90-97 and 100-107.

Reported by Tim Allen.
2009-10-25 10:39:48 +00:00
Nicholas Marriott
8c00dc2b6b Mustn't forget this. 2009-10-25 08:14:56 +00:00
Nicholas Marriott
38aa9a447a Much improved web page from Mike Putnam. 2009-10-25 08:14:34 +00:00
Nicholas Marriott
6dc796bb29 Update. 2009-10-25 08:13:13 +00:00
Nicholas Marriott
d8e566d0e9 cc -> $(CC) 2009-10-24 22:02:18 +00:00
Tiago Cunha
5820efa513 Sync OpenBSD patchset 440:
Redraw checks have to after handling input or pane redraw flags set by key
presses will not be acted on.
2009-10-23 17:53:16 +00:00
Tiago Cunha
e05fe0ba05 Sync OpenBSD patchset 439:
The client buffers have to be checked after every event in order to catch the
escape timers and properly reset the cursor.
2009-10-23 17:51:57 +00:00
Tiago Cunha
134a33f6e0 Adjust OpenBSD patchset 438 to the portable version. 2009-10-23 17:51:02 +00:00
Tiago Cunha
cc9ef11985 Sync OpenBSD patchset 438:
Split the server code handling clients, jobs and windows off into separate
files from server.c (merging server-msg.c into the client file) and rather than
iterating over each set after poll(), allow a callback to be specified when the
fd is added and just walk once over the returned pollfds calling each callback
where needed.

More to come, getting this in so it is tested.
2009-10-23 17:49:47 +00:00
Tiago Cunha
9ad2347258 Sync OpenBSD patchset 437:
Only redraw the pane when changing mode, not the entire window.
2009-10-23 17:41:20 +00:00
Tiago Cunha
dbefea339f Sync OpenBSD patchset 436:
Merge prepare_cmd into main as it is short and only called once.
2009-10-23 17:40:23 +00:00
Tiago Cunha
9260888d1c Fix CVS keyword. 2009-10-23 17:38:42 +00:00
Tiago Cunha
eaa188bb63 Sync OpenBSD patchset 435:
Tidy identify message send into a separate function.
2009-10-23 17:37:41 +00:00
Tiago Cunha
dc8b7d6b03 Sync OpenBSD patchset 434:
Don't try to unsuspend a client if it isn't suspended.
2009-10-23 17:33:26 +00:00
Tiago Cunha
84392ffc0d Sync OpenBSD patchset 433:
Client tidying: get rid of client_ctx struct in favour of two variables in
client.c, and move the functions in client-fn.c into other files.
2009-10-23 17:32:26 +00:00
Tiago Cunha
c6828bf32b Sync OpenBSD patchset 432:
Unused variable.
2009-10-23 17:28:29 +00:00
Tiago Cunha
31552722a8 Sync OpenBSD patchset 431:
Remove unused function.
2009-10-23 17:27:40 +00:00
Tiago Cunha
d7d4d7830b Sync OpenBSD patchset 430:
Nuke dead store.
2009-10-23 17:26:40 +00:00
Tiago Cunha
dbf2351d3a Sync OpenBSD patchset 429:
Now we are correctly not redrawing the whole pane on linefeed, redo the
last-cursor-position code to move to the right position when panes reach EOL.
2009-10-23 17:25:51 +00:00
Tiago Cunha
9731625230 Sync OpenBSD patchset 428:
Tweak descriptions for up/down pane to be clearer.
2009-10-23 17:24:57 +00:00
Tiago Cunha
a572533c89 Sync OpenBSD patchset 427:
Don't redraw the scroll region on linefeed/reverse index unless it is necessary
(the cursor is at the bottom/top). Should fix slow cursor movement when using
vi in a pane spotted by pirofti@.
2009-10-23 17:23:52 +00:00
Tiago Cunha
8ec8d1f32a Sync OpenBSD patchset 426:
Some terminals don't correctly clear their let's-wrap flag after changing the
scroll region (which moves the cursor to 0,0). This means that if the cursor
was at the edge of the screen, any further output after scroll region change
incorrectly causes a line wrap. Add a workaround to move the cursor to position
0 if it is at the screen edge before changing scroll region.
2009-10-23 17:22:39 +00:00
Tiago Cunha
21b23f8e54 Sync OpenBSD patchset 424:
%zu not %u, doh.
2009-10-23 17:21:34 +00:00
Tiago Cunha
fce889235c Sync OpenBSD patchset 422:
Correctly nuke the EOL $ marker when scrolling, reported by martynas@, thanks.
2009-10-23 17:17:20 +00:00
Tiago Cunha
f41a3914a5 Sync OpenBSD patchset 421:
Try to reduce the UTF-8 mess.

Get rid of passing around u_char[4]s and define a struct utf8_data which has
character data, size (sequence length) and width. Move UTF-8 character
collection into two functions utf8_open/utf8_append in utf8.c which fill in
this struct and use these functions from input.c and the various functions in
screen-write.c.

Space for rather more data than is necessary for one UTF-8 sequence is in the
utf8_data struct because screen_write_copy is still nasty and needs to reinject
the character (after combining) into screen_write_cell.
2009-10-23 17:16:25 +00:00
Tiago Cunha
c643ac4827 Sync OpenBSD patchset 420:
UTF-8 combined character fixes.

Thai can have treble combinations (1 x width=1 then 2 x width=0) so bump the
UTF-8 cell data size to 9 and alter the code to allow this.

Also break off the combining code into a separate function, handle any further
combining beyond the buffer size by replacing the character with _s, and when
redrawing the UTF-8 character don't assume the first part has just been
printed, redraw the entire line.
2009-10-23 17:13:10 +00:00
Tiago Cunha
97e02eae7d Sync OpenBSD patchset 419:
Move the check for whether to force a line wrapper lower down into the tty code
where it has access to the tty width, which is what should have been checked.
2009-10-23 17:11:26 +00:00
Tiago Cunha
516bfe7ba3 Sync OpenBSD patchset 418:
Nuke stray blank line.
2009-10-23 17:10:00 +00:00
Tiago Cunha
9463492ac1 Sync OpenBSD patchset 417:
Stop updating the screen when not in output mode, stops copy mode getting
confused.
2009-10-23 17:09:21 +00:00
Tiago Cunha
2f14ef61ff Sync OpenBSD patchset 416:
Always move the cursor position on !xenl terminals, since there is no invisible
last cursor position.

Also nuke an unused variable.
2009-10-23 17:08:30 +00:00
Tiago Cunha
2e39ab59d7 Sync OpenBSD patchset 415:
Don't print wide characters at screen width - 1. Matches uterm behaviour and
is probably a better idea anyway.
2009-10-23 17:07:18 +00:00
Tiago Cunha
ac4e4a2b6c Sync OpenBSD patchset 414:
Instead of having a complicated check to see if the cursor is in the last
position to avoid an explicit wrap, actually move it there.

Some UTF-8 fixes to come.
2009-10-23 17:06:23 +00:00
Tiago Cunha
13d1df659f Sync OpenBSD patchset 413:
When checking whether the region will scroll and the cursor position is thus
unsuitable for using CUD/CUU, check the current cursor position not the target
position.
2009-10-23 17:03:48 +00:00
Nicholas Marriott
4afecbe400 Getting the read and write ends of the pipe the right way round is usually
recommended. DOH.
2009-10-21 07:37:11 +00:00
Nicholas Marriott
bb625a76d9 +. 2009-10-21 07:19:59 +00:00
Nicholas Marriott
b027aa103c +. 2009-10-20 14:22:17 +00:00
Nicholas Marriott
59269a431b +. 2009-10-17 15:58:52 +00:00
Nicholas Marriott
c8f2584d87 +. 2009-10-15 20:48:51 +00:00
Tiago Cunha
24d7cf6618 Sync OpenBSD patchset 412:
The pane pty name isn't useful for anything so show the pane number instead.
2009-10-15 20:10:28 +00:00
Nicholas Marriott
1fdf489cae Turn off stupid warnings when using Sun CC. 2009-10-15 08:15:06 +00:00
Nicholas Marriott
0614ca434a Fill in the tty name in SunOS's forkpty compat, and use it in osdep_getname.
From Todd Carson.

Tweaked by me to nuke (void) casts. Say no to lint appeasement! ;-)
2009-10-15 07:11:25 +00:00
Tiago Cunha
8085adb8a2 Sync OpenBSD patchset 411:
cmd_find_client shouldn't die when there is an empty slot in the clients
array. DOH.
2009-10-15 01:56:45 +00:00
Tiago Cunha
3d88da7b2a Sync OpenBSD patchset 409:
Move lines into the history when scrolling even if the scroll region is not
the entire screen.

Allows ircII users to see history, prompted by naddy.
2009-10-15 01:55:12 +00:00
Tiago Cunha
ee46dba585 Sync OpenBSD patchset 408:
Handle DECCOLM by just emulating its side-effect of clearing the screen.
2009-10-15 01:53:48 +00:00
Tiago Cunha
a505ca69d9 Sync OpenBSD patchset 407:
Add mode keys to move the cursor to the top, middle and bottom of the screen.
H/M/L in vi mode and M-R/M-r in emacs (bottom of screen not bound in emacs).
2009-10-15 01:52:47 +00:00
Tiago Cunha
428f76db80 Fix CVS keyword. 2009-10-15 01:51:09 +00:00
Tiago Cunha
b6ebf7cb60 Update. 2009-10-15 01:49:39 +00:00
Tiago Cunha
6257be6371 Sync OpenBSD patchset 406:
Do this in a better way - print messages when exiting with nonzero.

Also remove the login shell information from server-info, only the client
should care about it.
2009-10-15 01:48:24 +00:00
Tiago Cunha
9800dc4697 Sync OpenBSD patchset 405:
Don't print exit messages when used as a login shell, requested by martynas@ a
while back.
2009-10-15 01:45:13 +00:00
Tiago Cunha
b8e4bd2029 Sync OpenBSD patchset 404:
Don't try to use \n across scroll region when doing \r\n either.
2009-10-15 01:44:15 +00:00
Tiago Cunha
941032b707 Sync OpenBSD patchset 403:
When a session is unattached, reset its activity timer to prevent it locking
instantly when reattached.
2009-10-15 01:43:16 +00:00
Tiago Cunha
fe99f6fa11 Sync OpenBSD patchset 402:
Instead of using something sort of similar for both newline checks, use
something the same. Doesn't fix the bug I'm looking for though :-/.
2009-10-15 01:42:07 +00:00
Tiago Cunha
6103628129 Sync OpenBSD patchset 401:
When drawing lines that have wrapped naturally, don't force a newline but
permit them to wrap naturally again. This allows terminals that use this to
guess where lines start and end for eg mouse selecting (like xterm) to work
correctly.

This was another long-standing issue raised by several people over the last
while.

Thanks to martynas@ for much testing. This was not trivial to get right so
bringing it in for wider testing and adn to fix any further glitches in-tree.
2009-10-15 01:41:14 +00:00
Tiago Cunha
cbd3b1bc9b Sync OpenBSD patchset 400:
When backspace is received at the beginning of a line and the previous line was
wrapped, move the cursor back up to the end of the previous line.

Another one of the forgotten persons requested this quite a while ago (I need
to start noting names on todo items...) when it was quite hard to
implement. Now it is easy and I don't see it can do any harm, so hey presto...
2009-10-15 01:39:30 +00:00
Tiago Cunha
04db3c6211 Sync OpenBSD patchset 399:
Don't run through the column unchanged case if the row was unchanged but there
were no suitable optimisations, instead make it an else to fall through to
absolute addressing.
2009-10-15 01:38:09 +00:00
Tiago Cunha
858b8b190b Sync OpenBSD patchset 398:
If the vertical cursor movement crosses the scroll region, CUU and CUD
shouldn't be used even if VPA isn't present - in that case CUP should be used.
2009-10-15 01:36:53 +00:00
Tiago Cunha
7af01a4afb Sync OpenBSD patchset 397:
Wrap a couple of long lines.
2009-10-15 01:35:35 +00:00
Tiago Cunha
9e4a3d50f0 Sync OpenBSD patchset 396:
Use absolute movement if right at the end of the line as it isn't a reliable
place to move from relatively.
2009-10-15 01:34:28 +00:00
Tiago Cunha
44fd6f4381 Sync OpenBSD patchset 395:
Use relative cursor movement instead of absolute when possible and when
supported by the terminal to reduce the size of the output data (generally
about 10-20%).
2009-10-15 01:33:21 +00:00
Tiago Cunha
8ab3a3d9aa Sync OpenBSD patchset 394:
Permit attributes to be turned off in #[] by prefixing with "no", for example
"noblink".
2009-10-15 01:31:38 +00:00
Tiago Cunha
8bdcc10c8f Sync OpenBSD patchset 393:
Similarly add a tty_cursor_pane function to tidy up most of the calls.
2009-10-15 01:30:00 +00:00
Tiago Cunha
6369fca253 Sync OpenBSD patchset 392:
_absolute is redundant, just use tty_region.
2009-10-15 01:28:14 +00:00
Tiago Cunha
9b771a96f0 Sync OpenBSD patchset 391:
Cleanup: use two functions for region setting, one for absolute and one inside
pane.
2009-10-15 01:26:50 +00:00
Nicholas Marriott
f8f2421ac3 Don't let cmd_lookup_client find clients w/o a session. 2009-10-14 13:22:24 +00:00
Nicholas Marriott
9e6d1b24c8 Support for automatic-rename for Solaris thanks to Todd Carson. 2009-10-14 10:14:21 +00:00
Nicholas Marriott
587e7127eb +. 2009-10-13 14:35:06 +00:00
Nicholas Marriott
6b522bd770 +. 2009-10-13 14:27:57 +00:00
Nicholas Marriott
edc901d107 Lots of stuff is done done done. 2009-10-13 13:48:47 +00:00
Nicholas Marriott
e88a2ba7d4 +. 2009-10-12 23:13:06 +00:00
Tiago Cunha
629afba526 Reduce diff with OpenBSD. 2009-10-12 00:49:06 +00:00
Tiago Cunha
f92cc84631 Sync OpenBSD patchset 390:
Like linefeed, don't set the scroll region for reverse index unless it will be
needed.

While here, also tidy up a couple of long lines and remove an extraneous blank.
2009-10-12 00:41:00 +00:00
Tiago Cunha
6ea6d1b29f Sync OpenBSD patchset 389:
punctuation fix;
2009-10-12 00:38:31 +00:00
Tiago Cunha
39afe3fc2a Sync OpenBSD patchset 388:
Set the current window pointer to NULL when killing a winlink that is to be
replaced with link-window -k. This prevents it being pushed onto the last
window stack and causing a use-after-free.

Only took me an hour to find this :-/...
2009-10-12 00:37:41 +00:00
Tiago Cunha
3584fa15ec No paths.h in here, as well. 2009-10-12 00:36:31 +00:00
Tiago Cunha
6091b051fb Sync OpenBSD patchset 387:
Add a pipe-pane command to allow a pane to be piped to a shell command, for
example:

        pipe-pane 'cat >~/out'

No arguments stops outputing and closes the pipe; the -o flag toggles a pipe
and on and off (useful for key bindings).

Suggested by espie@.
2009-10-12 00:35:08 +00:00
Tiago Cunha
a053aeddf8 Sync OpenBSD patchset 386:
Convert if-shell over to the background job framework as well.
2009-10-12 00:29:03 +00:00
Tiago Cunha
50ece89ab9 Sync OpenBSD patchset 385:
Remove a debugging leftover and add copyright.
2009-10-12 00:26:06 +00:00
Tiago Cunha
197f8b88bf Sync OpenBSD patchset 384:
Switch run-shell over to queue the command in the background like #().
2009-10-12 00:25:25 +00:00
Tiago Cunha
c8d0608369 Sync OpenBSD patchset 383:
There isn't much point in having a free function if it isn't used.

Also allow a NULL tree.
2009-10-12 00:22:17 +00:00
Tiago Cunha
1b03bc2404 Sync OpenBSD patchset 382:
Collect status from dead jobs and don't invoke the callback until both
all input (the socket is closed) and status is available.
2009-10-12 00:21:08 +00:00
Tiago Cunha
b26ea8462e Sync OpenBSD patchset 381:
Clean up by introducing a wrapper struct for mouse clicks rather than passing
three u_chars around.

As a side-effect this fixes incorrectly rejecting high cursor positions
(because it was comparing them as signed char), reported by Tom Doherty.
2009-10-12 00:18:19 +00:00
Tiago Cunha
323469723b Sync OpenBSD patchset 380:
Braek some bits out of server_fill_client() that aren't really related to
polling into their own function.
2009-10-12 00:14:44 +00:00
Tiago Cunha
d7fa9bc056 Sync OpenBSD patchset 379:
Put all jobs on a global all_jobs list and use that in server.c instead of
running through all the clients.
2009-10-12 00:12:33 +00:00
Tiago Cunha
256a55b33b Sync OpenBSD patchset 378:
-scroll mode which is dead.
2009-10-12 00:09:48 +00:00
Tiago Cunha
53f1e6eed2 Update. 2009-10-12 00:08:48 +00:00
Tiago Cunha
0b8a7dc4a2 Sync OpenBSD patchset 377:
Split list-panes off from list-windows.
2009-10-12 00:08:12 +00:00
Tiago Cunha
cf9804f2a0 Sync OpenBSD patchset 376:
Accept key and mouse input for keys in zombified windows if they are in a mode..
2009-10-12 00:04:56 +00:00
Tiago Cunha
bc90c7c199 Sync OpenBSD patchset 375:
When a window is zombified and automatic-rename is on, append [dead] to the
name.
2009-10-12 00:03:04 +00:00
Tiago Cunha
3e93bdf31b Do not include paths.h, since it's OS-dependent, due to OpenBSD patchset 374. 2009-10-11 23:59:34 +00:00
Tiago Cunha
bc236109fd Sync OpenBSD patchset 374:
Rather than running status-left, status-right and window title #() with popen
immediately every redraw, queue them up and run them in the background,
starting each once every status-interval. The actual status line uses the
output from the last run.

This brings several advantages:

- tmux itself may be called from inside #() without causing the server to hang;
- likewise, sleep or similar doesn't cause the server to block;
- commands aren't run excessively often when redrawing;
- commands shared by status-left and status-right, or used multiple times, will
  only be run once.

run-shell and if-shell still use system()/popen() but will be changed over to
use this too later.
2009-10-11 23:55:26 +00:00
Tiago Cunha
07ad6da7e8 Update. 2009-10-11 23:47:02 +00:00
Tiago Cunha
ea1721bcb0 Sync OpenBSD patchset 373:
New option, mouse-select-pane. If on, the mouse may be used to select the
current pane.

Suggested by sthen@ and also by someone else ages ago who I have forgotten.
2009-10-11 23:46:02 +00:00
Tiago Cunha
2486a36af3 Sync OpenBSD patchset 372:
There is no point setting the scroll region up for line feeds unless scrolling
is actually going to happen, so don't.
2009-10-11 23:39:37 +00:00
Tiago Cunha
6a1ebb11df Sync OpenBSD patchset 371:
Add "grouped sessions" which have independent name, options, current window and
so on but where the linked windows are synchronized (ie creating, killing
windows and so on are mirrored between the sessions). A grouped session may be
created by passing -t to new-session.

Had this around for a while, tested by a couple of people.
2009-10-11 23:38:16 +00:00
Tiago Cunha
1fd3a405e6 Update. 2009-10-11 23:31:02 +00:00
Tiago Cunha
91e4dc83fc Sync OpenBSD patchset 370:
Support for individual session idle time locking. May be enabled by turning off
the lock-server option (it is on by default). When this is off, each session
locks when it has been idle for the lock-after-time setting. When on, the
entire server locks when ALL sessions have been idle for their individual
lock-after-time settings.

This replaces one global-only option (lock-after-time) with another
(lock-server), but the default behaviour is usually preferable so there don't
seem to be many alternatives.

Diff/idea largely from Thomas Adam, tweaked by me.
2009-10-11 23:30:28 +00:00
Tiago Cunha
a4ea6a9d19 Sync OpenBSD patchset 369:
Instead of passing a struct pollfd ** around through various functions, build
them into a tree and then convert into a flat poll array before and after poll.

This adds a little code but should reduce annoying problems with ordering when
adding new things that also need to be polled.
2009-10-11 23:25:44 +00:00
Nicholas Marriott
0e5f20a97d +. 2009-10-11 22:06:25 +00:00
Nicholas Marriott
bc67e01e52 Done or not doing. 2009-10-11 12:46:40 +00:00
Nicholas Marriott
eba57d84a6 pcvt25 has AX but in fact the console doesn't support it. 2009-10-10 17:08:57 +00:00
Nicholas Marriott
3d1936e9c7 Update. 2009-10-10 15:17:50 +00:00
Tiago Cunha
932f0a757f Sync with reality. 2009-10-09 22:55:43 +00:00
Tiago Cunha
cddb781127 Sync OpenBSD patchset 368:
The UTF-8 detection idea doesn't work and I am reasonably happy with the
current methods, so remove the (already #ifdef 0'd) code.
2009-10-09 13:11:42 +00:00
Tiago Cunha
220f3f2384 Update. 2009-10-09 13:07:29 +00:00
Tiago Cunha
9ac062acef Sync OpenBSD patchset 367:
Add a simple synchronize-panes window option: when set, all input to any pane
that is part of the window is also sent to all other panes in the same
window. Suggested by several, most recently Tomasz Pajor.
2009-10-09 13:07:04 +00:00
Tiago Cunha
765a38e534 Sync OpenBSD patchset 366:
Be less aggressive about turning the cursor off, only explicitly turn it off
when tmux is redrawing, otherwise leave in the state set by the application.
2009-10-09 13:03:28 +00:00
Nicholas Marriott
c2e78a3104 Add a little. 2009-10-09 07:30:27 +00:00
Tiago Cunha
1eb665832a Sync OpenBSD patchset 365:
Support J and K for scroll up and scroll down in copy mode with vi keys,
suggested by martynas.
2009-10-07 17:13:59 +00:00
Tiago Cunha
64e9d07b1b Sync OpenBSD patchset 364:
Fix comment.
2009-10-07 17:10:44 +00:00
Tiago Cunha
d23635f66d Remove unneeded defines that were used with the internal locking mechanism. 2009-10-06 15:32:21 +00:00
Tiago Cunha
4640627f6e Sync OpenBSD patchset 363:
Accept ^? for backspace as well as BSpace.
2009-10-06 14:15:45 +00:00
Tiago Cunha
83bf166a1f Update. 2009-10-06 14:14:40 +00:00
Tiago Cunha
f881502f84 Sync OpenBSD patchset 362:
Remove scroll mode which is now redundant, copy mode should be used instead.

The = key binding now does nothing.
2009-10-06 14:14:07 +00:00
Tiago Cunha
32291172bf Sync OpenBSD patchset 361:
Make C-Up and C-Down in copy mode scroll the screen up and down one line
without moving the cursor, like Up and Down in scroll mode (which will shortly
disappear).
2009-10-06 14:10:10 +00:00
Tiago Cunha
eb7f8b6d33 Sync OpenBSD patchset 360:
If no target client is specified to commands which accept one, try to guess the
current client, in a similar manner to how sessions already work: if the
current session can be established and has only one client, use that; otherwise
use the most recently created client.
2009-10-06 14:00:50 +00:00
Tiago Cunha
d8c0634524 Sync OpenBSD patchset 359:
tweak previous;
2009-10-05 18:26:00 +00:00
Tiago Cunha
11e97f4eb0 Sync OpenBSD patchset 358:
Get / and ? the right way round in vi mode, and use : for goto line rather than
g.
2009-10-05 18:25:05 +00:00
Tiago Cunha
813d78e46a Sync OpenBSD patchset 357:
Check for already locked/suspended clients in server_lock_client rather than
its callers.
2009-10-05 18:23:31 +00:00
Tiago Cunha
2931277608 Sync OpenBSD patchset 356:
Add a key string for space ("Space") and document the names, suggested by
guenther@. Also document how to bind " and ', suggested by miod@.
2009-10-05 18:21:58 +00:00
Tiago Cunha
6b3ec44ee9 Sync OpenBSD patchset 355:
C-v and M-v too.
2009-10-05 18:19:52 +00:00
Tiago Cunha
19e502c64e Sync OpenBSD patchset 354:
Support C-n/C-p with emacs keys in choice mode, also fix a comment.
2009-10-05 18:18:50 +00:00
Tiago Cunha
a9a0cd8297 Update. 2009-09-25 17:52:26 +00:00
Tiago Cunha
88c3b9c989 Sync OpenBSD patchset 353:
New lock-client and lock-session commands to lock an individual client or all
clients attached to a session respectively.
2009-09-25 17:51:39 +00:00
Tiago Cunha
804b8696a4 Sync OpenBSD patchset 352:
Don't allow locked or suspended clients to limit the size of active clients.
2009-09-25 17:47:42 +00:00
Tiago Cunha
b5d23ef38b Sync OpenBSD patchset 351:
Remove PROMPT_HIDDEN code which is now unused.
2009-09-25 17:45:46 +00:00
Nicholas Marriott
c190a65c69 Should be bestp now. 2009-09-24 12:30:22 +00:00
Nicholas Marriott
bf4b27e679 Earlier versions of FreeBSD are missing RB_PREV. 2009-09-24 07:15:22 +00:00
Nicholas Marriott
d73516c0a9 Use __sun not __sun__ as Sun's CC doesn't define the latter. 2009-09-23 16:09:12 +00:00
Tiago Cunha
ac95da3afc Adjust OpenBSD patchset 350 to the portable version. 2009-09-23 15:20:16 +00:00
Tiago Cunha
5be3fb86b9 Sync OpenBSD patchset 350:
Support -c like sh(1) to execute a command, useful when tmux is a login
shell. Suggested by halex@.

This includes another protocol version increase (the last for now) so again
restart the tmux server before upgrading.
2009-09-23 15:18:56 +00:00
Tiago Cunha
4dd332c95e Sync OpenBSD patchset 349:
On SIGTERM, just abandon any suspended/locked clients and leave them to it,
otherwise the server will hang around (refusing new connections) until they
exit properly.
2009-09-23 15:10:37 +00:00
Tiago Cunha
fea7bda58f Sync OpenBSD patchset 348:
Don't die if the client is detaching (the tty has been closed) after waking up
from locking.
2009-09-23 15:08:21 +00:00
Tiago Cunha
88f689e167 Remove HAVE_LOGIN_CAP now that the internal locking mechanism was removed, due
to OpenBSD patchset 347.
2009-09-23 15:05:03 +00:00
Tiago Cunha
5743da5588 Update. 2009-09-23 15:01:10 +00:00
Tiago Cunha
1310ea2729 Sync OpenBSD patchset 347:
Remove the internal tmux locking and instead detach each client and run the
command specified by a new option "lock-command" (by default "lock -np") in
each client.

This means each terminal has to be unlocked individually but simplifies the
code and allows the system password to be used to unlock.

Note that the set-password command is gone, so it will need to be removed from
configuration files, and the -U command line flag has been removed.

This is the third protocol version change so again it is best to stop the tmux
server before upgrading.
2009-09-23 15:00:09 +00:00
Tiago Cunha
2acf349d4e Sync OpenBSD patchset 346:
Trim some code by moving the ioctl(TIOCGWINSZ) after SIGWINCH from the client
into the server.

This is another (the second of four) protocol version changes coming this
morning, so again the server should be killed before upgrading.
2009-09-23 14:44:02 +00:00
Tiago Cunha
acedc2dcf2 Sync OpenBSD patchset 345:
Don't attempt to open() the tty path, rely on the client sending its stdin fd
with imsg and fatal if it doesn't, then set the FD_CLOEXEC flag in tty_init
instead of tty_open to prevent them leaking into child processes if any are
created between the two calls.

This bumps the protocol version, so the tmux server should be killed before
upgrading.
2009-09-23 14:39:30 +00:00
Tiago Cunha
c40d8cbda4 Sync OpenBSD patchset 344:
Be more careful about what flags are cleared when opening the terminal,
otherwise the opened/started flags are cleared and the terminal never released.
2009-09-23 14:33:13 +00:00
Nicholas Marriott
07bd160861 +. 2009-09-23 12:07:08 +00:00
Nicholas Marriott
2c9d4dfdd4 Tweak tparm() to make Solaris' backward userland happy and remove the -I mess
in configure which tried to deal with the fallout from their horrible package
management.
2009-09-22 19:20:08 +00:00
Tiago Cunha
df7b68480c Sync OpenBSD patchset 343:
Permit multiple prefix keys to be defined, separated by commas, for example:

set -g prefix ^a,^b

Any key in the list acts as the prefix. The send-prefix command always sends
the first key in the list.
2009-09-22 14:22:21 +00:00
Tiago Cunha
31ccf2f813 Sync OpenBSD patchset 342:
Use KEYC_NONE constant instead of 0 on init.
2009-09-22 14:06:40 +00:00
Tiago Cunha
480211f0ee Sync OpenBSD patchset 341:
Nuke -i option which isn't used anymore.
2009-09-22 14:03:11 +00:00
Tiago Cunha
59e65cbda2 Sync OpenBSD patchset 340:
Use option print function for info messages as well.
2009-09-22 13:59:46 +00:00
Tiago Cunha
649b7c132d Sync OpenBSD patchset 339:
Move common code from show-options and show-window-options into a function.
2009-09-22 13:56:02 +00:00
Tiago Cunha
b6bc8a6828 Sync OpenBSD patchset 338:
zap trailing whitespace;
2009-09-22 13:51:24 +00:00
Tiago Cunha
f2d249fdc7 Sync OpenBSD patchset 337:
Drop tiny union from option struct.
2009-09-22 13:49:13 +00:00
Tiago Cunha
c28d4e41cf Sync OpenBSD patchset 336:
Key options were implemented as a number so these struct members are unused.
2009-09-22 13:45:06 +00:00
Nicholas Marriott
1572e483c2 Done. 2009-09-22 11:40:11 +00:00
Tiago Cunha
f8ea4f44e8 Update. 2009-09-20 22:20:51 +00:00
Tiago Cunha
e3dcc5327a Sync OpenBSD patchset 335:
run-shell command to run a shell command without opening a window, sending
stdout to output mode.
2009-09-20 22:20:10 +00:00
Tiago Cunha
bd24bdd411 Sync OpenBSD patchset 334:
Nuke unused variables and fix stupid error message.
2009-09-20 22:17:03 +00:00
Tiago Cunha
7335ef5792 Sync OpenBSD patchset 333:
Move some common and untidy code for window link/unlink into generic functions
instead of duplicating it in move/link window..
2009-09-20 22:15:32 +00:00
Tiago Cunha
3266fb5441 Sync OpenBSD patchset 332:
Regularise some fatal messages.
2009-09-20 22:11:27 +00:00
Tiago Cunha
ab96772436 Delete backup files in the compat directory, as well. 2009-09-20 22:06:34 +00:00
Nicholas Marriott
c7ace08193 Now working on 1.1. 2009-09-20 19:01:01 +00:00
Nicholas Marriott
f82598ca2d 1.0. 2009-09-20 18:54:21 +00:00
Nicholas Marriott
b29d4affd8 Don't try to use tio if it is NULL. 2009-09-20 18:31:16 +00:00
Nicholas Marriott
6594af3729 These are done. 2009-09-20 17:52:39 +00:00
Nicholas Marriott
6df9ac7c37 FreeBSD tree.h is fine. 2009-09-20 17:51:54 +00:00
Tiago Cunha
73f58b90a0 Update. 2009-09-19 18:53:56 +00:00
Tiago Cunha
23d7ed3187 Sync OpenBSD patchset 331:
New option, set-titles-string, to allow the window title to be specified (as
for status-left/right) if set-titles is on. Also only update the title when the
status line is being redrawn.
2009-09-19 18:53:01 +00:00
Nicholas Marriott
a2e03ce3cb Add some bits. 2009-09-18 14:19:18 +00:00
Nicholas Marriott
15b643fc11 Sync from OpenBSD:
==
Rather than constructing an entire termios struct from ttydefaults.h, just let
forkpty do it and then alter the bits that should be changed after fork. A
little neater and more portable.
==

This should fix problems caused by glibc's broken ttydefaults.h file.
2009-09-16 12:36:28 +00:00
Tiago Cunha
150fba5ecd Sync OpenBSD patchset 329:
Enclose repeated buffer draining code in a new msgbuf_drain()
function, which is additionally exported for use by others.

From nicm@, who reminded me that tmux is now using buffer.c, too.
2009-09-15 23:59:40 +00:00
Tiago Cunha
c507bf25de Sync OpenBSD patchset 328:
Stick line length to what is actually used (removing an optimization that
allowed it to be bigger), and use clear line/EOL sequences rather than spaces
in copy/scroll mode.

This fixes xterm copy/paste from tmux which treats trailing spaces differently
from clearing a line with the escape sequences. Reported by martynas@.
2009-09-15 23:54:57 +00:00
Tiago Cunha
dbaa28492e Sync OpenBSD patchset 327:
The default terminal size should be 80x24, not 80x25.
2009-09-15 23:52:30 +00:00
Tiago Cunha
960cd3da69 Sync OpenBSD patchset 326:
Nuke unused server_client_index function, pointed out by martynas@.
2009-09-15 23:50:32 +00:00
Nicholas Marriott
82d6bab57c +. 2009-09-15 19:02:35 +00:00
Nicholas Marriott
24baf14e53 Update. 2009-09-15 07:43:25 +00:00
Tiago Cunha
5fcf7149d4 Always set VERASE to \177. 2009-09-13 20:56:52 +00:00
Tiago Cunha
4d4ec52df8 Zap unused variables. 2009-09-13 20:43:21 +00:00
Tiago Cunha
69e7f4af19 Sync OpenBSD patchset 324:
Tidy some common code for destroying sessions into a new function.
2009-09-13 20:37:37 +00:00
Tiago Cunha
61990deb36 Sync OpenBSD patchset 323:
tmux always outputs \177 for backspace, so explicitly set VERASE to \177 for
new windows.
2009-09-13 20:30:12 +00:00
Tiago Cunha
0ec1ce005c Sync OpenBSD patchset 322:
Permit options such as status-bg to be configured using the entire 256 colour
palette by setting "colour0" to "colour255".
2009-09-11 14:13:52 +00:00
Tiago Cunha
f0cb57d8ac Sync OpenBSD patchset 321:
While the display-panes indicator is on screen, make the number keys select the
pane with that index.
2009-09-08 00:01:11 +00:00
Tiago Cunha
930f67f474 Sync OpenBSD patchset 320:
Reference count clients and sessions rather than relying on a saved index for
cmd-choose-*.
2009-09-07 23:59:19 +00:00
Tiago Cunha
1de812d5a8 Sync OpenBSD patchset 319:
Tiny cleanup.

ok nicm@
2009-09-07 23:50:07 +00:00
Tiago Cunha
c272de7cba Sync OpenBSD patchset 318:
Give each paste buffer a size member instead of requiring them to be
zero-terminated.
2009-09-07 23:48:54 +00:00
Tiago Cunha
5edc465802 Sync OpenBSD patchset 317:
Permit embedded colour and attributes in status-left and status-right using new
#[] special characters, for example #[fg=red,bg=blue,blink].
2009-09-07 23:37:48 +00:00
Nicholas Marriott
ec195a4e15 +. 2009-09-07 15:41:52 +00:00
Tiago Cunha
bb2d57dcbf Sync OpenBSD patchset 316:
Only redraw all clients once when the backoff timer expires rather than every
second all the time.

Reported by Simon Nicolussi.
2009-09-05 19:03:41 +00:00
Tiago Cunha
02c4760ace Sync OpenBSD patchset 315:
Tidy main and make it a bit easier to read.
2009-09-04 20:37:40 +00:00
Tiago Cunha
51a1f25247 Sync OpenBSD patchset 314:
Tell the user when sleeping due to password backoff.
2009-09-04 20:27:06 +00:00
Nicholas Marriott
895efe7b05 Solaris needs a knob twiddled to get POSIX getpwduid_r. 2009-09-04 14:48:25 +00:00
Tiago Cunha
83f5581da4 Sync OpenBSD patchset 313:
Fix a race condition when asking a client to take over the terminal (switching
to a different poll loop):

If a MSG_READY was followed very quickly by a MSG_EXIT (for example if doing
"tmux new 'exit'"), both messages could be read as part of the same imsg_read
in the first client poll loop. The MSG_READY would then cause a switch to the
second client loop, which would immediately call poll(2) again, causing the
client to hang forever waiting for an exit message that it already had.

Change to call imsg_get to process any existing messages before polling.
2009-09-03 21:06:30 +00:00
Tiago Cunha
884ebb6dab Sync OpenBSD patchset 309:
Accept -l to make it easier for people who use tmux as a login shell to use
$SHELL. Originally from martynas@, tweaked by me.
2009-09-03 21:02:55 +00:00
Tiago Cunha
c274551db6 - Make it compile on operating systems other than BSD due to OpenBSD patchset
308.
- While there, remove some duplicate code from the compat header file.
2009-09-03 20:54:39 +00:00
Tiago Cunha
f796336a12 Sync OpenBSD patchset 308:
When incorrect passwords are entered, behave similarly to login(1) and backoff
for a bit. Based on a diff from martynas@.
2009-09-03 20:44:38 +00:00
Tiago Cunha
3b944fe7e8 Sync OpenBSD patchset 307:
Add a transpose-chars command in edit mode (C-t in emacs mode only). From Kalle
Olavi Niemitalo.
2009-09-02 22:45:17 +00:00
Nicholas Marriott
afd0bd7cb0 When shutting down the server, expect clients to be polite and exit when asked
with the right message.
2009-09-02 21:36:00 +00:00
Nicholas Marriott
a5c17d77bf Nuke debugging. 2009-09-02 20:17:23 +00:00
Nicholas Marriott
d33caca6c7 That was the wrong fix. MSG_ERROR should set the error and the client should
use the error and exit on MSG_EXIT (it was being handled in the default
case). Undo the last change, move the errstr check into the MSG_EXIT case, and
add a comment.
2009-09-02 20:16:29 +00:00
Nicholas Marriott
c23bde74ec Set exittype for error exit as well as the error string. 2009-09-02 20:01:22 +00:00
Nicholas Marriott
ecffcf1667 Update. 2009-09-02 19:33:47 +00:00
Nicholas Marriott
26682256b3 OS X CMSG_FIRSTHDR is broken. 2009-09-02 12:30:56 +00:00
Tiago Cunha
5838ee1263 Sync OpenBSD patchset 306:
If forking a login shell or if SHELL is otherwise not useful, set it to the
default shell. Based on a diff from martynas@.
2009-09-02 01:08:32 +00:00
Tiago Cunha
b7cb7d10f9 Update. 2009-09-02 01:06:30 +00:00
Tiago Cunha
521659db4b Adjust OpenBSD patchset 305 to the portable version. 2009-09-02 01:05:55 +00:00
Tiago Cunha
a3a150faf2 Sync OpenBSD patchset 305:
When using tmux as a login shell, there is currently no way to specify a shell
to be used as a login shell inside tmux, so add a default-shell session option.
This sets the shell invoked as a login shell when the default-command option is
empty.

The default option value is whichever of $SHELL, getpwuid(getuid())'s pw_shell
or /bin/sh is valid first.

Based on a diff from martynas@, changed by me to be a session option rather
than a window option.
2009-09-02 01:02:44 +00:00
Tiago Cunha
ce5c441f0f Sync OpenBSD patchset 304:
Use "Password:" with no space for password prompts and don't display a *s for
the password, like pretty much everything else. From martynas@ with minor
tweaks by me.
2009-09-02 00:55:49 +00:00
Tiago Cunha
99de03ea32 Sync OpenBSD patchset 303:
Sort cases same as getopt argument, from martynas.
2009-09-02 00:54:00 +00:00
Tiago Cunha
d463eddb8b Update. 2009-08-31 22:31:44 +00:00
Tiago Cunha
ed3535db8a Sync OpenBSD patchset 302:
Add a new display-panes command, with two options (display-panes-colour and
display-panes-time), which displays a visual indication of the number of each
pane.
2009-08-31 22:30:15 +00:00
Tiago Cunha
2fe369831c Sync OpenBSD patchset 301:
squash typo
2009-08-31 22:25:33 +00:00
Tiago Cunha
86fb9737dc Sync OpenBSD patchset 300:
Don't call tty_free unless the client is a terminal, otherwise tty_init hasn't
been called and it may end up doing close(0). From Kalle Olavi Niemitalo.
2009-08-31 22:24:18 +00:00
Tiago Cunha
d15e88cb68 Sync OpenBSD patchset 299:
Initialise the arg2 pointer properly (also free it when freeing the
others). Fixes crashes with J in malloc_options reported by oga.
2009-08-26 22:13:52 +00:00
Tiago Cunha
83e44c7d8e Sync OpenBSD patchset 298:
Make this work when the clock is in small characters as well. Doh.
2009-08-26 22:12:21 +00:00
Tiago Cunha
fde3bda453 Sync OpenBSD patchset 297:
Fix clock mode in black and white terminals now that tty.c tries to fix
reverse.
2009-08-26 22:11:00 +00:00
Nicholas Marriott
1a5aba47c7 ttydefchars is a fucking horlicks. Happily we only need it in one file, move it
in there to avoid multiple inclusion issues.

Perhaps it would be better to pass NULL through to forkpty in the default
case...
2009-08-26 09:10:47 +00:00
Nicholas Marriott
6b4ed722b1 FreeBSD and NetBSD HAVE got ttydefaults.h. Fixes SF bug 2844744.
Also make clang use -iquote in makefiles.
2009-08-26 08:58:39 +00:00
Tiago Cunha
1ce325b31e Sync OpenBSD patchset 296:
Print -l and -p when showing command, pointed out by Tiago Cunha.
2009-08-25 16:52:42 +00:00
Tiago Cunha
f5d38f2696 Update. 2009-08-25 16:50:34 +00:00
Tiago Cunha
bd5b011ecd Include <ctype.h>. 2009-08-25 13:55:29 +00:00
Tiago Cunha
8fd77cbb5b Sync OpenBSD patchset 294:
Add a choose-client command and extend choose-{session,window} to accept a
template. After a choice is made, %% (or %1) in the template is replaced by the
name of the session, window or client suitable for -t and the result executed
as a command. So, for example, "choose-window "killw -t '%%'"" will kill the
selected window.

The defaults if no template is given are (as now) select-window for
choose-window, switch-client for choose-session, and detach-client for
choose-client (now bound to D).
2009-08-25 13:53:39 +00:00
Tiago Cunha
c1653ff654 Sync OpenBSD patchset 293:
gcc2 doesn't understand attributes on function pointers.
2009-08-25 13:11:24 +00:00
Nicholas Marriott
22b2b7c6c5 Done. 2009-08-25 12:24:45 +00:00
Tiago Cunha
d5bc78d98b Sync OpenBSD patchset 292:
Add some other obvious variables to update-environment (WINDOWID SSH_ASKPASS
SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION) so they are updated in the session
environment on new/attach.
2009-08-24 16:35:24 +00:00
Tiago Cunha
a3799e0350 Sync OpenBSD patchset 291:
Some code tidying.
2009-08-24 16:31:26 +00:00
Tiago Cunha
35b926c445 Sync OpenBSD patchset 290:
When using source-file, run the commands in the context of the source-file
command rather than with no context. This makes things like attach work from a
file.
2009-08-24 16:27:03 +00:00
Tiago Cunha
2e2e762743 Sync OpenBSD patchset 289:
The cursession member in struct cmd_ctx is always either curclient->session or
NULL when curclient is also NULL, so just eliminate it.
2009-08-24 16:24:18 +00:00
Nicholas Marriott
266c13df18 Check the return value of strunvis against -1 not NULL. 2009-08-23 11:50:39 +00:00
Tiago Cunha
633e74ef80 Sync OpenBSD patchset 287:
Emulate dch/dch1 if missing by redrawing the entire line.
2009-08-21 21:15:00 +00:00
Tiago Cunha
1fa8a8f4a6 Sync OpenBSD patchset 285:
Ugh, committed the wrong version of this change and got both solutions rather
than just the second. Remove unused assignment.
2009-08-21 21:13:20 +00:00
Tiago Cunha
d07d18258b Sync OpenBSD patchset 284:
When moving up or down in copy mode, save the cursor position and size of the
last line with content (width != 0) and use it to determine if the cursor
should be at the end of the line. Fixes problem of the cursor always jumping to
the end of the line when scrolling past a blank line.
2009-08-21 21:12:07 +00:00
Tiago Cunha
a004fc3592 Sync OpenBSD patchset 283:
Fix grid_expand_line so it actually works when the required size is bigger than
2 * the current size.
2009-08-21 21:10:37 +00:00
Tiago Cunha
4b883524d8 Sync OpenBSD patchset 282:
A few trivial optimisations: no need to check for zero size if calling
buffer_ensure in buffer.c; expand grid lines by a greater increase than one
each time; and don't read UTF-8 data unless it actually needs to be checked
when overwriting a cell.
2009-08-21 21:09:13 +00:00
Tiago Cunha
15556ad0d6 Sync OpenBSD patchset 281:
Nuke unused variable.
2009-08-21 21:07:20 +00:00
Nicholas Marriott
27c5df22cf Move reading termios settings to before tty_open alters them, and expand the
comment.
2009-08-21 11:38:09 +00:00
Nicholas Marriott
03f4ab4bd5 Done. 2009-08-21 10:57:21 +00:00
Nicholas Marriott
f1c982608f VTIME and VMIN are only necessary in noncanonical mode, so Solaris reuses the
VEOF and VEOL indexes for them. ICANON is set by default, so don't bother to
set VTIME and VMIN.
2009-08-20 18:35:53 +00:00
Nicholas Marriott
c18e027ad5 Need this rubbish on Solaris for CMESG*. 2009-08-20 13:35:59 +00:00
Nicholas Marriott
dd9dd142c9 Add $Id$, nuke queue.h. 2009-08-20 12:54:08 +00:00
Nicholas Marriott
2f517111ef Solaris has no u_int32_t etc. 2009-08-20 12:49:18 +00:00
Nicholas Marriott
9311e4255e Didn't mean to commit this. 2009-08-20 12:39:21 +00:00
Nicholas Marriott
61c7bfc128 Also undef CTRL. 2009-08-20 12:38:37 +00:00
Nicholas Marriott
14eb6df45e Solaris defines some of these in termios.h so #ifndef them. 2009-08-20 12:27:58 +00:00
Nicholas Marriott
698e003fcd Solaris has no bzero(). 2009-08-20 12:25:17 +00:00
Tiago Cunha
cc2c061289 Sync OpenBSD patchset 280:
Handle the device attributes (DA) escape sequence.
2009-08-20 11:54:58 +00:00
Tiago Cunha
9d33b3f72a Sync OpenBSD patchset 279:
tweak previous;
2009-08-20 11:53:27 +00:00
Tiago Cunha
0027aa3d1e Sync OpenBSD patchset 278:
Don't read beyond the edge of the screen when searching (dies with debug
enabled).
2009-08-20 11:52:39 +00:00
Tiago Cunha
1292540bb5 Sync OpenBSD patchset 276:
Extend command-prompt with a -p option which is a comma-separated list of one
or more prompts to present in order.

The responses to the prompt are replaced in the template string: %% are
replaced in order, so the first prompt replaces the first %%, the second
replaces the second, and so on. In addition, %1 up to %9 are replaced with the
responses to the first the ninth prompts

The default template is "%1" so the response to the first prompt is processed
as a command.

Note that this changes the behaviour for %% so if there is only one prompt,
only the first %% will be replaced. Templates such as "neww -n '%%' 'ssh %%'"
should be changed to "neww -n '%1' 'ssh %1'".

From Tiago Cunha.
2009-08-20 11:51:20 +00:00
Tiago Cunha
4631c07483 Sync OpenBSD patchset 275:
Instead of just checking for an empty buffer, which may not be the case if
there is unconsumed data, save the previous size and use it instead. This means
that activity monitoring should work in this (unlikely) event.

Also remove a debugging statement that no longer seems necessary.
2009-08-20 11:48:01 +00:00
Tiago Cunha
d895d4a9f0 Sync OpenBSD patchset 274:
Whoops, getting the comparison the right way round is usually recommended.
2009-08-20 11:45:37 +00:00
Tiago Cunha
d3da62d53a Sync OpenBSD patchset 273:
Move another expensive options test to after a cheaper timer check/update.
2009-08-20 11:44:18 +00:00
Tiago Cunha
b644b17599 Sync OpenBSD patchset 272:
options_get_number() is relatively expensive and a check for dead panes happens
a lot more often than actually finding one, so instead of getting the option
for every check, get it for every dead window found.
2009-08-20 11:40:15 +00:00
Tiago Cunha
36475f80e9 Sync OpenBSD patchset 271:
Now that pane targets (-t) are supported, switch some commands to use them
where it makes sense: clock-mode, copy-mode, scroll-mode, send-keys,
send-prefix.
2009-08-20 11:37:46 +00:00
Tiago Cunha
52b02850ca Sync OpenBSD patchset 270:
Tag a few missed printf-like functions and fix a missing "%s".
2009-08-20 11:35:16 +00:00
Tiago Cunha
7ca3d7ac8e Do not include vis.h directly, since it's OS-dependent, due to OpenBSD
patchsets 268, and 269.
2009-08-20 11:33:13 +00:00
Tiago Cunha
3756fce553 Sync OpenBSD patchset 269:
Pass show-buffer output through vis(3) as well, and wrap it to the edge of the
terminal when used from the command line.
2009-08-20 11:30:24 +00:00
Tiago Cunha
9386f640a5 Sync OpenBSD patchset 268:
Change list-buffers to run the preview of the buffer through vis(1).
2009-08-20 11:28:05 +00:00
Tiago Cunha
bcfb4f2a07 Sync OpenBSD patchset 267:
Use the full screen width when printing output rather than one less.
2009-08-20 11:24:33 +00:00
Tiago Cunha
aa7c0f1ce8 Sync OpenBSD patchset 266:
Nuke unnecessary assignment.
2009-08-20 11:23:36 +00:00
Tiago Cunha
2a5f08c15a Sync OpenBSD patchset 265:
Add a "delete line" key when editing in the status line or the search up/down
prompt. C-u with emacs keys, d with vi.
2009-08-20 11:22:48 +00:00
Tiago Cunha
70fc085862 Sync OpenBSD patchset 264:
Add (naive) searching and goto line in copy mode. Searching is C-r and C-s with
emacs keys, / and ? with vi; n repeats the search again with either key
set. All searching wraps the top/bottom. Goto line is g for both emacs and vi.

The search prompts don't have full line editing, just simple append and delete
characters.

Also sort the mode keys list in tmux.1.
2009-08-20 11:20:24 +00:00
Nicholas Marriott
09cc530299 Solaris and AIX have no ttydefaults.h. 2009-08-20 05:34:58 +00:00
Nicholas Marriott
966818c23d Call tcsetattr(). Not tested. 2009-08-19 16:06:45 +00:00
Nicholas Marriott
7c9f827bfe In yet another triumph of stupidity over common sense, the glibc
sys/ttydefaults.h is just a copy of the file from *BSD, taking no account of
the fact that their OWN termios.h uses entirely different indexes into the
array.

I know ttydefaults.h is not meant to be portable, but you'd think it would be
obvious to anyone that no file is better than a broken one...
2009-08-19 15:57:54 +00:00
Nicholas Marriott
2a300c6661 Use cfsetispeed/cfsetospeed to set termios speed members. 2009-08-19 14:32:49 +00:00
Nicholas Marriott
53570b1505 Make this match OpenBSD. 2009-08-19 09:28:10 +00:00
Nicholas Marriott
11f0f812c5 Didn't mean to commit this stuff. 2009-08-19 09:04:48 +00:00
Nicholas Marriott
620402a833 This is a better fix for OS X stupidity. 2009-08-19 09:00:06 +00:00
Nicholas Marriott
3f7e2589cd OS X stupid poll fix. 2009-08-19 08:36:45 +00:00
Nicholas Marriott
ed26a1d3bb Update. 2009-08-18 16:21:25 +00:00
Nicholas Marriott
ae1debbc92 Example from Han Boetes. 2009-08-16 21:55:30 +00:00
Tiago Cunha
622e018570 vis(3) compat files were removed prematurely from {DragonFly,Free,Net}BSD. Add
them back, per SourceForge bug #2838408.
2009-08-16 19:48:17 +00:00
Tiago Cunha
a2a8518f74 Sync OpenBSD patchset 263:
Reset attributes as well as scroll region before poll(2) and add a big comment
explaining why.
2009-08-16 19:33:49 +00:00
Tiago Cunha
7182f6d799 Sync OpenBSD patchset 262:
Send SGR0 when initialising the screen. Fixes problems on terminals with BCE
(like putty) if the background colours is non-default when tmux starts. May
also fix problems when resuming a suspended tmux.
2009-08-16 19:31:37 +00:00
Tiago Cunha
646d6a929c Sync OpenBSD patchset 261:
Switch the prompt code to return an empty string when the user enters no
response and reserve NULL for an explicit cancel. Change all callbacks to treat
them the same so no functional change.

Also add cancel key bindings to emacs mode which were missing.
2009-08-16 19:29:24 +00:00
Tiago Cunha
6f9a2ee50a Sync OpenBSD patchset 260:
vi(1)-style half page scroll in copy and scroll modes. Move the vi full page
scroll key to C-b instead of C-u and use C-u/C-d for half page scrolling with
vi keys. In emacs mode, half page scrolling is bound to M-Up and M-Down.

Suggested by merdely (about a year ago :-)).
2009-08-16 19:26:49 +00:00
Tiago Cunha
98e9e09588 Sync OpenBSD patchset 259:
Scroll by two less than the number of lines in the screen, like emacs, rather
than by the entire screen, to make it easier to pull things out from under the
line indicator. Suggested by claudio.
2009-08-16 19:23:07 +00:00
Tiago Cunha
9541471f87 Sync OpenBSD patchset 258:
Disable mode-mouse (mouse in copy/choice mode) by default as it isn't very
useful at the moment and causes confusion.
2009-08-16 19:20:37 +00:00
Tiago Cunha
c1fee8793d Update. 2009-08-16 19:18:10 +00:00
Tiago Cunha
e61ee94e26 Sync OpenBSD patchset 257:
Add a base-index session option to specify the first index checked when looking
for an index for a new window.
2009-08-16 19:16:27 +00:00
Tiago Cunha
9116905b24 Sync OpenBSD patchset 256:
Allowing copy mode to scroll left and right is annoying, so limit it to the
real screen width. To indicate the cursor is at the end of the line rather than
the cell before, put a '$' in the last cell.

Also clear the selection when the terminal is resized to avoid tmux getting
confused.
2009-08-16 19:12:07 +00:00
Tiago Cunha
64950f4524 Sync OpenBSD patchset 255:
Rather than telling the client to exit in the function when creating a new
session detached, let the caller do it. Allows "tmux new -d \; attach" to work.
2009-08-16 19:07:40 +00:00
Tiago Cunha
8973af82c5 Include unistd.h due to OpenBSD patchset 254. At least on Linux, that's where
_POSIX_VDISABLE is defined.
2009-08-16 19:04:05 +00:00
Tiago Cunha
f415d43c3b Sync OpenBSD patchset 254:
When creating a new session from the command-line where there is an external
terminal, copy the termios(4) special characters and use them for new windows
created in the new session. Suggested by Theo.
2009-08-16 18:59:12 +00:00
Nicholas Marriott
8f9858ba2f Solaris has no strsep(3). 2009-08-16 16:15:53 +00:00
Tiago Cunha
ba42910595 Sync OpenBSD patchset 253:
Redraw the screen after resizing.
2009-08-14 21:33:42 +00:00
Tiago Cunha
78c789e1cb Sync OpenBSD patchset 252:
It was originally intended that scroll mode would show content that was
currently off-screen due to resize, but somewhere along the way this got
lost. Restore this behaviour to scroll mode by fixing screen_write_copy to read
up to the saved line length rather than the current screen width. Copy mode
remains unaltered for now.
2009-08-14 21:32:38 +00:00
Tiago Cunha
b5059bc8a4 Sync OpenBSD patchset 251:
If the client passes zero for the window size in the identify message (which it
can, for example on serial terminals), reset it to 80x25, same as for resize
messages. Problem reported by kettenis@.
2009-08-14 21:31:20 +00:00
Tiago Cunha
05fe69eb92 Sync OpenBSD patchset 250:
A tty context must not be modified as it may be reused to update multiple
clients, so make it const.

Also fix an actual modification which caused a hang when a session was
connected to multiple terminals at least one of which was missing ich/ich1.
2009-08-14 21:30:24 +00:00
Tiago Cunha
06b3f49c49 Sync OpenBSD patchset 249:
When started as the shell, __progname contains a leading -, so hardcode "tmux"
for socket path and log files, and strip it when working out the shell.
2009-08-14 21:28:00 +00:00
Tiago Cunha
1063e5d0e4 Sync OpenBSD patchset 248:
imsg closes the fd after sending, so dup() STDIN_FILENO before passing it to
the parent, otherwise TIOCGWINSZ will fail when the window is resized (that
could actually be moved into the server but this is more future-proof and
avoids breaking the protocol).
2009-08-14 21:26:07 +00:00
Tiago Cunha
7f77c395e3 Sync OpenBSD patchset 247:
Initialise log_fd to -1, prevents spurious disconnection of the client when it
ends up as fd 0 (likely if the server is started with "tmux start").

Also add some extra debugging messages to server.c.
2009-08-14 21:24:46 +00:00
Tiago Cunha
e2a18894b3 Sync OpenBSD patchset 246:
Have the client pass its stdin fd to the server when identifying itself and
have the server use that rather than reopening the tty. If the fd isn't given,
use the old behaviour (so no need for a version change).

This allows tmux to be used as the shell, so also change so that when working
out the command to execute if default-command is empty (the default), tmux will
try not execute itself.
2009-08-14 21:23:20 +00:00
Tiago Cunha
0714e41148 Sync OpenBSD patchset 245:
Add a TTY_OPENED flag and tidy a little.
2009-08-14 21:20:01 +00:00
Tiago Cunha
5cc971facd Sync OpenBSD patchset 244:
Drop the no_stop argument to tty_close and tty_free in favour of a flag in the
tty struct.
2009-08-14 21:17:54 +00:00
Tiago Cunha
b402cef338 Adjust imsg changes to the portable version due to OpenBSD patchset 243. 2009-08-14 21:13:48 +00:00
Tiago Cunha
a9b6bfdddd Sync OpenBSD patchset 243:
Switch tmux to use imsg. This is the last major change to make the
client-server protocol more resilient and make the protocol versioning work
properly. In future, the only things requiring a protocol version bump will be
changes in the message structs, and (when both client and server have this
change) mixing different versions should nicely report an error message.

As a side effect this also makes the code tidier, fixes a problem with the way
errors reported during server startup were handled, and supports fd passing
(which will be used in future).

Looked over by eric@, thanks.

Please note that mixing a client with this change with an older server or vice
versa may cause tmux to crash or hang - tmux should be completely exited before
upgrading.
2009-08-14 21:04:04 +00:00
Nicholas Marriott
a604dfbb97 +. 2009-08-13 22:39:22 +00:00
Nicholas Marriott
e9d170176d Add and remove some bits. 2009-08-13 22:36:20 +00:00
Nicholas Marriott
304296972b Sync from OpenBSD:
Add flags for 1+2 and 2 arguments to the generic target code, use it for
cmd-set-environment/option/window-option and remove the generic options
parsing.
2009-08-11 14:42:59 +00:00
Nicholas Marriott
d0eae2cbfd +. 2009-08-11 10:09:32 +00:00
Nicholas Marriott
4d90ce7b40 Update. 2009-08-11 10:06:27 +00:00
Tiago Cunha
48ede1a00a Sync OpenBSD patchset 241:
No arguments are the same as new-session and this requires the environment to
be sent, so set that flag too when argc == 0.
2009-08-10 21:43:34 +00:00
Tiago Cunha
c261ae32d2 Sync OpenBSD patchset 240:
Reset the attributes after drawing all or part of the screen, and reset the
region before poll(2). This reduces (but does not eliminate) the chance of the
attributes not being normal if tmux is disconnected without warning (ssh ~.,
reboot from inside, etc).
2009-08-10 21:41:35 +00:00
Tiago Cunha
e8ea3ccd58 Sync OpenBSD patchset 239:
Use the right source and destination lines in grid_duplicate_lines.
2009-08-10 21:40:21 +00:00
Tiago Cunha
7bcd7c2752 Sync OpenBSD patchset 238:
some minor tweaks; ok nicm
2009-08-10 21:39:15 +00:00
Nicholas Marriott
7dbabe84e4 Missing options are not illegal. 2009-08-09 18:35:38 +00:00
Tiago Cunha
3dadb349eb Sync OpenBSD patchset 237:
zap trailing whitespace;
2009-08-09 18:02:36 +00:00
Tiago Cunha
e43ce15736 Sync OpenBSD patchset 236:
Minor language tweaks, change which key bindings are summarised.
2009-08-09 18:02:02 +00:00
Tiago Cunha
6297285527 Nuke dead variable here as well, in accordance to OpenBSD patchset 235. 2009-08-09 18:00:45 +00:00
Tiago Cunha
2c863b9f2c Sync OpenBSD patchset 235:
Nuke a dead variable found with clang and an unused declaration with lint.
2009-08-09 17:57:39 +00:00
Tiago Cunha
221ce5afb3 Sync OpenBSD patchset 234:
Move the key bindings section to near the start, mention attach/detach in the
first section, and another couple of tweaks. Based on a diff from Theo.
2009-08-09 17:55:59 +00:00
Tiago Cunha
1297c39a31 Sync OpenBSD patchset 233:
Don't leak in the (rare) case of an invalid command at the end of a file not
terminated by a \n.
2009-08-09 17:53:50 +00:00
Tiago Cunha
4c944910fa Sync OpenBSD patchset 232:
Use a temporary variable for strdup of const char *.
2009-08-09 17:52:54 +00:00
Tiago Cunha
deac1fc188 Update. 2009-08-09 17:51:19 +00:00
Tiago Cunha
29b1b2fb5e Sync OpenBSD patchset 231:
Infrastructure and commands to manage the environment for processes started
within tmux.

There is a global environment, copied from the external environment when the
server is started and each session has an (initially empty) session
environment which overrides it.

New commands set-environment and show-environment manipulate or display the
environments.

A new session option, update-environment, is a space-separated list of
variables which are updated from the external environment into the session
environment every time a new session is created - the default is DISPLAY.
2009-08-09 17:48:55 +00:00
Tiago Cunha
af3db9a4fe Sync OpenBSD patchset 230:
Tidy function a little by using a temporary variable.
2009-08-09 17:43:00 +00:00
Tiago Cunha
a26817d604 Update. 2009-08-09 17:41:46 +00:00
Tiago Cunha
167a8c9edc Sync OpenBSD patchset 229:
Options to set the colours and attributes for status-left/-right. From Thomas
Adam, thanks.
2009-08-09 17:40:17 +00:00
Tiago Cunha
97eb537f38 Sync OpenBSD patchset 227:
Add a flags member to the grid_line struct and use it to differentiate lines
wrapped at the screen edge from those terminated by a newline. Then use this
when copying to combine wrapped lines together into one.
2009-08-09 17:32:06 +00:00
Tiago Cunha
37b0bcd7c1 Sync OpenBSD patchset 226:
Change the way the grid is stored, previously it was:

- a two-dimensional array of cells;
- a two-dimensional array of utf8 data;
- an array of line lengths.

Now it is a single array of a new struct grid_line each of which represents a
line and contains the length and an array of cells and an array of utf8 data.

This will make it easier to add additional per-line members, such as flags.
2009-08-09 17:28:24 +00:00
Tiago Cunha
5b56ea1816 Sync OpenBSD patchset 225:
If there is an error in the configuration file, don't just exit(1) as this can
cause the client to hang. Instead, send the error message, then mark the client
as bad and start a normal shutdown so the server exits once the error is
written.

This also allows some code duplicating daemon(3) to be trimmed and logging to
begin earlier.

Prompted by Theo noticing the behaviour on error wasn't documented.
2009-08-09 17:19:18 +00:00
Tiago Cunha
602aae7839 Sync OpenBSD patchset 224:
Move introduction section up into description. From jmc.
2009-08-09 16:59:35 +00:00
Tiago Cunha
05eb4ece44 Sync OpenBSD patchset 223:
Using the alternative screen (smcup/rmcup) should also preserve the current
colours and attributes. Found thanks to a report from Taylor Venable.

While here also nuke a couple of extra blank lines.
2009-08-09 16:57:49 +00:00
Tiago Cunha
5840c3e13a Sync OpenBSD patchset 222:
tweak INTRODUCTION; from nicm and myself (jmc)
2009-08-09 16:54:46 +00:00
Tiago Cunha
cd5294dfb4 Sync OpenBSD patchset 221:
Clear the codes array earlier as tty_term_free could be called on error.
2009-08-09 16:52:06 +00:00
Tiago Cunha
88b83be07b Sync OpenBSD patchset 220:
If colours are not supported by the terminal, try to emulate a coloured
background by setting or clearing the reverse attribute.

This makes a few applications which don't use the reverse attribute themselves
a little happier, and allows the status, message and mode options to have
default attributes and fg/bg options that work as expected when set as reverse.
2009-08-09 16:50:57 +00:00
Tiago Cunha
65a28912eb Sync OpenBSD patchset 219:
Add a -a flag to set-option and set-window-option to append to an existing
string value, useful for terminal-overrides.
2009-08-09 16:48:34 +00:00
Tiago Cunha
d8a2ceea43 Sync OpenBSD patchset 217:
Show the bell/activity/current status and the window title in the choice list.
2009-08-09 16:41:17 +00:00
Tiago Cunha
c32ca6a8e6 Sync OpenBSD patchset 216:
Check for "UTF8" as well as "UTF-8" in LANG etc as it seems this may also
appear.
2009-08-09 16:39:40 +00:00
Tiago Cunha
c9f55c1063 Make similar (untested) changes to the OS-dependent code for FreeBSD, and
NetBSD in accordance to OpenBSD patchset 214.
2009-08-09 16:37:05 +00:00
Tiago Cunha
1127a290f4 Sync OpenBSD patchset 214:
Split the comparison into a function to make this code smaller and more
understandable.
2009-08-09 16:08:12 +00:00
Tiago Cunha
bd5cf2e809 Update. 2009-08-09 15:58:09 +00:00
Tiago Cunha
9002e60adf Sync OpenBSD patchset 213:
Don't try to free old string values (and crash) when they are overridden unless
they were actually found in the source terminal description. Reported by jmc.
2009-08-09 15:57:13 +00:00
Tiago Cunha
bd2fe4ce9b Make it build on the remaining operating systems, due to the changes
introduced on OpenBSD patchset 211.
2009-08-09 15:53:02 +00:00
Tiago Cunha
e6d5633671 DragonFlyBSD, FreeBSD, and NetBSD do not need vis.c. 2009-08-09 15:48:03 +00:00
Tiago Cunha
e098f7b285 Add unvis(3) compat stuff. 2009-08-09 15:39:41 +00:00
Tiago Cunha
3deb17e841 Do not include vis.h directly, since it's OS-dependent. 2009-08-09 15:29:54 +00:00
Tiago Cunha
15f6a41a75 Sync OpenBSD patchset 211:
Add a terminal-overrides session option allowing individual terminfo(5) entries
to be overridden. The 88col/256col checks are now moved into the default
setting and out of the code.

Also remove a couple of old workarounds for xterm and rxvt which are no longer
necessary (tmux can emulate them if missing).
2009-08-09 15:26:24 +00:00
Tiago Cunha
75b6736cf4 Sync OpenBSD patchset 210:
Fix checking of setupterm(3) error codes. While there include the
name of the terminal type causing the error where relevant. ok nicm@.
2009-08-09 12:06:25 +00:00
Nicholas Marriott
80196c9abc Fix typo and add ref to infocmp. 2009-08-08 20:46:26 +00:00
Nicholas Marriott
becdf220fd Clarify 256 colours entries from Chris Jones, tweaked by me. 2009-08-08 20:42:42 +00:00
Nicholas Marriott
dcde77cd09 Update. 2009-08-08 16:03:09 +00:00
Nicholas Marriott
f03dd8d216 This file is not kept up to date and too many people are using it as-is then
finding tmux key bindings missing. Trim it down and make it clear this is an
example only.
2009-08-07 12:09:50 +00:00
Nicholas Marriott
a5d55ba16d Sync up tmux.1 from OpenBSD. 2009-08-06 19:25:44 +00:00
Nicholas Marriott
2936f4f32c tmux no longers sends init strings so this is no longer relevant. 2009-08-06 12:22:50 +00:00
Nicholas Marriott
e2686d8819 +IRC channel. 2009-08-05 16:39:28 +00:00
Nicholas Marriott
b2606c0421 Correct usage of termcap. 2009-08-05 16:29:50 +00:00
Nicholas Marriott
e3e0d70c0e +PuTTY ACS from Mike Putnam. 2009-08-05 14:56:58 +00:00
Nicholas Marriott
f42a0475e4 Tweak FAQ to mention default-terminal. 2009-08-05 14:42:08 +00:00
Tiago Cunha
a834d037bc Sync OpenBSD patchset 209:
Pass the ACS border characters through tty_get_acs so they appear correctly on
terminals which don't use the standard set.
2009-07-31 20:35:21 +00:00
Tiago Cunha
cccd072ed1 Sync OpenBSD patchset 208:
Don't leak when rollling buffers off when the paste buffer limit is reached.
2009-07-31 20:33:49 +00:00
Nicholas Marriott
5f0e688b50 Add some lines. 2009-07-31 10:58:51 +00:00
Nicholas Marriott
ec8930c144 Part of last commit, remove -lcurses. 2009-07-31 10:45:22 +00:00
Nicholas Marriott
3e46bcec93 On SUSE Linux compatibility is something that only happens to other people, so
on Linux use -lncurses instead of -lcurses.

Also use -lncurses on NetBSD because they are only now realising that
supporting the 20-year-old terminfo API in their libcurses might be nice, and
so far none of the releases do.
2009-07-31 10:44:03 +00:00
Nicholas Marriott
5d13704e04 Some Linuxes/gcc versions hide LLONG_MAX/MIN unless the compiler is told to use
C99, so use -std=c99 on Linux.
2009-07-31 10:30:40 +00:00
Nicholas Marriott
52f8578984 Some stuff that is done. 2009-07-30 21:55:16 +00:00
Tiago Cunha
09c6432854 Sync OpenBSD patchset 207:
Plug some memory leaks.
2009-07-30 21:14:04 +00:00
Tiago Cunha
796bfbd7af Update. 2009-07-30 21:11:10 +00:00
Tiago Cunha
56dd5dfff4 Sync OpenBSD patchset 206:
Don't babysit people and let them try to load /dev/zero or (more useful)
/dev/null if they want.
2009-07-30 21:07:23 +00:00
Tiago Cunha
3eb77bf53f Sync OpenBSD patchset 205:
Remove some dead code found by clang.
2009-07-30 21:04:40 +00:00
Tiago Cunha
89826983eb Sync OpenBSD patchset 204:
tweak previous;
2009-07-30 21:02:35 +00:00
Tiago Cunha
697051d1fd Sync OpenBSD patchset 203:
Similar changes for server_msg_dispatch: use a switch instead of a lookup
table and merge smaller functions inline.
2009-07-30 21:01:01 +00:00
Tiago Cunha
67266dc25c Sync OpenBSD patchset 202:
There aren't many client message types or code to handle them so get rid of
the lookup table and use a switch, merge the tiny handler functions into it,
and move the whole lot to client.c.

Also change client_msg_dispatch to consume as many messages as possible and
move the call to it to the right place so it checks for signals afterwards.

Prompted by suggestions from eric@.
2009-07-30 20:57:39 +00:00
Tiago Cunha
817e93ac94 Sync OpenBSD patchset 201:
Tell the server when the client gets SIGTERM so it can clean up the terminal
properly, rather than just exiting.
2009-07-30 20:50:10 +00:00
Tiago Cunha
1650b8552f Sync OpenBSD patchset 200:
Merge pane number into the target specification for pane commands. Instead of
using -p index, a target pane is now addressed with the normal -t window form
but suffixed with a period and a pane index, for example :0.2 or
mysess:mywin.1. An unadorned number such as -t 1 is tried as a pane index in
the current window, if that fails the same rules are followed as for a target
window and the current pane in that window used.

As a side-effect this now means that swap-pane can swap panes between
different windows.

Note that this changes the syntax of the break-pane, clear-history, kill-pane,
resize-pane, select-pane and swap-pane commands.
2009-07-30 20:45:20 +00:00
Tiago Cunha
ec1396c9ee Sync OpenBSD patchset 199:
new sentence, new line;
2009-07-30 20:33:29 +00:00
Tiago Cunha
ec3dba01b2 Sync OpenBSD patchset 198:
Add a mode-mouse option to prevent tmux taking over the mouse in choice or
copy modes.
2009-07-30 20:32:05 +00:00
Tiago Cunha
8ce1f0b047 Sync OpenBSD patchset 197:
Add an additional heuristic to work out the current session when run from the
command line. The name of all slave ptys in the server is known, so if the
client was run on a tty, look for any sessions containing that tty and use the
most recently created.

This is more reliable than looking at $TMUX if windows have been moved or
linked between sessions.
2009-07-30 20:26:20 +00:00
Tiago Cunha
6fbfcfc0d7 Sync OpenBSD patchset 196:
Rename struct hdrtype to msgtype which is a better name and can be used even
when struct hdr disappears.
2009-07-30 20:21:55 +00:00
Tiago Cunha
5a9b7b230c Sync OpenBSD patchset 195:
Taking account of the "s, 22 not 24 is the maximum length of #T in
status-right to prevent the date being cut off.
2009-07-30 20:17:25 +00:00
Tiago Cunha
522fc94d12 Sync OpenBSD patchset 194:
Final pieces of mode key rebinding: bind-key and unbind-key now accept a -t
argument to modify a table.
2009-07-28 23:19:06 +00:00
Tiago Cunha
deaba44835 Sync OpenBSD patchset 193:
Accept and print "Enter" and "Escape" for keys rather than C-m and C-[.
2009-07-28 23:13:00 +00:00
Tiago Cunha
de7483a114 Sync OpenBSD patchset 192:
Next step towards customisable mode keys: build each default table of keys
into a named tree on start and use that for lookups. Also add command to string
translation tables and modify list-keys to show the mode key bindings (new
-t argument).
2009-07-28 23:11:18 +00:00
Tiago Cunha
d9dcc5ed44 Sync OpenBSD patchset 191:
If select-layout is not given an argument, reapply the last layout used in the
window, if any.
2009-07-28 23:04:29 +00:00
Tiago Cunha
1c73e75982 Sync OpenBSD patchset 190:
Remove an unused entry in the mode keys command enum and rename
MODEKEYCOPY_QUIT to _CANCEL to match the others.
2009-07-28 22:58:20 +00:00
Tiago Cunha
920b9c5872 Sync OpenBSD patchset 189:
Change mode key bindings from big switches into a set of tables. Rather than
lumping them all together, split editing keys from those used in choice/more
mode and those for copy/scroll mode.

Tidier and clearer, and the first step towards customisable mode keys.
2009-07-28 22:55:59 +00:00
Tiago Cunha
1880b83c37 Sync OpenBSD patchset 188:
Get rid of empty mode_key_free function.
2009-07-28 22:49:26 +00:00
Tiago Cunha
46cb0de347 Sync OpenBSD patchset 187:
Add a key to delete to end of line at the prompt (^K in emacs mode, C/D in
vi).

From Kalle Olavi Niemitalo.
2009-07-28 22:44:38 +00:00
Tiago Cunha
7562781c9d Sync OpenBSD patchset 186:
Draw UTF-8 characters under the selection correctly.
2009-07-28 22:41:38 +00:00
Tiago Cunha
2a146852ef Sync OpenBSD patchset 185:
Change previous-word behavior to move to the beginning of the word (matches
emacs and vi). From Kalle Olavi Niemitalo.
2009-07-28 22:39:29 +00:00
Tiago Cunha
361801aaaa Sync OpenBSD patchset 184:
Detect backspace by looking at termios VERASE and translate it into \177
(which matches screen's behaviour if not its termcap/terminfo entry). The
terminfo kbs cap is often wrong or missing so it can't be used, and just
assuming \177 may be wrong.
2009-07-28 22:37:02 +00:00
Tiago Cunha
2aa4d47312 Sync OpenBSD patchset 183:
Calculate the space available for the prompt buffer and the cursor position
correctly, and make it work when the screen is not wide enough.

Noticed by Kalle Olavi Niemitalo.
2009-07-28 22:32:15 +00:00
Tiago Cunha
2dda197980 Make similar changes to the OS-dependent code for FreeBSD, and NetBSD in
accordance to OpenBSD patchset 182.
2009-07-28 22:28:11 +00:00
Tiago Cunha
6043d9cf89 Sync OpenBSD patchset 182:
Go to the next if the current best process is replaced, don't keep comparing
it with itself. Also fix process name comparison.
2009-07-28 22:26:13 +00:00
Tiago Cunha
a3fc9dee32 Add PASS_MAX for glibc. 2009-07-28 22:17:10 +00:00
Tiago Cunha
d637cb33da Sync OpenBSD patchset 181:
Make all messages sent between the client and server fixed size.

This is the first of two changes to make the protocol more resilient and less
sensitive to other changes in the code, particularly with commands. The client
now packs argv into a buffer and sends it to the server for parsing, rather
than doing it itself and sending the parsed command data.

As a side-effect this also removes a lot of now-unused command marshalling
code.

Mixing a server without this change and a client with or vice versa will cause
tmux to hang or crash, please ensure that tmux is entirely killed before
upgrading.
2009-07-28 22:12:16 +00:00
Nicholas Marriott
f5c0695605 This stuff is done. 2009-07-28 18:51:10 +00:00
Nicholas Marriott
21130b0c49 Add a couple of items, and wrap lines. 2009-07-26 15:58:40 +00:00
Tiago Cunha
a5ad186547 Sync OpenBSD patchset 180:
Set the active pane when respawning a window - fixes problems when respawning
a window with multiple panes.
2009-07-25 09:04:54 +00:00
Tiago Cunha
5e7a48a865 Sync OpenBSD patchset 179:
Use the full range of ACS line drawing characters to draw pane borders,
including intersections.
2009-07-25 09:03:33 +00:00
Tiago Cunha
2386fa2355 Sync OpenBSD patchset 178:
cmd_find_index should return -2 on error.
2009-07-25 08:59:38 +00:00
Tiago Cunha
723f363c07 Sync OpenBSD patchset 177:
Simplify screen redrawing by drawing the border and background together rather
than border separately, and consolidating all the drawing characters into one
string.
2009-07-25 08:58:19 +00:00
Tiago Cunha
a98dbb67b9 Sync OpenBSD patchset 176:
Accept lowercase c- and m- prefix as well as C- and M-.
2009-07-25 08:53:48 +00:00
Tiago Cunha
28cf7dc39e Sync OpenBSD patchset 175:
Permit commands to be bound to key presses without the prefix key first. The
new -n flag to bind-key and unbind-key sets or removes these bindings, and
list-key shows them in []s.
2009-07-25 08:52:04 +00:00
Tiago Cunha
744ccb7cc9 Sync OpenBSD patchset 174:
up-pane and down-pane no longer auto-repeat; update the description of
repeat-time accordingly. ok nicm@

if you prefer old behaviour;

bind -r Up up-pane
bind -r Down down-pane
2009-07-25 08:39:39 +00:00
Nicholas Marriott
db584544f4 Add some more bits. 2009-07-25 00:12:24 +00:00
Nicholas Marriott
f4718dcdf2 +another couple of items. 2009-07-25 00:00:33 +00:00
Nicholas Marriott
4ec1b5d4e2 +. 2009-07-24 22:59:06 +00:00
Nicholas Marriott
6e0626d3af Screenshot with more ACS love. 2009-07-24 19:30:51 +00:00
Nicholas Marriott
dd51dd14af Add. 2009-07-24 19:30:05 +00:00
Tiago Cunha
7cd412dc57 Sync OpenBSD patchset 173:
None of the server message functions return anything but 0, so make them all
void.

Also remove a leftover variable in client.c.
2009-07-23 23:47:23 +00:00
Tiago Cunha
1870b96578 Sync OpenBSD patchset 172:
Tidy client message return slightly: convert flags into an enum, and merge
error string into struct client_ctx as well.
2009-07-23 23:42:59 +00:00
Tiago Cunha
2e4df706f6 Sync OpenBSD patchset 171:
Redraw after starting selection to correctly remove any existing selection.
2009-07-23 23:37:14 +00:00
Tiago Cunha
1141acfd4c Revert previous per OpenBSD's patchset 170. 2009-07-23 23:35:10 +00:00
Tiago Cunha
53c1b32e02 Sync OpenBSD patchset 169:
C-d is delete as well in emacs mode.
2009-07-23 23:29:53 +00:00
Tiago Cunha
f2451c1e29 Sync OpenBSD patchset 168:
Both of cmdclient and curclient CAN be NULL - if the command is executed from
the configuration file. In this case, attach-session can't do much, and
new-session should just assume -d.
2009-07-23 13:25:27 +00:00
Tiago Cunha
a551ff2b1b Sync OpenBSD patchset 167:
If there is a current session, use its default path and working directory for
the initial window when creating a new session.
2009-07-23 13:19:12 +00:00
Tiago Cunha
7174c76bf0 Sync OpenBSD patchset 166:
Pass a set of flags into client_init rather than just a start_server
variable. Only one flag now but more to come later.
2009-07-23 13:15:41 +00:00
Tiago Cunha
6708ad19c5 Sync OpenBSD patchset 165:
window_add_pane cannot fail, so remove the unused cause argument and don't
bother to check for a NULL return.
2009-07-23 13:10:38 +00:00
Tiago Cunha
fb0301f8b8 Sync OpenBSD patchset 164:
Tidy the target parsing code a bit and correct the behaviour so that as before
a string with no colon as a target window is first looked up as a window then
as a session, noted by Iain Morgan.

Also attempt to clarify the description of the target specification in the man
page.
2009-07-23 13:06:31 +00:00
Tiago Cunha
c84145751a Sync OpenBSD patchset 164:
tty_write is relatively short and the only function left in tty-write.c so
move it into tty.c.
2009-07-23 12:57:45 +00:00
Tiago Cunha
b72f9bea43 Sync OpenBSD patchset 162:
More tty code tidying: move the saved cursor/region position (from before the
screen was updated) out of struct screen and into struct tty_ctx.
2009-07-23 12:48:18 +00:00
Tiago Cunha
9c6fa90857 Sync OpenBSD patchset 160:
enum tty_cmd is only used as an index into the array of command function
pointers, so remove it and use the function pointers directly to represent
themselves.
2009-07-23 12:38:01 +00:00
Nicholas Marriott
83d1f2b480 Some more TODO list items that are done. 2009-07-22 21:10:45 +00:00
Nicholas Marriott
19aae6dbd8 Add a couple of notes so I don't forget. 2009-07-22 21:02:07 +00:00
Tiago Cunha
aa3a262caa Update. 2009-07-22 20:42:56 +00:00
Tiago Cunha
b6afa30c39 Sync OpenBSD patchset 159:
There are relatively few arguments to tty_cmd_* functions now, so tidy them up
by using a struct rather than hiding everything with varargs.
2009-07-22 18:08:56 +00:00
Tiago Cunha
75a44d856e Sync OpenBSD patchset 158:
tty_cmd_raw is only used once, for raw UTF-8 output, so rename it to
tty_cmd_utf8character and eliminate the size argument.
2009-07-22 17:58:42 +00:00
Tiago Cunha
41207e4861 Sync OpenBSD patchset 157:
Adjust field width to fit longest key when listing.
2009-07-22 17:53:27 +00:00
Tiago Cunha
acdef09e00 Sync OpenBSD patchset 156:
Remove leftover debug logging of password.
2009-07-22 17:49:09 +00:00
Tiago Cunha
d29b57f597 Sync OpenBSD patchset 155:
Make some functions which return unused values void (mostly found by lint) and
tweak a redundant expression in window_pane_set_mode.
2009-07-22 17:46:53 +00:00
Tiago Cunha
0237e1dafd Sync OpenBSD patchset 154:
Nix a few unused attributes on arguments which are no longer unused.
2009-07-22 17:38:11 +00:00
Tiago Cunha
a92993228f Change GRID_DEBUG to use log_debug2 since log_debug3 was removed. 2009-07-22 17:33:02 +00:00
Tiago Cunha
6a97901691 Sync OpenBSD patchset 153:
Remove a couple of unused functions and fix a type ("FALLTHOUGH"), found by
lint.
2009-07-22 17:31:20 +00:00
Tiago Cunha
39aa8b32b1 Restore $Id$. 2009-07-22 16:55:22 +00:00
Tiago Cunha
1bf524c1b7 Sync OpenBSD patchset 152:
__progname is not const, pointed out by deraadt.

And, as a consequence change its declaration for operating systems which
don't provide __progname as well.
2009-07-22 16:53:30 +00:00
Tiago Cunha
a734488a4b Sync OpenBSD patchset 151:
Tidy up keys: use an enum for the key codes, and remove the macros which just
wrap flag sets/clears/tests.
2009-07-22 16:24:59 +00:00
Nicholas Marriott
94e2339842 OpenSolaris ioctl(TIOCSWINSZ) appears to be broken and can return EINVAL here
despite sx, sy and fd being fine (an fcntl on the fd succeeds). No problems on
other platforms so ignore the error under #ifdef __sun__.
2009-07-22 12:42:57 +00:00
Tiago Cunha
5263b3f61e Sync OpenBSD patchset 150:
Now that #P could be in the status line, flag it for redraw when the active
pane changes.
2009-07-21 16:27:41 +00:00
Nicholas Marriott
962b9c6548 Include .depend in GNUmakefile since GNU make does not include it
automatically.

Also remove .depend from clean target and add a clean-depend target.
2009-07-21 13:51:30 +00:00
Nicholas Marriott
48c36d628a No paths.h in cmd.c; add _PATH_DEV for Solaris. 2009-07-21 13:07:50 +00:00
Nicholas Marriott
e2a80151ae Update. 2009-07-21 13:07:14 +00:00
Tiago Cunha
2572c7139b Sync OpenBSD patchset 149:
Tweak unbind-key language very slightly.
2009-07-20 17:08:48 +00:00
Tiago Cunha
e7cda4f363 Update. 2009-07-20 17:06:13 +00:00
Tiago Cunha
54c6848d75 Sync OpenBSD patchset 148:
Display the number of failed password attempts (if any) when the server is
locked. From Tom Doherty.
2009-07-20 16:07:23 +00:00
Tiago Cunha
9a07e8f372 Sync OpenBSD patchset 147:
Add a status-justify option to allow the window list in the status line to be
positioned at the left, centre, or right.
2009-07-20 16:01:07 +00:00
Tiago Cunha
e8957009c7 Sync OpenBSD patchset 146:
New options, window-status-current-{fg,bg,attr}, to set the fg, bg and
attributes with which the current window is shown in the status line. From
Johan Friis, thanks.
2009-07-20 15:57:05 +00:00
Tiago Cunha
62017452e9 Sync OpenBSD patchset 145:
Kill some dead stores and fix a null pointer deref, found by clang.
2009-07-20 15:51:32 +00:00
Tiago Cunha
16f424d25d Sync OpenBSD patchset 144:
Move the offsets as well when swapping panes.
2009-07-20 15:48:54 +00:00
Tiago Cunha
95d593dd51 Sync OpenBSD patchset 143:
tweak previous;
2009-07-20 15:46:55 +00:00
Tiago Cunha
545893df73 Sync OpenBSD patchset 142:
Each window now has a tree of layout cells associated with it. In this tree,
each node is either a horizontal or vertical cell containing a list of other
cells running from left-to-right or top-to-bottom, or a leaf cell which is
associated with a pane.

The major functional changes are:

- panes may now be split arbitrarily both horizontally (splitw -h, C-b %) and
  vertically (splitw -v, C-b ");
- panes may be resized both horizontally and vertically (resizep -L/-R/-U/-D,
  bound to C-b left/right/up/down and C-b M-left/right/up/down);
- layouts are now applied and then may be modified by resizing or splitting
  panes, rather than being fixed and reapplied when the window is resized or
  panes are added;
- manual-vertical layout is no longer necessary, and active-only layout is gone
  (but may return in future);
- the main-pane layouts now reduce the size of the main pane to fit all panes
  if possible.

Thanks to all who tested.
2009-07-20 15:42:05 +00:00
Nicholas Marriott
680f2098f1 With gcc4, turn off unnecessart pointer sign warnings. 2009-07-20 05:40:13 +00:00
Tiago Cunha
376c808b50 Add three new session options: visual-activity, visual-bell, visual-content.
If these are enabled (and the monitor-activity, bell-action and monitor-content
options are configurated appropriately), when activity, a bell, or content is
detected, a message is shown.

Also tidy up the bell/activity/content code in server.c slightly and fix a
couple of errors.
2009-07-19 14:35:56 +00:00
Nicholas Marriott
4cf6396e4c Change a couple of screenshots which had screen in them now I've got rid of
screen on that box too :-).
2009-07-19 13:52:51 +00:00
Tiago Cunha
17170f5d6e Add a -k flag to unlink-window which makes it behave the same as the old
kill-window - if a window is linked into only one session it unlinked and
destroyed.
2009-07-19 00:39:37 +00:00
Nicholas Marriott
19cb1fb592 Make it so using kill-pane to destroy the last pane in a window destroys the
window instead of being an error.
2009-07-18 11:07:14 +00:00
Nicholas Marriott
c30fbd1d8d When resizing a screen smaller in alternate screen mode, all the lines needed
could be consumed by deleting from the bottom, leaving none to be removed from
the top. In this case, don't call grid_view_delete_lines with ny of 0 as this
is incorrect and causes a bounds check to fatal error if built with -DDEBUG.
2009-07-18 11:06:35 +00:00
Nicholas Marriott
6bc9ee3420 Tidy up new-session and attach-session and change them to work from inside
tmux, switching the current client to the new or requested session.
2009-07-18 11:06:09 +00:00
Nicholas Marriott
4192449112 Remove a duplicate key binding, and turn off autorepeat for up/down as it is
kind of annoying by default.
2009-07-18 11:05:45 +00:00
Nicholas Marriott
f1efd6b4e7 If -u is specified or UTF-8 is otherwise detected when the server is started,
enable the utf8 and status-utf8 optons. While here, note in the man page that
the server is started with the first session and exits when none remain.
2009-07-18 11:05:13 +00:00
Nicholas Marriott
21cfef45d6 When resizing a screen smaller in alternate screen mode, all the lines needed
could be consumed by deleting from the bottom, leaving none to be removed from
the top. In this case, don't call grid_view_delete_lines with ny of 0 as this
is incorrect and causes a bounds check to fatal error if built with -DDEBUG.
2009-07-17 18:35:55 +00:00
Tiago Cunha
ae7dda10ce - New command display-message (alias display) to display a message in the
status line (bound to "i" by default).
- Add support for including the window index, pane index, and window name
  in status-left, or status-right.
- Bump protocol version.
2009-07-17 18:32:54 +00:00
Nicholas Marriott
646632de1d Update TODO. 2009-07-17 18:05:06 +00:00
Nicholas Marriott
770ea563ee Changed the wrong thing here. 2009-07-17 15:56:46 +00:00
Nicholas Marriott
946affe60d Stupid cvsps. 2009-07-17 12:35:01 +00:00
Nicholas Marriott
89543e999d A similar for fix for window_choose: don't rely on the callback always being
called to free data, have a separate free callback and call it from the mode
cleanup code.
2009-07-17 12:12:54 +00:00
Nicholas Marriott
fc17ce0150 Oops, it is always a good idea to get arguments the right way round. 2009-07-17 09:28:27 +00:00
Nicholas Marriott
441c118b63 Memory could be leaked if a second prompt or message appeared while another was
still present, so add a separate prompt free callback and make the _clear
function responsible for calling it if necessary (rather than the individual
2009-07-17 09:26:21 +00:00
Nicholas Marriott
ac55534055 Remove some duplicate code that was causing the status line to be redrawn even
when it hadn't changed.
2009-07-17 07:46:08 +00:00
Nicholas Marriott
821de39b27 Fix arguments to switch-client. 2009-07-17 07:45:42 +00:00
Nicholas Marriott
ede2dd2d3a Typo in grid_duplicate_lines (sy for dy) causing it to write into the wrong
place when copying UTF-8 data. Found by Dan Colish.
2009-07-17 07:45:08 +00:00
Nicholas Marriott
08d32a1522 Update TODO. 2009-07-16 07:35:41 +00:00
Nicholas Marriott
d956ed0760 Typo in grid_duplicate_lines (sy for dy) causing it to write into the wrong
place when copying UTF-8 data. Found by Dan Colish.
2009-07-16 07:35:35 +00:00
Nicholas Marriott
6fe25a08d7 Improved NetBSD current-process detection from Roy Marples. 2009-07-15 17:53:15 +00:00
Nicholas Marriott
222b8e6743 Make status_message_set a variadic printf-like function. No functional change -
helpful for a couple of things coming soon.
2009-07-15 17:50:11 +00:00
Nicholas Marriott
d6908dd9c2 Return -1 not NULL on error, pointed out by Roy Marples. 2009-07-15 17:46:09 +00:00
Nicholas Marriott
ac2ab6501d Add a -k flag to unlink-window which makes it behave the same as the old
kill-window - if a window is linked into only one session it unlinked and
destroyed.
2009-07-15 17:45:29 +00:00
Nicholas Marriott
8bfbc8c61d The man page says that kill-window removes the window entirely, unlinking it
from any sessions. In fact the implementation only affected the current
session, making it the same as unlink-window but destroying the window if it
was linked into only one session (unlinkw gives an error). Change the behaviour
to match what it documented and was originally intended.
2009-07-15 17:45:09 +00:00
Nicholas Marriott
ff90170738 Having to update NSETOPTION/NSETWINDOWOPTION when adding new options is a bit
annoying and it is only use for iterating, so use a sentinel to mark the end of
each array instead. Different fix for a problem pointed out by Kalle Olavi
Niemitalo.
2009-07-15 17:44:47 +00:00
Nicholas Marriott
6ebb1df8fe Add main-pane-height to the options list (was missed before). 2009-07-15 17:44:25 +00:00
Nicholas Marriott
ff500b46c9 For some reason when clearing status/message it was redrawing the entire client
not just the status line. Changing this also revealed the check for the status
line was incorrect when drawing the pane.
2009-07-15 17:44:06 +00:00
Nicholas Marriott
72d56bd614 Instead of faking up a status line in status_redraw, use the same code to
redraw it as to draw the entire screen, just skip all lines but the last.
2009-07-15 17:43:45 +00:00
Nicholas Marriott
ad1945c278 Don't accept input to a window if it not visible. 2009-07-15 17:43:21 +00:00
Nicholas Marriott
82b45b460e The scroll region cannot be one line only, ignore attempts to make it so. 2009-07-15 17:43:02 +00:00
Nicholas Marriott
1e574bb70c Get rid of the PANE_HIDDEN flag in favour of a function, and moving the
decision for whether or not a pane should be drawn out of the layout code and
into the redraw code.

This is needed for the new layout design, getting it in now to make that easier
to work on.
2009-07-15 17:42:44 +00:00
Nicholas Marriott
537c32b6b6 Escape ~, pointed out by tcunha. 2009-07-14 17:44:24 +00:00
Nicholas Marriott
f44ae0535e Need time.h not sys/time.h for time(2). 2009-07-14 07:01:03 +00:00
Nicholas Marriott
910d6282c4 Whoops, chose the wrong one in a conflict. Revert. 2009-07-14 06:54:38 +00:00
Nicholas Marriott
20e322bf9b arg.c is no longer required. 2009-07-14 06:47:46 +00:00
Nicholas Marriott
edd3142d1f Don't need ncurses, use curses. 2009-07-14 06:47:12 +00:00
Nicholas Marriott
097b96ea44 Having fixed flags for single-character getopt options is a bit hard to
maintain and is only going to get worse as more are used. So instead, add a new
uint64_t member to cmd_entry which is a bitmask of upper and lowercase options
accepted by the command.

This means new single character options can be used without the need to add it
explicitly to the list.
2009-07-14 06:43:33 +00:00
Nicholas Marriott
5ccd0025a0 copy-mode and scroll-mode have a -u flag missing from usage, add it. 2009-07-14 06:42:22 +00:00
Nicholas Marriott
d358a352c0 Tidy up and improve target (-t) argument parsing:
- move the code back into cmd.c and merge with the existing functions where
  possible;
- accept "-tttyp0" as well as "-t/dev/ttyp0" for clients;
- when looking up session names, try an exact match first, and if that fails
  look for it as an fnmatch pattern and then as the start of a name - if more
  that one session matches an error is given; so if there is one session called
  "mysession", -tmysession, -tmysess, -tmysess* are equivalent but if there
  is also "mysession2", the last two are errors;
- similarly for windows, if the argument is not a valid index or exact window
  name match, try it against the window names as an fnmatch pattern and a
  prefix.
2009-07-14 06:42:06 +00:00
Nicholas Marriott
e63567d51c Support "alternate screen" mode (terminfo smcup/rmcup) typically used by full
screen interactive programs to preserve the screen contents. When activated, it
saves a copy of the visible grid and disables scrolling into and resizing out
of the history; when deactivated the visible data is restored and the history
reenabled.
2009-07-14 06:40:33 +00:00
Nicholas Marriott
f41ef2198b Missed this declaration in key bindings change. Whoops. 2009-07-14 06:40:03 +00:00
Nicholas Marriott
61bd3ae1c6 Document the -k flag to new-window. 2009-07-14 06:39:44 +00:00
Nicholas Marriott
5ef5bd7c31 Add a "back to indentation" key in copy mode to move the cursor to the first
non-whitespace character. ^ with vi and M-m with emacs key bindings. Another
from Kalle Olavi Niemitalo, thanks.
2009-07-14 06:39:25 +00:00
Nicholas Marriott
7f98193beb Merge three copies of identical code to move the cursor x position into a
single function, from Kalle Olavi Niemitalo.
2009-07-14 06:38:32 +00:00
Nicholas Marriott
d2c3dbc665 If it exist, load a system-wide configuration file /etc/tmux.conf before any
user-specified one.
2009-07-14 06:38:14 +00:00
Tiago Cunha
2f75b07d08 Update. 2009-07-13 18:29:28 +00:00
Tiago Cunha
280619a4e8 Expand leading tilde on commands which expect a filename. 2009-07-13 18:03:18 +00:00
Nicholas Marriott
6db6df882c Update. 2009-07-13 11:33:06 +00:00
Nicholas Marriott
db411ca515 Update TODO. 2009-07-13 06:29:19 +00:00
Nicholas Marriott
3fb3613d34 Limit the history to hlimit not hlimit - 1. This makes a history-limit setting
of 0 work as expected.
2009-07-12 17:12:41 +00:00
Nicholas Marriott
30f47dfc5e Add -r to the synopsis of the paste-buffer command, prompted by jmc. 2009-07-12 17:12:06 +00:00
Nicholas Marriott
27fc963631 When pasting, translate \n into \r. This matches xterm and putty's behaviour,
and makes emacs happy when pasting into some modes. A new -r (raw) flag to
paste-buffer pastes without the translation.

From Kalle Olavi Niemitalo, thanks!
2009-07-12 17:11:39 +00:00
Nicholas Marriott
d8de72ca77 Copy was using the real line length which after resize can be larger than the
screen width. When built with -DDEBUG, this made the grid bounds checking code
kill the server. Restrict copying to the actual width.

From Kalle Olavi Niemitalo, thanks.
2009-07-12 17:11:07 +00:00
Nicholas Marriott
ef5f356da2 paste-buffer -d was not documented. From Kalle Olavi Niemitalo. 2009-07-12 17:10:35 +00:00
Nicholas Marriott
1919deab1f Redraw the status line after renaming a session (it may contain the name). 2009-07-12 17:09:15 +00:00
Nicholas Marriott
fd0971542f Don't send initialisation strings is1/2/3 (barely anything else does) and move
smcup to the first and rmcup to the last sequences output to the terminal. This
allows tmux to use the alternate screen (smcup/rmcup) when available.
2009-07-12 17:08:37 +00:00
Nicholas Marriott
d7b4aa0ff3 Add a default-terminal option to set the starting value of $TERM in new
windows.
2009-07-12 17:07:58 +00:00
Nicholas Marriott
79bc6041c9 Document display-time option which seems to have been missed. 2009-07-12 17:04:21 +00:00
Nicholas Marriott
8be8016a76 When the terminal size is reduced horizontally, don't truncate lines to the new
width, so that if the same lines are later increased in size the content
reappears.
2009-07-12 17:03:11 +00:00
Nicholas Marriott
d4a143a425 Stop in the right place so all the lines selected are copied. Reported by Kalle
Olavi Niemitalo, thanks.
2009-07-12 16:56:56 +00:00
Nicholas Marriott
bf0f56d04e Update TODO. 2009-07-11 19:25:53 +00:00
Nicholas Marriott
0e7c6bdcc7 Update TODO. 2009-07-11 13:48:05 +00:00
Nicholas Marriott
7e8ff69a14 Fix $Id$. 2009-07-09 18:16:36 +00:00
Nicholas Marriott
eee3dd297e New command, if-shell (alias if). Executes the tmux command in the second
argument if the shell command in the first succeeds, for example:

       if "[ -e ~/.tmux.conf.alt ]" "source .tmux.conf.alt"

Written by Tiago Cunha, many thanks.
2009-07-09 18:14:18 +00:00
Nicholas Marriott
5afe17d147 Fix $Id$. 2009-07-09 18:08:29 +00:00
Nicholas Marriott
664a0bd559 Cursor up and down should be limited by the scroll region (cuu should stop at
the scroll region top if starting from below it and cud stop at the bottom if
starting from above). Fixes another vttest test.
2009-07-09 18:08:13 +00:00
Nicholas Marriott
4422b958c3 Don't leak FILE * on malloc failure. From ivoire at users dot sourceforge dot
net.
2009-07-09 18:05:17 +00:00
Nicholas Marriott
295879cced Change inserting and deleting lines inside the scroll region to properly clear
lines that should be inserted/deleted but not moved. Fixes problems with mutt
reported by Brian Lewis, thanks.
2009-07-09 18:04:53 +00:00
Nicholas Marriott
e073441c36 Tidy by removing unused argument from grid_view_{insert,delete}_line_region
functions (currently don't fully work, this is to make fix easier).
2009-07-09 18:04:17 +00:00
Nicholas Marriott
27e9f77a49 Fix two memory leaks when assigning shell variables in configuration
file/command prompt. From Tiago Cunha.
2009-07-09 18:03:28 +00:00
Nicholas Marriott
f8ea82d7dc Update TODO list. 2009-07-09 17:58:54 +00:00
Nicholas Marriott
890db6eaaf Accidently deleted default-command. 2009-07-08 18:12:57 +00:00
Nicholas Marriott
99395856ff Bring spacing into line. 2009-07-08 18:07:09 +00:00
Nicholas Marriott
9cf68ac868 Whoops, that shouldn't have been there. 2009-07-08 18:05:33 +00:00
Nicholas Marriott
2ddcb51df3 Fix $Id$. 2009-07-08 18:03:03 +00:00
Nicholas Marriott
9875be3327 When reinitialising the screen, do not omit to clear the last line. 2009-07-08 18:02:31 +00:00
Nicholas Marriott
a182502af0 Don't let ambiguous commands override an exact alias match: eg if commands
"abc-1", "abc-2", "abc-3" exist and "abc-3" has the alias "abc", "tmux abc"
should execute abc-3, not complain about the command being ambiguous.
2009-07-08 18:01:55 +00:00
Nicholas Marriott
86504af149 Rename the global options variables to be shorter and to make session options
clear. No functional change, getting this out of the way to make later options
changes easier.
2009-07-08 18:01:31 +00:00
Nicholas Marriott
1825609d8d Handle empty or unset TERM correctly; also fix a fatal() message while here. 2009-07-08 17:58:32 +00:00
Nicholas Marriott
43ff216fa6 When sending a "protocol mismatch" error message, tell the client to exit
afterwards, otherwise it hangs.
2009-07-08 17:58:09 +00:00
Nicholas Marriott
ff54332b66 The fix for default-path (use target session options instead of global options)
is required here as well, doh.
2009-07-08 17:57:51 +00:00
Nicholas Marriott
84da2f32ec Minor fix: look for default-path in the options for the specified session first
rather than just the global options. From Brandon Mercer, thanks.
2009-07-08 17:57:27 +00:00
Nicholas Marriott
b7a272fe6d Add a section summarising how options work, make the distinction between window
and session options clearer, and fix the incorrect synopses and descriptions of
show-options and show-window-options.
2009-07-08 17:57:07 +00:00
Nicholas Marriott
9e5a581307 When unlocking the server, don't try to clear the prompt on clients without a
prompt (such as the one issuing the unlock request).

This caused the server to die if the wrong password was entered when unlocking
from the command line with -U (nasty).
2009-07-08 17:54:36 +00:00
Nicholas Marriott
f34f1fd78d Sync. 2009-07-07 23:08:42 +00:00
Nicholas Marriott
a476d4c587 This is not really important or major. 2009-07-06 18:53:24 +00:00
Nicholas Marriott
21f8ed50db Next will be 1.0. 2009-07-06 18:21:17 +00:00
172 changed files with 16699 additions and 9651 deletions

90
CHANGES
View File

@@ -1,3 +1,91 @@
CHANGES FROM 1.0 TO 1.1, 05 November 2009
* New run-shell (alias run) command to run an external command without a
window, capture it's stdout, and send it to output mode.
* Ability to define multiple prefix keys.
* Internal locking mechanism removed. Instead, detach each client and run the
external command specified in the new session option lock-command (by default
lock -np), thus allowing the system password to be used.
* set-password command, and -U command line flag removed per the above change.
* Add support for -c command line flag to execute a shell command.
* New lock-client (alias lockc), and lock-session (alias locks) commands to
lock a particular client, or all clients attached to a session.
* Support C-n/C-p/C-v/M-v with emacs keys in choice mode.
* Use : for goto line rather than g in vi mode.
* Try to guess which client to use when no target client was specified. Finds
the current session, and if only one client is present, use it. Otherwise,
return the most recently used client.
* Make C-Down/C-Up in copy mode scroll the screen down/up one line without
moving the cursor.
* Scroll mode superseded by copy mode.
* New synchronize-panes window option to send all input to all other panes in
the same window.
* New lock-server session option to lock, when off (on by default), each
session when it has been idle for the lock-after-time setting. When on, the
entire server locks when all sessions have been idle for their individual
lock-after-time setting.
* Add support for grouped sessions which have independent name, options,
current window, but where the linked windows are synchronized (ie creating,
killing windows are mirrored between the sessions). A grouped session may be
created by passing -t to new-session.
* New mouse-select-pane session option to select the current pane with the
mouse.
* Queue, and run commands in the background for if-shell, status-left,
status-right, and #() by starting each once every status-interval. Adds the
capability to call some programs which would previously cause the server to
hang (eg sleep/tmux). It also avoids running commands excessively (ie if used
multiple times, it will be run only once).
* When a window is zombified and automatic-rename is on, append [dead] to the
name.
* Split list-panes (alias lsp) off from list-windows.
* New pipe-pane (alias pipep) to redirect a pane output to an external command.
* Support for automatic-renames for Solaris.
* Permit attributes to be turned off in #[] by prefixing with no (eg nobright).
* Add H/M/L in vi mode, and M-R/M-r in emacs to move the cursor to the top,
middle, and bottom of the screen.
* -a option added to kill-pane to kill all except current pane.
* The -d command line flag is now gone (can be replaced by terminal-overrides).
Just use op/AX to detect default colours.
* input/tty/utf8 improvements.
* xterm-keys rewrite.
* Additional code reduction, and bug fixes.
CHANGES FROM 0.9 TO 1.0, 20 Sept 2009
* Option to alter the format of the window title set by tmux.
* Backoff for a while after multiple incorrect password attempts.
* Quick display of pane numbers (C-b q).
* Better choose-window, choose-session commands and a new choose-client command.
* Option to request multiple responses when using command-prompt.
* Improved environment handling.
* Combine wrapped lines when pasting.
* Option to override terminal settings (terminal-overrides).
* Use the full range of ACS characters for drawing pane separator lines.
* Customisable mode keys.
* Status line colour options, with embedded colours in status-left/right, and
an option to centre the window list.
* Much improved layouts, including both horizontal and vertical splitting.
* Optional visual bell, activity and content indications.
* Set the utf8 and status-utf8 options when the server is started with -u.
* display-message command to show a message in the status line, by default some
information about the current window.
* Improved current process detection on NetBSD.
* unlink-window -k is now the same as kill-window.
* attach-session now works from inside tmux.
* A system-wide configuration file, /etc/tmux.conf.
* A number of new commands in copy mode, including searching.
* Panes are now specified using the target (-t) notation.
* -t now accepts fnmatch(3) patterns and looks for prefixes.
* Translate \r into \n when pasting.
* Support for binding commands to keys without the prefix key
* Support for alternate screen (terminfo smcup/rmcup).
* Maintain data that goes off screen after reducing the window size, so it can
be restored when the size is increased again.
* New if-shell command to test a shell command before running a tmux command.
* tmux now works as the shell.
* Man page reorganisation.
* Many minor additions, much code tidying and several bug fixes.
CHANGES FROM 0.8 TO 0.9, 01 July 2009
* Major changes to build infrastructure: cleanup of makefiles and addition
@@ -1322,7 +1410,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.299 2009-07-01 22:15:16 nicm Exp $
$Id: CHANGES,v 1.301 2009-11-05 12:35:47 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

61
FAQ
View File

@@ -42,16 +42,17 @@ include as much of the following information as possible:
Please send feature requests by email to nicm@users.sourceforge.net.
* Why do you use the screen termcap inside tmux? It sucks.
* Why do you use the screen terminal description inside tmux? It sucks.
It is already widely available. It is planned to change to something else
such as xterm-color at some point, if possible.
It is already widely available. It is planned to change to something else such
as xterm-xfree86 at some point, if possible.
* I don't see any colour in my terminal! Help!
On some platforms, common termcaps such as xterm do not include colour. screen
ignores this, tmux does not. If the terminal emulator in use supports colour,
use a termcap which correctly lists this, such as xterm-color.
On some platforms, common terminal descriptions such as xterm do not include
colour. screen ignores this, tmux does not. If the terminal emulator in use
supports colour, use a value for TERM which correctly lists this, such as
xterm-color.
* tmux freezes my terminal when I attach to a session. I even have to kill -9
the shell it was started from to recover!
@@ -92,13 +93,22 @@ 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
$ tmux -u new
* How do I use a 256 colour terminal?
tmux will attempt to detect a 256 colour terminal both by looking at the Co
termcap entry and, as this is broken for some terminals such as xterm-256color,
by looking for the string "256col" in the termcap name.
Provided the underlying terminal supports 256 colours, it is usually sufficient
to add the following to ~/.tmux.conf:
set -g default-terminal "screen-256color"
Note that some platforms do not support "screen-256color" ("infocmp
screen-256color" will return an error) - in this case see the next entry in
this FAQ.
tmux attempts to detect a 256 colour terminal both by looking at the colors
terminfo entry and by looking for the string "256col" in the TERM environment
variable.
If both these methods fail, the -2 flag may be passed to tmux when attaching
to a session to indicate the terminal supports 256 colours.
@@ -106,22 +116,18 @@ to a session to indicate the terminal supports 256 colours.
* vim or $otherprogram doesn't display 256 colours. What's up?
Some programs attempt to detect the number of colours a terminal is capable of
by checking the Co termcap entry. However, this is not reliable, and in any
case is missing from the "screen" termcap used inside tmux.
by checking the colors terminfo or Co termcap entry. However, this is not
reliable, and in any case is missing from the "screen" terminal description
used inside tmux.
There are three options to allow programs to recognise they are running on
a 256-colour terminal inside tmux:
There are two options (aside from using "screen-256color") to allow programs to
recognise they are running on a 256-colour terminal inside tmux:
- Manually force the application to use 256 colours always or if TERM is set to
screen. For vim, you can do this by overriding the t_Co option, see
http://vim.wikia.com/wiki/256_colors_in_vim.
- If the platform includes it, using the "screen-256color" termcap (set
TERM=screen-256color). "infocmp screen-256color" can be used to check if this
is supported. It is not currently possible to set this globally inside tmux
but it may be done in a shell startup script by checking if TERM is screen
and exporting TERM=screen-256color instead.
- Creating a custom terminfo file that includes Co#256 in ~/.terminfo and using
it instead. These may be compiled with tic(1).
- Creating a custom terminfo file that includes colors#256 in ~/.terminfo and
using it instead. These may be compiled with tic(1).
* How do I make Ctrl-PgUp and Ctrl-PgDn work in vim?
@@ -187,11 +193,12 @@ Automatic window renaming may use a lot of CPU, particularly on slow computers:
if this is a problem, turn it off with "setw -g automatic-rename off". If this
doesn't fix it, please report the problem.
* How do I prevent tmux from resizing my PuTTY window?
* I use PuTTY and my tmux window pane separators are all qqqqqqqqq's!
This isn't tmux's fault, but happens because the initialisation strings for the
terminal in use (set through TERM) request it. PuTTY can be told to ignore such
requests: in the configuration window under Terminal -> Features, check the
"Disable remote-controlled terminal resizing" box.
PuTTY is using a character set translation that doesn't support ACS line
drawing. With a Unicode font, try setting PuTTY to use a different translation
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.23 2009-07-01 19:49:56 nicm Exp $
$Id: FAQ,v 1.29 2009-08-08 20:46:26 nicm Exp $

View File

@@ -1,22 +1,35 @@
# $Id: GNUmakefile,v 1.107 2009-07-01 22:10:06 nicm Exp $
# $Id: GNUmakefile,v 1.120 2009-11-05 12:30:55 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.
#
.PHONY: clean
VERSION= 0.9
VERSION= 1.1
#FDEBUG= 1
CC?= gcc
CC?= cc
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+= -lncurses
LIBS+=
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
ifeq ($(shell (LC_ALL=C $(CC) -v 2>&1|awk '/gcc version 4/') || true), )
CPPFLAGS:= -I. -I- $(CPPFLAGS)
else
CPPFLAGS:= -iquote. $(CPPFLAGS)
# Sun CC
ifneq ($(shell ($(CC) -V 2>&1|awk '/Sun C/' || true)), )
CFLAGS+=-erroff=E_EMPTY_DECLARATION
FDEBUG=
endif
ifdef FDEBUG
@@ -27,6 +40,17 @@ CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
endif
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
ifeq ($(shell (LC_ALL=C $(CC) -v 2>&1|awk '/gcc version 4|clang/') || true), )
CPPFLAGS:= -I. -I- $(CPPFLAGS)
else
CPPFLAGS:= -iquote. $(CPPFLAGS)
ifdef FDEBUG
CFLAGS+= -Wno-pointer-sign
endif
endif
PREFIX?= /usr/local
INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555
@@ -45,9 +69,12 @@ depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
clean:
rm -f tmux *.o .depend *~ *.core *.log compat/*.o
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
clean-all: clean
clean-depend:
rm -f .depend
clean-all: clean clean-depend
rm -f config.h config.mk
install: all
@@ -55,3 +82,5 @@ install: all
$(INSTALLBIN) tmux $(DESTDIR)$(PREFIX)/bin/tmux
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) tmux.1 $(DESTDIR)$(PREFIX)/man/man1/tmux.1
-include .depend

View File

@@ -1,25 +1,31 @@
# $Id: Makefile,v 1.142 2009-07-01 22:10:06 nicm Exp $
# $Id: Makefile,v 1.153 2009-11-05 12:30:55 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.
#
.SUFFIXES: .c .o
.PHONY: clean
VERSION= 0.9
VERSION= 1.1
#FDEBUG= 1
CC?= cc
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+= -lncurses
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
CCV!= (LC_ALL=C ${CC} -v 2>&1|awk '/gcc version 4/') || true
.if empty(CCV)
CPPFLAGS:= -I. -I- -I/usr/local/include ${CPPFLAGS}
.else
CPPFLAGS:= -iquote. -I/usr/local/include ${CPPFLAGS}
.endif
LIBS+=
.ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG
@@ -29,6 +35,18 @@ CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
.endif
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
CCV!= (LC_ALL=C ${CC} -v 2>&1|awk '/gcc version 4|clang/') || true
.if empty(CCV)
CPPFLAGS:= -I. -I- -I/usr/local/include ${CPPFLAGS}
.else
CPPFLAGS:= -iquote. -I/usr/local/include ${CPPFLAGS}
.ifdef FDEBUG
CFLAGS+= -Wno-pointer-sign
.endif
.endif
PREFIX?= /usr/local
INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555
@@ -50,9 +68,12 @@ depend:
mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
clean:
rm -f tmux *.o .depend *~ *.core *.log compat/*.o
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
clean-all: clean
clean-depend:
rm -f .depend
clean-all: clean clean-depend
rm -f config.h config.mk
install: all

33
NOTES
View File

@@ -4,15 +4,17 @@ tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen.
This 0.9 release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they hasn't been tested in a while). It is
This release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they haven't been tested in a while). It is
usable, although there remain a number of missing features and some remaining
bugs are expected.
If upgrading from 0.5, PLEASE NOTE the following configuration file changes: it
is now required to pass the -g flag to set-option or set-window-option to set
global options; remain-by-default and utf8-default are now gone, use global
window options (set-window-option -g) instead.
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.
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
@@ -37,21 +39,14 @@ The following is a summary of major features implemented in this version:
- Support for VT100 line drawing characters.
- A large command set.
- Vertical window splitting and layout.
- Automatic server locking on inactivity.
- Automatic server locking on inactivity by running an external command.
- A configuration file.
- UTF-8 support.
And major missing features:
- No support for programs changing termios(4) settings or other tty(4) ioctls.
A more extensive, but rough, todo list is included in the TODO file.
tmux also depends on several features of the client terminal (TERM), if these
are missing it may refuse to run, or not behave correctly. Known working are
TERM=screen (tmux in screen), xterm, xterm-color and rxvt. Note that TERM=xterm
does not support colour on OpenBSD. screen ignores this, tmux does not: use
xterm-color or rxvt for colour.
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
@@ -85,6 +80,12 @@ welcome. Please send by email to:
nicm@users.sf.net
This file and the CHANGES, FAQ and TODO files are licensed under the ISC
license. Files under examples/ remain copyright their authors unless otherwise
stated in the file but permission has been received to distribute them with
tmux. All other files have a license and copyright notice at their
start. Please contact me with any queries.
-- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.48 2009-07-01 19:49:56 nicm Exp $
$Id: NOTES,v 1.51 2009-11-05 12:35:47 tcunha Exp $

119
TODO
View File

@@ -1,5 +1,4 @@
- window creation/idle time
- could use bsearch all over the place or get rid of smaller tables (clientmsg)
- better errors when creating new windows/sessions (how?)
- implicitly add exec to the commands for new windows (switch to disable it)?
- it would be nice to have multichar commands eg C-b K K
@@ -7,86 +6,92 @@
extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session?
- allow fnmatch for -c, so that you can, eg, detach all clients
- bind non prefix keys
- garbage collect window history (100 lines at a time?) if it hasn't been used
in $x time (need window creation/use times)
- lift SHRT_MAX limits for history?
- audit copy/scroll and other modes for problems with very small windows
- better mode features: search, back word, forward word, etc
- flags to centre screen in window
- better terminal emulation (identify, insert mode, some other bits)
- audit for leftover/unused code
- better terminal emulation
- activity/bell should be per-window not per-link? what if it is cur win in
session not being watched?
- tidy up window modes
- next prev word etc in command prompt; also ^K
- next prev word etc in command prompt
- many more info() displays for various things
- vi half page scroll
- backspace should perhaps wrap backwards over newlines which were not moved
down by a newline: screen and the OS X terminal does this but xterm and most
others do not. this might be hard: a flag for each grid line (top bit of size
maybe)? a single flag is insufficient as can't then tell when to /stop/
unwrapping
- input.c is too complicated. simplify?
- use a better termcap internally instead of screen, perhaps xterm
- kill all but current pane
- fix rxvt cursor fg issue (text under cursor can have non-white fg)
- key handling sucks a bit and may need to be reworked
- some people find first window being 0 rather than 1 is awkward on the
keyboard
- client sx/sy should be in tty, then can let the terminal wrap at edge
to allow xterm to pick up it should be one line for its c/p
- should be able to move to a hidden pane and it would be moved into view. pane
number in status line/top-right would be cool for this
- command to run something without a window at all - output to
window-more. what for? isnt this the same as doing it w/ splitw/neww now?
- would be nice if tmux could be the shell (tmux attach, but hard link to tmux
binary as "tmuxsh" or wrapper script?) problems with tty dev permissions
- support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically?
- set-option should be set-session-option and should be overall global options
for stuff like mode keys?
also quiet, utf8 and maybe other flags?
-g is a bit unexpected in conf file
- clear window title on exit
- refer to windows by name etc (duplicates? fnmatch?)
- the output code (tty.c) could do with optimisation depending on term
capibilities
capabilities
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- goto line and search history in copy/scroll modes
- a command to display the status line briefly when it is turned off
- clone session command
- make command sequences more usable: don't require space after ;, handle
errors better
- might be nice if attach-session behaved like switch-client inside an
existing client
- key to switch to copy mode from scroll mode
- attach should have a flag to create session if it doesn't exist
- layout/split stuff:
** NEW layout design:
1. finish rewrite manual with tree of layout_cell
2. convert automatic layout modes to produce a tree and make
them one-off operations
3. move any size/position details from window_pane to layout_cell
3.5. fix -p/-l on split
4. a way to address panes by name ("top-left") and position ("0,0")
TO TEST: force-width/height OK, respawn-window, rotate-window OK, break-pane??
** rename split-window -> split-pane
- fix UTF-8 guesswork on sparc64, improve tty checks
- choice and more mode would be better per client than per window?
- hooks to which commands may be attached, for example: tmux add-hook
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
$HOME/.tmux-session.conf
- 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
- 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
- what about utmp etc? can tmux update it like screen? setgid?
- warts on current naming:
- display-time but message-fg/bg/attr
- list-* vs show-*
- server-info
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-*
- split-window -> split-pane??
- tidy up and prioritise todo list ;-)
- neww and attach can create a session if none exists?
would work fine with config file since
- 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
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
- close/redirect stderr when popen to child proc for #() in status line
- if-shell-command command to run a tmux command if a shell command returns true
- hooks to which commands may be attached, for example:
tmux add-hook "new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file $HOME/.tmux-session.conf
- get it passing all the vttest tests that don't require resizing the terminal
- does tmux require a exmple conf? where does it go?
- there are an awful lot of commands. maybe separate man page for conf
file/commands -similar to ssh/ssh_config?
- esc seq to set window title should be documented and should set automatic-rename
- *** get rid of PANE_HIDDEN -- initially just check for outside window
- way to set socket path from config file
- the "window with one pane" vs window distinction is weird, eg you can't kill-pane the last pane
-- idea of a "view" onto a window, need base x/y offsets
for redraw
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- 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
- some way to KEEP a command running continually and just use its LAST line of
output
- bind commands to mouse buttons
- 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
- 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

194
arg.c
View File

@@ -1,194 +0,0 @@
/* $Id: arg.c,v 1.6 2009-06-25 15:25:45 nicm 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 <fnmatch.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
struct client *arg_lookup_client(const char *);
struct session *arg_lookup_session(const char *);
struct client *
arg_lookup_client(const char *name)
{
struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && strcmp(name, c->tty.path) == 0)
return (c);
}
return (NULL);
}
struct session *
arg_lookup_session(const char *name)
{
struct session *s, *newest = NULL;
struct timeval *tv;
u_int i;
tv = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL || fnmatch(name, s->name, 0) != 0)
continue;
if (tv == NULL || timercmp(&s->tv, tv, >)) {
newest = s;
tv = &s->tv;
}
}
return (newest);
}
struct client *
arg_parse_client(const char *arg)
{
struct client *c;
char *arg2;
size_t n;
if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (n && arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* Try and look up the client name. */
c = arg_lookup_client(arg2);
xfree(arg2);
return (c);
}
return (NULL);
}
struct session *
arg_parse_session(const char *arg)
{
struct session *s;
struct client *c;
char *arg2;
size_t n;
if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (n && arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* See if the argument matches a session. */
if ((s = arg_lookup_session(arg2)) != NULL) {
xfree(arg2);
return (s);
}
/* If not try a client. */
if ((c = arg_lookup_client(arg2)) != NULL) {
xfree(arg2);
return (c->session);
}
xfree(arg2);
}
return (NULL);
}
int
arg_parse_window(const char *arg, struct session **s, int *idx)
{
char *arg2, *ptr;
const char *errstr;
*idx = -1;
/* Handle no argument or a single :. */
if (arg == NULL || (arg[0] == ':' && arg[1] == '\0')) {
*s = arg_parse_session(NULL);
return (0);
}
/* Find the separator if any. */
arg2 = xstrdup(arg);
ptr = strrchr(arg2, ':');
/*
* If it is first, this means no session name, so use current session
* and try to convert the rest as index.
*/
if (ptr == arg2) {
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}
xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}
/* If missing, try as an index, else look up immediately. */
if (ptr == NULL) {
*idx = strtonum(arg2, 0, INT_MAX, &errstr);
if (errstr == NULL) {
/* This is good as an index; use current session. */
xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}
*idx = -1;
goto lookup;
}
/* If last, strip it and look up as a session. */
if (ptr[1] == '\0') {
*ptr = '\0';
goto lookup;
}
/* Present but not first and not last. Break and convert both. */
*ptr = '\0';
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}
lookup:
/* Look up as session. */
*s = arg_parse_session(arg2);
xfree(arg2);
if (*s == NULL)
return (1);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: array.h,v 1.7 2008-09-29 16:58:02 nicm Exp $ */
/* $Id: array.h,v 1.9 2009-11-02 21:34:32 tcunha Exp $ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -85,7 +85,7 @@
ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \
} \
(a)->num--; \
if ((a)->num == 0) \
if ((a)->num == 0) \
ARRAY_FREE(a); \
} while (0)
@@ -102,7 +102,7 @@
#define ARRAY_CONCAT(a, b) do { \
ARRAY_ENSURE(a, (b)->num); \
memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)) \
memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \
(a)->num += (b)->num; \
} while (0)

View File

@@ -1,4 +1,4 @@
/* $Id: buffer-poll.c,v 1.14 2009-06-25 16:22:36 nicm Exp $ */
/* $Id: buffer-poll.c,v 1.18 2009-10-23 17:49:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -25,17 +25,15 @@
/* Fill buffers from socket based on poll results. */
int
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
buffer_poll(int fd, int events, struct buffer *in, struct buffer *out)
{
ssize_t n;
#ifdef HAVE_POLL
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
if (events & (POLLERR|POLLNVAL))
return (-1);
#endif
if (pfd->revents & POLLIN) {
if (in != NULL && events & POLLIN) {
buffer_ensure(in, BUFSIZ);
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
n = read(fd, BUFFER_IN(in), BUFFER_FREE(in));
if (n == 0)
return (-1);
if (n == -1) {
@@ -43,9 +41,10 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
return (-1);
} else
buffer_add(in, n);
}
if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
} 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);

View File

@@ -1,4 +1,4 @@
/* $Id: buffer.c,v 1.7 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: buffer.c,v 1.8 2009-08-21 21:09:13 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -100,9 +100,6 @@ buffer_remove(struct buffer *b, size_t size)
void
buffer_write(struct buffer *b, const void *data, size_t size)
{
if (size == 0)
fatalx("zero size");
buffer_ensure(b, size);
memcpy(BUFFER_IN(b), data, size);
buffer_add(b, size);
@@ -127,7 +124,7 @@ buffer_write8(struct buffer *b, uint8_t n)
{
buffer_ensure(b, 1);
BUFFER_IN(b)[0] = n;
buffer_add(b, 1);
b->size++;
}
/* Extract an 8-bit value. */

34
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.18 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cfg.c,v 1.23 2009-10-28 23:12:38 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -51,25 +51,15 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
}
int
load_cfg(const char *path, char **cause)
load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
{
FILE *f;
FILE *f;
u_int n;
struct stat sb;
char *buf, *line, *ptr;
char *buf, *line, *ptr;
size_t len;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
if (stat(path, &sb) != 0) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (-1);
}
if (!S_ISREG(sb.st_mode)) {
xasprintf(cause, "%s: not a regular file", path);
return (-1);
}
if ((f = fopen(path, "rb")) == NULL) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (1);
@@ -97,16 +87,20 @@ load_cfg(const char *path, char **cause)
continue;
cfg_cause = NULL;
ctx.msgdata = NULL;
ctx.cursession = NULL;
ctx.curclient = NULL;
if (ctxin == NULL) {
ctx.msgdata = NULL;
ctx.curclient = NULL;
ctx.cmdclient = NULL;
} else {
ctx.msgdata = ctxin->msgdata;
ctx.curclient = ctxin->curclient;
ctx.cmdclient = ctxin->cmdclient;
}
ctx.error = cfg_error;
ctx.print = cfg_print;
ctx.info = cfg_print;
ctx.cmdclient = NULL;
cfg_cause = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
@@ -122,6 +116,8 @@ load_cfg(const char *path, char **cause)
return (0);
error:
if (line != NULL)
xfree(line);
fclose(f);
xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);

View File

@@ -1,92 +0,0 @@
/* $Id: client-fn.c,v 1.6 2009-03-04 17:24:07 nicm 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 <stdlib.h>
#include <string.h>
#include "tmux.h"
void
client_fill_session(struct msg_command_data *data)
{
char *env, *ptr1, *ptr2, buf[256];
size_t len;
const char *errstr;
long long ll;
data->pid = -1;
if ((env = getenv("TMUX")) == NULL)
return;
if ((ptr2 = strrchr(env, ',')) == NULL || ptr2 == env)
return;
for (ptr1 = ptr2 - 1; ptr1 > env && *ptr1 != ','; ptr1--)
;
if (*ptr1 != ',')
return;
ptr1++;
ptr2++;
len = ptr2 - ptr1 - 1;
if (len > (sizeof buf) - 1)
return;
memcpy(buf, ptr1, len);
buf[len] = '\0';
ll = strtonum(buf, 0, LONG_MAX, &errstr);
if (errstr != NULL)
return;
data->pid = ll;
ll = strtonum(ptr2, 0, UINT_MAX, &errstr);
if (errstr != NULL)
return;
data->idx = ll;
}
void
client_write_server(
struct client_ctx *cctx, enum hdrtype type, void *buf, size_t len)
{
struct hdr hdr;
hdr.type = type;
hdr.size = len;
buffer_write(cctx->srv_out, &hdr, sizeof hdr);
if (buf != NULL && len > 0)
buffer_write(cctx->srv_out, buf, len);
}
void
client_write_server2(struct client_ctx *cctx,
enum hdrtype type, void *buf1, size_t len1, void *buf2, size_t len2)
{
struct hdr hdr;
hdr.type = type;
hdr.size = len1 + len2;
buffer_write(cctx->srv_out, &hdr, sizeof hdr);
if (buf1 != NULL && len1 > 0)
buffer_write(cctx->srv_out, buf1, len1);
if (buf2 != NULL && len2 > 0)
buffer_write(cctx->srv_out, buf2, len2);
}

View File

@@ -1,159 +0,0 @@
/* $Id: client-msg.c,v 1.19 2009-06-25 15:25:45 nicm 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 <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_shutdown(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exited(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **);
struct client_msg {
enum hdrtype type;
int (*fn)(struct hdr *, struct client_ctx *, char **);
};
struct client_msg client_msg_table[] = {
{ MSG_DETACH, client_msg_fn_detach },
{ MSG_ERROR, client_msg_fn_error },
{ MSG_EXIT, client_msg_fn_exit },
{ MSG_EXITED, client_msg_fn_exited },
{ MSG_SHUTDOWN, client_msg_fn_shutdown },
{ MSG_SUSPEND, client_msg_fn_suspend },
};
int
client_msg_dispatch(struct client_ctx *cctx, char **error)
{
struct hdr hdr;
struct client_msg *msg;
u_int i;
if (BUFFER_USED(cctx->srv_in) < sizeof hdr)
return (1);
memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr);
if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size)
return (1);
buffer_remove(cctx->srv_in, sizeof hdr);
for (i = 0; i < nitems(client_msg_table); i++) {
msg = client_msg_table + i;
if (msg->type == hdr.type) {
if (msg->fn(&hdr, cctx, error) != 0)
return (-1);
return (0);
}
}
fatalx("unexpected message");
}
int
client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
{
if (hdr->size == SIZE_MAX)
fatalx("bad MSG_ERROR size");
*error = xmalloc(hdr->size + 1);
buffer_read(cctx->srv_in, *error, hdr->size);
(*error)[hdr->size] = '\0';
return (-1);
}
int
client_msg_fn_detach(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_DETACH size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_DETACH;
return (0);
}
int
client_msg_fn_shutdown(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_SHUTDOWN;
return (0);
}
int
client_msg_fn_exit(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_EXIT size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_EXIT;
return (0);
}
int
client_msg_fn_exited(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_EXITED size");
return (-1);
}
int
client_msg_fn_suspend(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
struct sigaction act;
if (hdr->size != 0)
fatalx("bad MSG_SUSPEND size");
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);
return (0);
}

338
client.c
View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.53 2009-07-01 23:06:32 nicm Exp $ */
/* $Id: client.c,v 1.84 2009-11-02 21:41:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,21 +33,23 @@
#include "tmux.h"
void client_handle_winch(struct client_ctx *);
struct imsgbuf client_ibuf;
const char *client_exitmsg;
int
client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
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);
struct imsgbuf *
client_init(char *path, int cmdflags, int flags)
{
struct sockaddr_un sa;
struct stat sb;
struct msg_identify_data data;
struct winsize ws;
size_t size;
int mode;
struct buffer *b;
char *name;
struct sockaddr_un sa;
size_t size;
int fd, mode;
#ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
char rpathbuf[MAXPATHLEN];
#endif
#ifdef HAVE_SETPROCTITLE
@@ -56,19 +58,6 @@ client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
setproctitle("client (%s)", rpathbuf);
#endif
if (lstat(path, &sb) != 0) {
if (start_server && errno == ENOENT) {
if ((cctx->srv_fd = server_start(path)) == -1)
goto start_failed;
goto server_started;
}
goto not_found;
}
if (!S_ISSOCK(sb.st_mode)) {
errno = ENOTSOCK;
goto not_found;
}
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
@@ -77,15 +66,19 @@ client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
goto not_found;
}
if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket");
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket failed");
if (connect(
cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
if (errno == ECONNREFUSED) {
if (unlink(path) != 0 || !start_server)
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
if (!(cmdflags & CMD_STARTSERVER))
goto not_found;
switch (errno) {
case ECONNREFUSED:
if (unlink(path) != 0)
goto not_found;
if ((cctx->srv_fd = server_start(path)) == -1)
/* FALLTHROUGH */
case ENOENT:
if ((fd = server_start(path)) == -1)
goto start_failed;
goto server_started;
}
@@ -93,141 +86,240 @@ client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
}
server_started:
if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
if ((mode = fcntl(fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
cctx->srv_in = buffer_create(BUFSIZ);
cctx->srv_out = buffer_create(BUFSIZ);
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
imsg_init(&client_ibuf, fd);
if (isatty(STDIN_FILENO)) {
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
data.version = PROTOCOL_VERSION;
data.flags = flags;
data.sx = ws.ws_col;
data.sy = ws.ws_row;
*data.tty = '\0';
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0';
if (cmdflags & CMD_SENDENVIRON)
client_send_environ();
if (isatty(STDIN_FILENO))
client_send_identify(flags);
if ((name = ttyname(STDIN_FILENO)) == NULL)
fatal("ttyname failed");
if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty)
fatalx("ttyname failed");
b = buffer_create(BUFSIZ);
cmd_send_string(b, getenv("TERM"));
client_write_server2(cctx, MSG_IDENTIFY,
&data, sizeof data, BUFFER_OUT(b), BUFFER_USED(b));
buffer_destroy(b);
}
return (0);
return (&client_ibuf);
start_failed:
log_warnx("server failed to start");
return (1);
return (NULL);
not_found:
log_warn("server not found");
return (1);
return (NULL);
}
int
client_main(struct client_ctx *cctx)
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)
*data.term = '\0';
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf,
MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
}
void
client_send_environ(void)
{
struct msg_environ_data data;
char **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);
}
}
void
client_write_server(enum msgtype type, void *buf, size_t len)
{
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
__dead void
client_main(void)
{
struct pollfd pfd;
char *error;
int xtimeout; /* Yay for ncurses namespace! */
int n, nfds;
siginit();
logfile("client");
error = NULL;
while (!sigterm) {
/*
* 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.
*/
if (client_dispatch() != 0)
goto out;
for (;;) {
if (sigterm) {
client_exitmsg = "terminated";
client_write_server(MSG_EXITING, NULL, 0);
}
if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG);
sigchld = 0;
waitpid(WAIT_ANY, NULL, WNOHANG);
continue;
}
if (sigwinch) {
sigwinch = 0;
client_write_server(MSG_RESIZE, NULL, 0);
continue;
}
if (sigwinch)
client_handle_winch(cctx);
if (sigcont) {
siginit();
client_write_server(cctx, MSG_WAKEUP, NULL, 0);
sigcont = 0;
siginit();
client_write_server(MSG_WAKEUP, NULL, 0);
continue;
}
switch (client_msg_dispatch(cctx, &error)) {
case -1:
goto out;
case 0:
/* May be more in buffer, don't let poll block. */
xtimeout = 0;
break;
default:
/* Out of data, poll may block. */
xtimeout = INFTIM;
break;
}
pfd.fd = cctx->srv_fd;
pfd.fd = client_ibuf.fd;
pfd.events = POLLIN;
if (BUFFER_USED(cctx->srv_out) > 0)
if (client_ibuf.w.queued > 0)
pfd.events |= POLLOUT;
if (poll(&pfd, 1, xtimeout) == -1) {
if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
if (nfds == 0)
continue;
if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
goto server_dead;
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;
}
}
}
out:
if (sigterm) {
printf("[terminated]\n");
return (1);
}
if (cctx->flags & CCTX_SHUTDOWN) {
printf("[server exited]\n");
return (0);
/* Print the exit message, if any, and exit. */
if (client_exitmsg != NULL) {
if (!login_shell)
printf("[%s]\n", client_exitmsg);
exit(1);
}
exit(0);
}
if (cctx->flags & CCTX_EXIT) {
printf("[exited]\n");
return (0);
int
client_dispatch(void)
{
struct imsg imsg;
struct msg_lock_data lockdata;
ssize_t n, datalen;
for (;;) {
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
fatalx("imsg_get failed");
if (n == 0)
return (0);
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
switch (imsg.hdr.type) {
case MSG_DETACH:
if (datalen != 0)
fatalx("bad MSG_DETACH size");
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "detached";
break;
case MSG_EXIT:
if (datalen != 0)
fatalx("bad MSG_EXIT size");
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "exited";
break;
case MSG_EXITED:
if (datalen != 0)
fatalx("bad MSG_EXITED size");
imsg_free(&imsg);
return (-1);
case MSG_SHUTDOWN:
if (datalen != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "server exited";
break;
case MSG_SUSPEND:
if (datalen != 0)
fatalx("bad MSG_SUSPEND size");
client_suspend();
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);
break;
default:
fatalx("unexpected message");
}
imsg_free(&imsg);
}
if (cctx->flags & CCTX_DETACH) {
printf("[detached]\n");
return (0);
}
printf("[error: %s]\n", error);
return (1);
server_dead:
printf("[lost server]\n");
return (0);
}
void
client_handle_winch(struct client_ctx *cctx)
client_suspend(void)
{
struct msg_resize_data data;
struct winsize ws;
struct sigaction act;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl failed");
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
data.sx = ws.ws_col;
data.sy = ws.ws_row;
client_write_server(cctx, MSG_RESIZE, &data, sizeof data);
act.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &act, NULL) != 0)
fatal("sigaction failed");
sigwinch = 0;
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
}

16
clock.c
View File

@@ -1,4 +1,4 @@
/* $Id: clock.c,v 1.4 2009-05-04 17:58:25 nicm Exp $ */
/* $Id: clock.c,v 1.7 2009-09-11 14:13:52 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -112,8 +112,6 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
strftime(tim, sizeof tim, "%H:%M", localtime(&t));
screen_write_clearscreen(ctx);
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = colour;
if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) {
if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) {
@@ -121,7 +119,8 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
y = screen_size_y(s) / 2;
screen_write_cursormove(ctx, x, y);
gc.fg = colour;
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_fg(&gc, colour);
screen_write_puts(ctx, &gc, "%s", tim);
}
return;
@@ -130,6 +129,8 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
x = (screen_size_x(s) / 2) - 3 * strlen(tim);
y = (screen_size_y(s) / 2) - 3;
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_bg(&gc, colour);
for (ptr = tim; *ptr != '\0'; ptr++) {
if (*ptr >= '0' && *ptr <= '9')
idx = *ptr - '0';
@@ -147,13 +148,10 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
}
for (j = 0; j < 5; j++) {
screen_write_cursormove(ctx, x, y + j);
for (i = 0; i < 5; i++) {
screen_write_cursormove(ctx, x + i, y + j);
if (clock_table[idx][j][i])
gc.attr |= GRID_ATTR_REVERSE;
else
gc.attr &= ~GRID_ATTR_REVERSE;
screen_write_putc(ctx, &gc, ' ');
screen_write_putc(ctx, &gc, ' ');
}
}
x += 6;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-attach-session.c,v 1.26 2009-06-25 16:34:50 nicm Exp $ */
/* $Id: cmd-attach-session.c,v 1.32 2009-08-09 17:48:55 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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_DFLAG|CMD_CANTNEST|CMD_STARTSERVER,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, CMD_CHFLAG('d'),
cmd_target_init,
cmd_target_parse,
cmd_attach_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,10 +42,10 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
char *cause;
if (ctx->curclient != NULL)
return (0);
struct client *c;
const char *update;
char *overrides, *cause;
u_int i;
if (ARRAY_LENGTH(&sessions) == 0) {
ctx->error(ctx, "no sessions");
@@ -56,24 +54,53 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
if (ctx->cmdclient == NULL && ctx->curclient == NULL)
return (0);
if (ctx->cmdclient == NULL) {
if (data->chflags & CMD_CHFLAG('d')) {
/*
* Can't use server_write_session in case attaching to
* the same session as currently attached to.
*/
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (c == ctx->curclient)
continue;
server_write_client(c, MSG_DETACH, NULL, 0);
}
}
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
} else {
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
overrides =
options_get_string(&s->options, "terminal-overrides");
if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "terminal open failed: %s", cause);
xfree(cause);
return (-1);
}
if (data->chflags & CMD_CHFLAG('d'))
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
update = options_get_string(&s->options, "update-environment");
environ_update(update, &ctx->cmdclient->environ, &s->environ);
server_redraw_client(ctx->cmdclient);
}
if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
ctx->error(ctx, "terminal open failed: %s", cause);
xfree(cause);
return (-1);
}
if (data->flags & CMD_DFLAG)
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
recalculate_sizes();
server_redraw_client(ctx->cmdclient);
return (1);
return (1); /* 1 means don't tell command client to exit */
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-bind-key.c,v 1.21 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-bind-key.c,v 1.25 2009-07-28 23:19:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,8 @@
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/*
@@ -26,26 +28,28 @@
int cmd_bind_key_parse(struct cmd *, int, char **, char **);
int cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
void cmd_bind_key_send(struct cmd *, struct buffer *);
void cmd_bind_key_recv(struct cmd *, struct buffer *);
void cmd_bind_key_free(struct cmd *);
size_t cmd_bind_key_print(struct cmd *, char *, size_t);
int cmd_bind_key_table(struct cmd *, struct cmd_ctx *);
struct cmd_bind_key_data {
int key;
int can_repeat;
struct cmd_list *cmdlist;
int command_key;
char *tablename;
char *modecmd;
};
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
"[-r] key command [arguments]",
0,
"[-cnr] [-t key-table] key command [arguments]",
0, 0,
NULL,
cmd_bind_key_parse,
cmd_bind_key_exec,
cmd_bind_key_send,
cmd_bind_key_recv,
cmd_bind_key_free,
cmd_bind_key_print
};
@@ -54,17 +58,29 @@ int
cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_bind_key_data *data;
int opt;
int opt, no_prefix = 0;
self->data = data = xmalloc(sizeof *data);
data->can_repeat = 0;
data->cmdlist = NULL;
data->command_key = 0;
data->tablename = NULL;
data->modecmd = NULL;
while ((opt = getopt(argc, argv, "r")) != -1) {
while ((opt = getopt(argc, argv, "cnrt:")) != -1) {
switch (opt) {
case 'c':
data->command_key = 1;
break;
case 'n':
no_prefix = 1;
break;
case 'r':
data->can_repeat = 1;
break;
case 't':
data->tablename = xstrdup(optarg);
break;
default:
goto usage;
}
@@ -78,11 +94,19 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
xasprintf(cause, "unknown key: %s", argv[0]);
goto error;
}
if (!no_prefix)
data->key |= KEYC_PREFIX;
argc--;
argv++;
if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
goto error;
if (data->tablename != NULL) {
if (argc != 1)
goto usage;
data->modecmd = xstrdup(argv[0]);
} else {
if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
goto error;
}
return (0);
@@ -101,6 +125,8 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
if (data == NULL)
return (0);
if (data->tablename != NULL)
return (cmd_bind_key_table(self, ctx));
key_bindings_add(data->key, data->can_repeat, data->cmdlist);
data->cmdlist = NULL; /* avoid free */
@@ -108,23 +134,37 @@ cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
return (0);
}
void
cmd_bind_key_send(struct cmd *self, struct buffer *b)
int
cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_bind_key_data *data = self->data;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
enum mode_key_cmd cmd;
buffer_write(b, data, sizeof *data);
cmd_list_send(data->cmdlist, b);
}
if ((mtab = mode_key_findtable(data->tablename)) == NULL) {
ctx->error(ctx, "unknown key table: %s", data->tablename);
return (-1);
}
void
cmd_bind_key_recv(struct cmd *self, struct buffer *b)
{
struct cmd_bind_key_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->cmdlist = cmd_list_recv(b);
cmd = mode_key_fromstring(mtab->cmdstr, data->modecmd);
if (cmd == MODEKEY_NONE) {
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) {
mbind->cmd = cmd;
return (0);
}
mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key;
mbind->mode = mtmp.mode;
mbind->cmd = cmd;
SPLAY_INSERT(mode_key_tree, mtab->tree, mbind);
return (0);
}
void
@@ -134,6 +174,10 @@ cmd_bind_key_free(struct cmd *self)
if (data->cmdlist != NULL)
cmd_list_free(data->cmdlist);
if (data->tablename != NULL)
xfree(data->tablename);
if (data->modecmd != NULL)
xfree(data->modecmd);
xfree(data);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.3 2009-05-18 21:01:38 nicm Exp $ */
/* $Id: cmd-break-pane.c,v 1.9 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,41 +30,31 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp",
CMD_PANE_WINDOW_USAGE " [-d]",
CMD_DFLAG,
cmd_pane_init,
cmd_pane_parse,
CMD_TARGET_PANE_USAGE " [-d]",
0, CMD_CHFLAG('d'),
cmd_target_init,
cmd_target_parse,
cmd_break_pane_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
cmd_target_free,
cmd_target_print
};
int
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct session *s;
struct window_pane *wp;
struct window *w;
char *cause;
int base_idx;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (window_count_panes(wl->window) == 1) {
ctx->error(ctx, "can't break pane: %d", data->pane);
ctx->error(ctx, "can't break with only one pane");
return (-1);
}
@@ -74,19 +64,21 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl->window->active == NULL)
wl->window->active = TAILQ_NEXT(wp, entry);
}
layout_refresh(wl->window, 0);
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);
layout_init(w);
wl = session_attach(s, w, -1, &cause); /* can't fail */
if (!(data->flags & CMD_DFLAG))
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);
layout_refresh(w, 0);
server_redraw_session(s);
server_status_session_group(s);
return (0);
}

152
cmd-choose-client.c Normal file
View File

@@ -0,0 +1,152 @@
/* $Id: cmd-choose-client.c,v 1.3 2009-09-07 23:59:19 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 <ctype.h>
#include "tmux.h"
/*
* Enter choice mode to choose a client.
*/
int cmd_choose_client_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_client_callback(void *, int);
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_target_init,
cmd_target_parse,
cmd_choose_client_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_choose_client_data {
struct client *client;
char *template;
};
int
cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_choose_client_data *cdata;
struct winlink *wl;
struct client *c;
u_int i, idx, cur;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c == ctx->curclient)
cur = idx;
idx++;
window_choose_add(wl->window->active, i,
"%s: %s [%ux%u %s]%s", c->tty.path,
c->session->name, c->tty.sx, c->tty.sy,
c->tty.termname, c->tty.flags & TTY_UTF8 ? " (utf8)" : "");
}
cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL)
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("detach-client -t '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
cur, cmd_choose_client_callback, cmd_choose_client_free, cdata);
return (0);
}
void
cmd_choose_client_callback(void *data, int idx)
{
struct cmd_choose_client_data *cdata = data;
struct client *c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause;
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
if ((u_int) idx > ARRAY_LENGTH(&clients) - 1)
return;
c = ARRAY_ITEM(&clients, idx);
if (c == NULL || c->session == NULL)
return;
template = cmd_template_replace(cdata->template, c->tty.path, 1);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, "%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_client_free(void *data)
{
struct cmd_choose_client_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-session.c,v 1.7 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-choose-session.c,v 1.14 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,8 @@
#include <sys/types.h>
#include <ctype.h>
#include "tmux.h"
/*
@@ -27,22 +29,22 @@
int cmd_choose_session_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_session_callback(void *, int);
void cmd_choose_session_free(void *);
const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL,
CMD_TARGET_WINDOW_USAGE,
0,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_choose_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
struct cmd_choose_session_data {
u_int client;
struct client *client;
char *template;
};
int
@@ -52,7 +54,9 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_choose_session_data *cdata;
struct winlink *wl;
struct session *s;
struct session_group *sg;
u_int i, idx, cur;
char tmp[64];
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
@@ -74,17 +78,30 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx;
idx++;
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
else {
idx = session_group_index(sg);
xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
}
window_choose_add(wl->window->active, i,
"%s: %u windows [%ux%u]%s", s->name,
"%s: %u windows [%ux%u]%s%s", s->name,
winlink_count(&s->windows), s->sx, s->sy,
s->flags & SESSION_UNATTACHED ? "" : " (attached)");
tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
}
cdata = xmalloc(sizeof *cdata);
cdata->client = server_client_index(ctx->curclient);
if (data->arg != NULL)
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("switch-client -t '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(
wl->window->active, cur, cmd_choose_session_callback, cdata);
window_choose_ready(wl->window->active,
cur, cmd_choose_session_callback, cmd_choose_session_free, cdata);
return (0);
}
@@ -93,15 +110,53 @@ void
cmd_choose_session_callback(void *data, int idx)
{
struct cmd_choose_session_data *cdata = data;
struct client *c;
struct session *s;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause;
if (idx != -1 && cdata->client <= ARRAY_LENGTH(&clients) - 1) {
c = ARRAY_ITEM(&clients, cdata->client);
if (c != NULL && (u_int) idx <= ARRAY_LENGTH(&sessions) - 1) {
c->session = ARRAY_ITEM(&sessions, idx);
recalculate_sizes();
server_redraw_client(c);
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
if ((u_int) idx > ARRAY_LENGTH(&sessions) - 1)
return;
s = ARRAY_ITEM(&sessions, idx);
if (s == NULL)
return;
template = cmd_template_replace(cdata->template, s->name, 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_session_free(void *data)
{
struct cmd_choose_session_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-window.c,v 1.9 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-choose-window.c,v 1.18 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,8 @@
#include <sys/types.h>
#include <ctype.h>
#include "tmux.h"
/*
@@ -27,22 +29,23 @@
int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_window_callback(void *, int);
void cmd_choose_window_free(void *);
const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL,
CMD_TARGET_WINDOW_USAGE,
0,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_choose_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
struct cmd_choose_window_data {
u_int session;
struct client *client;
struct session *session;
char *template;
};
int
@@ -54,6 +57,8 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl, *wm;
struct window *w;
u_int idx, cur;
char flag, *title;
const char *left, *right;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
@@ -75,17 +80,44 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx;
idx++;
flag = ' ';
if (session_alert_has(s, wm, WINDOW_ACTIVITY))
flag = '#';
else if (session_alert_has(s, wm, WINDOW_BELL))
flag = '!';
else if (session_alert_has(s, wm, WINDOW_CONTENT))
flag = '+';
else if (wm == s->curw)
flag = '*';
else if (wm == TAILQ_FIRST(&s->lastw))
flag = '-';
title = w->active->screen->title;
if (wm == wl)
title = w->active->base.title;
left = " \"";
right = "\"";
if (*title == '\0')
left = right = "";
window_choose_add(wl->window->active,
wm->idx, "%3d: %s [%ux%u %s] (%u panes)", wm->idx, w->name,
w->sx, w->sy, layout_name(w), window_count_panes(w));
wm->idx, "%3d: %s%c [%ux%u] (%u panes)%s%s%s",
wm->idx, w->name, flag, w->sx, w->sy, window_count_panes(w),
left, title, right);
}
cdata = xmalloc(sizeof *cdata);
if (session_index(s, &cdata->session) != 0)
fatalx("session not found");
if (data->arg != NULL)
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("select-window -t '%%'");
cdata->session = s;
cdata->session->references++;
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(
wl->window->active, cur, cmd_choose_window_callback, cdata);
window_choose_ready(wl->window->active,
cur, cmd_choose_window_callback, cmd_choose_window_free, cdata);
return (0);
}
@@ -94,13 +126,54 @@ void
cmd_choose_window_callback(void *data, int idx)
{
struct cmd_choose_window_data *cdata = data;
struct session *s;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *target, *template, *cause;
if (idx != -1 && cdata->session <= ARRAY_LENGTH(&sessions) - 1) {
s = ARRAY_ITEM(&sessions, cdata->session);
if (s != NULL && session_select(s, idx) == 0)
server_redraw_session(s);
recalculate_sizes();
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
if (cdata->session->flags & SESSION_DEAD)
return;
if (cdata->client->session != cdata->session)
return;
xasprintf(&target, "%s:%d", cdata->session->name, idx);
template = cmd_template_replace(cdata->template, target, 1);
xfree(target);
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_window_free(void *data)
{
struct cmd_choose_window_data *cdata = data;
cdata->session->references--;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clear-history.c,v 1.3 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cmd-clear-history.c,v 1.7 2009-07-30 21:04:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,36 +28,24 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
CMD_PANE_WINDOW_USAGE,
0,
cmd_pane_init,
cmd_pane_parse,
CMD_TARGET_PANE_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_clear_history_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
cmd_target_free,
cmd_target_print
};
int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
struct cmd_target_data *data = self->data;
struct window_pane *wp;
struct grid *gd;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clock-mode.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-clock-mode.c,v 1.6 2009-08-20 11:37:46 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,13 +28,11 @@ int cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
CMD_TARGET_WINDOW_USAGE,
0,
CMD_TARGET_PANE_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_clock_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -43,12 +41,12 @@ int
cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
window_pane_set_mode(wl->window->active, &window_clock_mode);
window_pane_set_mode(wp, &window_clock_mode);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-command-prompt.c,v 1.16 2009-02-16 18:58:14 nicm Exp $ */
/* $Id: cmd-command-prompt.c,v 1.26 2009-09-22 14:06:40 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,57 +27,111 @@
* Prompt for command in client.
*/
void cmd_command_prompt_init(struct cmd *, int);
int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
void cmd_command_prompt_init(struct cmd *, int);
int cmd_command_prompt_parse(struct cmd *, int, char **, char **);
int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
void cmd_command_prompt_free(struct cmd *);
size_t cmd_command_prompt_print(struct cmd *, char *, size_t);
int cmd_command_prompt_callback(void *, const char *);
int cmd_command_prompt_callback(void *, const char *);
void cmd_command_prompt_cfree(void *);
const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL,
CMD_TARGET_CLIENT_USAGE " [template]",
CMD_ARG01,
CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]",
0, 0,
cmd_command_prompt_init,
cmd_target_parse,
cmd_command_prompt_parse,
cmd_command_prompt_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
cmd_command_prompt_free,
cmd_command_prompt_print
};
struct cmd_command_prompt_data {
char *prompts;
char *target;
char *template;
};
struct cmd_command_prompt_cdata {
struct client *c;
char *next_prompt;
char *prompts;
char *template;
int idx;
};
void
cmd_command_prompt_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
struct cmd_command_prompt_data *data;
cmd_target_init(self, key);
data = self->data;
self->data = data = xmalloc(sizeof *data);
data->prompts = NULL;
data->target = NULL;
data->template = NULL;
switch (key) {
case ',':
data->arg = xstrdup("rename-window '%%'");
data->template = xstrdup("rename-window '%%'");
break;
case '.':
data->arg = xstrdup("move-window -t '%%'");
data->template = xstrdup("move-window -t '%%'");
break;
case 'f':
data->arg = xstrdup("find-window '%%'");
data->template = xstrdup("find-window '%%'");
break;
}
}
int
cmd_command_prompt_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_command_prompt_data *data;
int opt;
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "p:t:")) != -1) {
switch (opt) {
case 'p':
if (data->prompts == NULL)
data->prompts = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 0 && argc != 1)
goto usage;
if (argc == 1)
data->template = xstrdup(argv[0]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_command_prompt_data *cdata;
struct cmd_command_prompt_data *data = self->data;
struct cmd_command_prompt_cdata *cdata;
struct client *c;
char *hdr, *ptr;
char *prompt, *ptr;
size_t n;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
@@ -87,80 +141,102 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata = xmalloc(sizeof *cdata);
cdata->c = c;
if (data->arg != NULL) {
cdata->template = xstrdup(data->arg);
if ((ptr = strchr(data->arg, ' ')) == NULL)
ptr = strchr(data->arg, '\0');
xasprintf(&hdr, "(%.*s) ", (int) (ptr - data->arg), data->arg);
} else {
cdata->template = NULL;
hdr = xstrdup(":");
}
status_prompt_set(c, hdr, cmd_command_prompt_callback, cdata, 0);
xfree(hdr);
cdata->idx = 1;
cdata->next_prompt = NULL;
cdata->prompts = NULL;
cdata->template = NULL;
if (data->template != NULL)
cdata->template = xstrdup(data->template);
else
cdata->template = xstrdup("%1");
if (data->prompts != NULL)
cdata->prompts = xstrdup(data->prompts);
else if (data->template != NULL) {
n = strcspn(data->template, " ,");
xasprintf(&cdata->prompts, "(%.*s) ", (int) n, data->template);
} else
cdata->prompts = xstrdup(":");
cdata->next_prompt = cdata->prompts;
ptr = strsep(&cdata->next_prompt, ",");
if (data->prompts == NULL)
prompt = xstrdup(ptr);
else
xasprintf(&prompt, "%s ", ptr);
status_prompt_set(c, prompt, cmd_command_prompt_callback,
cmd_command_prompt_cfree, cdata, 0);
xfree(prompt);
return (0);
}
void
cmd_command_prompt_free(struct cmd *self)
{
struct cmd_command_prompt_data *data = self->data;
if (data->prompts != NULL)
xfree(data->prompts);
if (data->target != NULL)
xfree(data->target);
if (data->template != NULL)
xfree(data->template);
xfree(data);
}
size_t
cmd_command_prompt_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_command_prompt_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->prompts != NULL)
off += cmd_prarg(buf + off, len - off, " -p ", data->prompts);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->template != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->template);
return (off);
}
int
cmd_command_prompt_callback(void *data, const char *s)
{
struct cmd_command_prompt_data *cdata = data;
struct cmd_command_prompt_cdata *cdata = data;
struct client *c = cdata->c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *cause, *ptr, *buf, ch;
size_t len, slen;
struct cmd_ctx ctx;
char *cause, *newtempl, *prompt, *ptr;
if (s == NULL) {
xfree(cdata);
if (s == NULL)
return (0);
newtempl = cmd_template_replace(cdata->template, s, cdata->idx);
xfree(cdata->template);
cdata->template = newtempl;
if ((ptr = strsep(&cdata->next_prompt, ",")) != NULL) {
xasprintf(&prompt, "%s ", ptr);
status_prompt_update(c, prompt);
xfree(prompt);
cdata->idx++;
return (1);
}
slen = strlen(s);
len = 0;
buf = NULL;
if (cdata->template != NULL) {
ptr = cdata->template;
while (*ptr != '\0') {
switch (ch = *ptr++) {
case '%':
if (*ptr != '%')
break;
ptr++;
buf = xrealloc(buf, 1, len + slen + 1);
memcpy(buf + len, s, slen);
len += slen;
break;
default:
buf = xrealloc(buf, 1, len + 2);
buf[len++] = ch;
break;
}
if (cmd_string_parse(newtempl, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, "%s", cause);
xfree(cause);
}
xfree(cdata->template);
buf[len] = '\0';
s = buf;
}
xfree(cdata);
if (cmd_string_parse(s, &cmdlist, &cause) != 0) {
if (cause == NULL)
return (0);
*cause = toupper((u_char) *cause);
status_message_set(c, cause);
xfree(cause);
cmdlist = NULL;
}
if (buf != NULL)
xfree(buf);
if (cmdlist == NULL)
return (0);
}
ctx.msgdata = NULL;
ctx.cursession = c->session;
ctx.curclient = c;
ctx.error = key_bindings_error;
@@ -172,7 +248,19 @@ cmd_command_prompt_callback(void *data, const char *s)
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
if (c->prompt_callback != (void *) &cmd_command_prompt_callback)
if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
return (1);
return (0);
}
void
cmd_command_prompt_cfree(void *data)
{
struct cmd_command_prompt_cdata *cdata = data;
if (cdata->prompts != NULL)
xfree(cdata->prompts);
if (cdata->template != NULL)
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-confirm-before.c,v 1.4 2009-04-28 18:29:44 tcunha Exp $ */
/* $Id: cmd-confirm-before.c,v 1.11 2009-08-24 16:24:18 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -29,25 +29,24 @@ int cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *);
void cmd_confirm_before_init(struct cmd *, int);
int cmd_confirm_before_callback(void *, const char *);
struct cmd_confirm_before_data {
struct client *c;
char *cmd;
};
void cmd_confirm_before_free(void *);
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
CMD_TARGET_CLIENT_USAGE " command",
CMD_ARG1,
CMD_ARG1, 0,
cmd_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
struct cmd_confirm_before_data {
struct client *c;
char *cmd;
};
void
cmd_confirm_before_init(struct cmd *self, int key)
{
@@ -67,7 +66,7 @@ cmd_confirm_before_init(struct cmd *self, int key)
}
int
cmd_confirm_before_exec(unused struct cmd *self, struct cmd_ctx *ctx)
cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_confirm_before_data *cdata;
@@ -91,8 +90,9 @@ cmd_confirm_before_exec(unused struct cmd *self, struct cmd_ctx *ctx)
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg);
cdata->c = c;
status_prompt_set(
cdata->c, buf, cmd_confirm_before_callback, cdata, PROMPT_SINGLE);
status_prompt_set(cdata->c, buf,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
PROMPT_SINGLE);
xfree(buf);
return (1);
@@ -107,20 +107,21 @@ cmd_confirm_before_callback(void *data, const char *s)
struct cmd_ctx ctx;
char *cause;
if (s == NULL || tolower((u_char) s[0]) != 'y' || s[1] != '\0')
goto out;
if (s == NULL || *s == '\0')
return (0);
if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
return (0);
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, cause);
status_message_set(c, "%s", cause);
xfree(cause);
}
goto out;
return (0);
}
ctx.msgdata = NULL;
ctx.cursession = c->session;
ctx.curclient = c;
ctx.error = key_bindings_error;
@@ -132,10 +133,15 @@ cmd_confirm_before_callback(void *data, const char *s)
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
out:
return (0);
}
void
cmd_confirm_before_free(void *data)
{
struct cmd_confirm_before_data *cdata = data;
if (cdata->cmd != NULL)
xfree(cdata->cmd);
xfree(cdata);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-buffer.c,v 1.1 2009-02-03 17:21:19 tcunha Exp $ */
/* $Id: cmd-copy-buffer.c,v 1.5 2009-09-22 14:06:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -16,7 +16,10 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -26,8 +29,6 @@
int cmd_copy_buffer_parse(struct cmd *, int, char **, char **);
int cmd_copy_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_copy_buffer_send(struct cmd *, struct buffer *);
void cmd_copy_buffer_recv(struct cmd *, struct buffer *);
void cmd_copy_buffer_free(struct cmd *);
void cmd_copy_buffer_init(struct cmd *, int);
size_t cmd_copy_buffer_print(struct cmd *, char *, size_t);
@@ -42,12 +43,10 @@ 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,
cmd_copy_buffer_send,
cmd_copy_buffer_recv,
cmd_copy_buffer_free,
cmd_copy_buffer_print
};
@@ -71,7 +70,7 @@ cmd_copy_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
const char *errstr;
int n, opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "a:b:s:t:")) != -1) {
@@ -126,61 +125,44 @@ cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_copy_buffer_data *data = self->data;
struct paste_buffer *pb;
struct paste_stack *dst_ps, *src_ps;
u_char *pdata;
struct session *dst_session, *src_session;
u_int limit;
if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL ||
(src_session = cmd_find_session(ctx, data->src_session)) == NULL)
return (-1);
dst_ps = &dst_session->buffers;
src_ps = &src_session->buffers;
if (data->src_idx == -1) {
if ((pb = paste_get_top(&src_session->buffers)) == NULL) {
if ((pb = paste_get_top(src_ps)) == NULL) {
ctx->error(ctx, "no buffers");
return (-1);
}
} else {
if ((pb = paste_get_index(&src_session->buffers,
data->src_idx)) == NULL) {
if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) {
ctx->error(ctx, "no buffer %d", data->src_idx);
return (-1);
}
}
limit = options_get_number(&dst_session->options, "buffer-limit");
if (data->dst_idx == -1) {
paste_add(&dst_session->buffers, xstrdup(pb->data), limit);
return (0);
}
if (paste_replace(&dst_session->buffers, data->dst_idx,
xstrdup(pb->data)) != 0) {
pdata = xmalloc(pb->size);
memcpy(pdata, pb->data, pb->size);
if (data->dst_idx == -1)
paste_add(dst_ps, pdata, pb->size, limit);
else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) {
ctx->error(ctx, "no buffer %d", data->dst_idx);
xfree(pdata);
return (-1);
}
return (0);
}
void
cmd_copy_buffer_send(struct cmd *self, struct buffer *b)
{
struct cmd_copy_buffer_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->dst_session);
cmd_send_string(b, data->src_session);
}
void
cmd_copy_buffer_recv(struct cmd *self, struct buffer *b)
{
struct cmd_copy_buffer_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->dst_session = cmd_recv_string(b);
data->src_session = cmd_recv_string(b);
}
void
cmd_copy_buffer_free(struct cmd *self)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-mode.c,v 1.19 2009-07-01 23:06:32 nicm Exp $ */
/* $Id: cmd-copy-mode.c,v 1.24 2009-10-06 14:14:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,34 +24,46 @@
* Enter copy mode.
*/
void cmd_copy_mode_init(struct cmd *, int);
int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
CMD_TARGET_WINDOW_USAGE,
CMD_UFLAG,
cmd_target_init,
"[-u] " CMD_TARGET_PANE_USAGE,
0, CMD_CHFLAG('u'),
cmd_copy_mode_init,
cmd_target_parse,
cmd_copy_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
NULL
};
void
cmd_copy_mode_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case KEYC_PPAGE:
data->chflags |= CMD_CHFLAG('u');
break;
}
}
int
cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
wp = wl->window->active;
window_pane_set_mode(wp, &window_copy_mode);
if (wp->mode == &window_copy_mode && data->flags & CMD_UFLAG)
if (wp->mode == &window_copy_mode && data->chflags & CMD_CHFLAG('u'))
window_copy_pageup(wp);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-delete-buffer.c,v 1.5 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-delete-buffer.c,v 1.7 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-detach-client.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-detach-client.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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, 0,
cmd_target_init,
cmd_target_parse,
cmd_detach_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

63
cmd-display-message.c Normal file
View File

@@ -0,0 +1,63 @@
/* $Id: cmd-display-message.c,v 1.3 2009-10-11 23:55:26 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <time.h>
#include "tmux.h"
/*
* Displays a message in the status line.
*/
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,
cmd_target_init,
cmd_target_parse,
cmd_display_message_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
const char *template;
char *msg;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
if (data->arg == NULL)
template = "[#S] #I:#W, current pane #P - (%H:%M %d-%b-%y)";
else
template = data->arg;
msg = status_replace(c, template, time(NULL));
status_message_set(c, "%s", msg);
xfree(msg);
return (0);
}

52
cmd-display-panes.c Normal file
View File

@@ -0,0 +1,52 @@
/* $Id: cmd-display-panes.c,v 1.1 2009-08-31 22:30:15 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"
/*
* Display panes on a client.
*/
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,
cmd_target_init,
cmd_target_parse,
cmd_display_panes_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_display_panes_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);
server_set_identify(c);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-down-pane.c,v 1.7 2009-04-01 21:10:08 nicm Exp $ */
/* $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>
@@ -29,12 +29,10 @@ 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, 0,
cmd_target_init,
cmd_target_parse,
cmd_down_pane_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -54,8 +52,8 @@ cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_NEXT(w->active, entry);
if (w->active == NULL)
w->active = TAILQ_FIRST(&w->panes);
layout_refresh(w, 1);
} while (w->active->flags & PANE_HIDDEN);
} 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.10 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cmd-find-window.c,v 1.13 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,12 +34,10 @@ 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,
CMD_ARG1, 0,
cmd_target_init,
cmd_target_parse,
cmd_find_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -140,7 +138,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
fatalx("session not found");
window_choose_ready(
wl->window->active, 0, cmd_find_window_callback, cdata);
wl->window->active, 0, cmd_find_window_callback, xfree, cdata);
out:
ARRAY_FREE(&list_idx);
@@ -161,5 +159,4 @@ cmd_find_window_callback(void *data, int idx)
server_redraw_session(s);
recalculate_sizes();
}
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.28 2009-05-21 19:47:57 nicm Exp $ */
/* $Id: cmd-generic.c,v 1.34 2009-08-26 22:13:52 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,13 +23,10 @@
#include "tmux.h"
#define CMD_FLAGS "adDgkuU"
#define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_BIGDFLAG|CMD_GFLAG|CMD_KFLAG| \
CMD_UFLAG|CMD_BIGUFLAG)
int cmd_do_flags(int, int, int *);
size_t cmd_print_flags(char *, size_t, size_t, int);
int cmd_fill_argument(int, char **, int, char **);
int cmd_getopt(int, char **, const char *, uint64_t);
int cmd_flags(int, uint64_t, uint64_t *);
size_t cmd_print_flags(char *, size_t, size_t, uint64_t);
int cmd_fill_argument(int, char **, char **, int, char **);
size_t
cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
@@ -39,85 +36,78 @@ 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. */
int
cmd_do_flags(int opt, int iflags, int *oflags)
cmd_getopt(int argc, char **argv, const char *flagstr, uint64_t chflags)
{
switch (opt) {
case 'a':
if (iflags & CMD_AFLAG) {
(*oflags) |= CMD_AFLAG;
return (0);
}
return (-1);
case 'd':
if (iflags & CMD_DFLAG) {
(*oflags) |= CMD_DFLAG;
return (0);
}
return (-1);
case 'D':
if (iflags & CMD_BIGDFLAG) {
(*oflags) |= CMD_BIGDFLAG;
return (0);
}
return (-1);
case 'g':
if (iflags & CMD_GFLAG) {
(*oflags) |= CMD_GFLAG;
return (0);
}
return (-1);
case 'k':
if (iflags & CMD_KFLAG) {
(*oflags) |= CMD_KFLAG;
return (0);
}
return (-1);
case 'u':
if (iflags & CMD_UFLAG) {
(*oflags) |= CMD_UFLAG;
return (0);
}
return (-1);
case 'U':
if (iflags & CMD_BIGUFLAG) {
(*oflags) |= CMD_BIGUFLAG;
return (0);
}
return (-1);
u_char ch;
char buf[128];
size_t len, off;
*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);
}
return (1);
strlcat(buf, flagstr, sizeof buf);
return (getopt(argc, argv, buf));
}
size_t
cmd_print_flags(char *buf, size_t len, size_t off, int flags)
/*
* If this option is expected (in ichflags), set it in ochflags, otherwise
* return -1.
*/
int
cmd_flags(int opt, uint64_t ichflags, uint64_t *ochflags)
{
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);
}
/* Print the flags supported in chflags. */
size_t
cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags)
{
u_char ch;
size_t boff = off;
if ((flags & CMD_FLAGMASK) == 0)
if (chflags == 0)
return (0);
off += xsnprintf(buf + off, len - off, " -");
if (off < len && flags & CMD_AFLAG)
off += xsnprintf(buf + off, len - off, "a");
if (off < len && flags & CMD_BIGDFLAG)
off += xsnprintf(buf + off, len - off, "D");
if (off < len && flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, "d");
if (off < len && flags & CMD_GFLAG)
off += xsnprintf(buf + off, len - off, "g");
if (off < len && flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, "k");
if (off < len && flags & CMD_UFLAG)
off += xsnprintf(buf + off, len - off, "u");
if (off < len && flags & CMD_BIGUFLAG)
off += xsnprintf(buf + off, len - off, "U");
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);
}
return (off - boff);
}
int
cmd_fill_argument(int flags, char **arg, int argc, char **argv)
cmd_fill_argument(int flags, char **arg, char **arg2, int argc, char **argv)
{
*arg = NULL;
*arg2 = NULL;
if (flags & CMD_ARG1) {
if (argc != 1)
@@ -134,6 +124,23 @@ cmd_fill_argument(int flags, char **arg, int argc, char **argv)
return (0);
}
if (flags & CMD_ARG2) {
if (argc != 2)
return (-1);
*arg = xstrdup(argv[0]);
*arg2 = xstrdup(argv[1]);
return (0);
}
if (flags & CMD_ARG12) {
if (argc != 1 && argc != 2)
return (-1);
*arg = xstrdup(argv[0]);
if (argc == 2)
*arg2 = xstrdup(argv[1]);
return (0);
}
if (argc != 0)
return (-1);
return (0);
@@ -145,28 +152,26 @@ cmd_target_init(struct cmd *self, unused int key)
struct cmd_target_data *data;
self->data = data = xmalloc(sizeof *data);
data->flags = 0;
data->chflags = 0;
data->target = NULL;
data->arg = NULL;
data->arg2 = NULL;
}
int
cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_target_data *data;
const struct cmd_entry *entry = self->entry;
int opt;
/* Don't use the entry version since it may be dependent on key. */
cmd_target_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
while ((opt = cmd_getopt(argc, argv, "t:", entry->chflags)) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
}
switch (opt) {
case 't':
if (data->target == NULL)
@@ -179,7 +184,8 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
argc -= optind;
argv += optind;
if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
if (cmd_fill_argument(
self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
goto usage;
return (0);
@@ -190,27 +196,6 @@ usage:
return (-1);
}
void
cmd_target_send(struct cmd *self, struct buffer *b)
{
struct cmd_target_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->arg);
}
void
cmd_target_recv(struct cmd *self, struct buffer *b)
{
struct cmd_target_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void
cmd_target_free(struct cmd *self)
{
@@ -220,6 +205,8 @@ cmd_target_free(struct cmd *self)
xfree(data->target);
if (data->arg != NULL)
xfree(data->arg);
if (data->arg2 != NULL)
xfree(data->arg2);
xfree(data);
}
@@ -232,11 +219,13 @@ cmd_target_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
off += cmd_print_flags(buf, len, off, data->flags);
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)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}
@@ -246,28 +235,26 @@ cmd_srcdst_init(struct cmd *self, unused int key)
struct cmd_srcdst_data *data;
self->data = data = xmalloc(sizeof *data);
data->flags = 0;
data->chflags = 0;
data->src = NULL;
data->dst = NULL;
data->arg = NULL;
data->arg2 = NULL;
}
int
cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_srcdst_data *data;
const struct cmd_entry *entry = self->entry;
int opt;
cmd_srcdst_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, CMD_FLAGS "s:t:")) != -1) {
switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
while ((opt = cmd_getopt(argc, argv, "s:t:", entry->chflags)) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
}
switch (opt) {
case 's':
if (data->src == NULL)
@@ -284,7 +271,8 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
argc -= optind;
argv += optind;
if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
if (cmd_fill_argument(
self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
goto usage;
return (0);
@@ -295,29 +283,6 @@ usage:
return (-1);
}
void
cmd_srcdst_send(struct cmd *self, struct buffer *b)
{
struct cmd_srcdst_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->src);
cmd_send_string(b, data->dst);
cmd_send_string(b, data->arg);
}
void
cmd_srcdst_recv(struct cmd *self, struct buffer *b)
{
struct cmd_srcdst_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->src = cmd_recv_string(b);
data->dst = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void
cmd_srcdst_free(struct cmd *self)
{
@@ -329,6 +294,8 @@ cmd_srcdst_free(struct cmd *self)
xfree(data->dst);
if (data->arg != NULL)
xfree(data->arg);
if (data->arg2 != NULL)
xfree(data->arg2);
xfree(data);
}
@@ -341,13 +308,15 @@ cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
off += cmd_print_flags(buf, len, off, data->flags);
off += cmd_print_flags(buf, len, off, data->chflags);
if (off < len && data->src != NULL)
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)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}
@@ -357,29 +326,27 @@ cmd_buffer_init(struct cmd *self, unused int key)
struct cmd_buffer_data *data;
self->data = data = xmalloc(sizeof *data);
data->flags = 0;
data->chflags = 0;
data->target = NULL;
data->buffer = -1;
data->arg = NULL;
data->arg2 = NULL;
}
int
cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_buffer_data *data;
const struct cmd_entry *entry = self->entry;
int opt, n;
const char *errstr;
cmd_buffer_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, CMD_FLAGS "b:t:")) != -1) {
switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
while ((opt = cmd_getopt(argc, argv, "b:t:", entry->chflags)) != -1) {
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
}
switch (opt) {
case 'b':
if (data->buffer == -1) {
@@ -402,7 +369,8 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
argc -= optind;
argv += optind;
if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
if (cmd_fill_argument(
self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
goto usage;
return (0);
@@ -414,27 +382,6 @@ error:
return (-1);
}
void
cmd_buffer_send(struct cmd *self, struct buffer *b)
{
struct cmd_buffer_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->arg);
}
void
cmd_buffer_recv(struct cmd *self, struct buffer *b)
{
struct cmd_buffer_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void
cmd_buffer_free(struct cmd *self)
{
@@ -444,6 +391,8 @@ cmd_buffer_free(struct cmd *self)
xfree(data->target);
if (data->arg != NULL)
xfree(data->arg);
if (data->arg2 != NULL)
xfree(data->arg2);
xfree(data);
}
@@ -456,239 +405,14 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
off += cmd_print_flags(buf, len, off, data->flags);
off += cmd_print_flags(buf, len, off, data->chflags);
if (off < len && data->buffer != -1)
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)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
return (off);
}
void
cmd_option_init(struct cmd *self, unused int key)
{
struct cmd_option_data *data;
self->data = data = xmalloc(sizeof *data);
data->flags = 0;
data->target = NULL;
data->option = NULL;
data->value = NULL;
}
int
cmd_option_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_option_data *data;
int opt;
/* Don't use the entry version since it may be dependent on key. */
cmd_option_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
continue;
}
switch (opt) {
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc == 2) {
data->option = xstrdup(argv[0]);
data->value = xstrdup(argv[1]);
} else if (argc == 1)
data->option = xstrdup(argv[0]);
else
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
void
cmd_option_send(struct cmd *self, struct buffer *b)
{
struct cmd_option_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->option);
cmd_send_string(b, data->value);
}
void
cmd_option_recv(struct cmd *self, struct buffer *b)
{
struct cmd_option_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->option = cmd_recv_string(b);
data->value = cmd_recv_string(b);
}
void
cmd_option_free(struct cmd *self)
{
struct cmd_option_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
if (data->option != NULL)
xfree(data->option);
if (data->value != NULL)
xfree(data->value);
xfree(data);
}
size_t
cmd_option_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_option_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
off += cmd_print_flags(buf, len, off, data->flags);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->option != NULL)
off += xsnprintf(buf + off, len - off, " %s", data->option);
if (off < len && data->value != NULL)
off += xsnprintf(buf + off, len - off, " %s", data->value);
return (off);
}
void
cmd_pane_init(struct cmd *self, unused int key)
{
struct cmd_pane_data *data;
self->data = data = xmalloc(sizeof *data);
data->flags = 0;
data->target = NULL;
data->arg = NULL;
data->pane = -1;
}
int
cmd_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_pane_data *data;
int opt, n;
const char *errstr;
/* Don't use the entry version since it may be dependent on key. */
cmd_pane_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, CMD_FLAGS "p:t:")) != -1) {
switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
case -1:
goto usage;
case 0:
continue;
}
switch (opt) {
case 'p':
if (data->pane == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "pane %s", errstr);
goto error;
}
data->pane = n;
}
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
}
void
cmd_pane_send(struct cmd *self, struct buffer *b)
{
struct cmd_pane_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->arg);
}
void
cmd_pane_recv(struct cmd *self, struct buffer *b)
{
struct cmd_pane_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->arg = cmd_recv_string(b);
}
void
cmd_pane_free(struct cmd *self)
{
struct cmd_pane_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
if (data->arg != NULL)
xfree(data->arg);
xfree(data);
}
size_t
cmd_pane_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_pane_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
off += cmd_print_flags(buf, len, off, data->flags);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
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.12 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-has-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

117
cmd-if-shell.c Normal file
View File

@@ -0,0 +1,117 @@
/* $Id: cmd-if-shell.c,v 1.7 2009-11-02 21:38:26 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
* Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include "tmux.h"
/*
* Executes a tmux command if a shell command returns true.
*/
int cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_if_shell_callback(struct job *);
void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"shell-command command",
CMD_ARG2, 0,
cmd_target_init,
cmd_target_parse,
cmd_if_shell_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_if_shell_data {
char *cmd;
struct cmd_ctx ctx;
};
int
cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_if_shell_data *cdata;
struct job *job;
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg2);
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
ctx->cmdclient->references++;
if (ctx->curclient != NULL)
ctx->curclient->references++;
job = job_add(NULL, 0, NULL,
data->arg, cmd_if_shell_callback, cmd_if_shell_free, cdata);
job_run(job);
return (1); /* don't let client exit */
}
void
cmd_if_shell_callback(struct job *job)
{
struct cmd_if_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
struct cmd_list *cmdlist;
char *cause;
if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
return;
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
ctx->error(ctx, "%s", cause);
xfree(cause);
}
return;
}
if (cmd_list_exec(cmdlist, ctx) < 0) {
cmd_list_free(cmdlist);
return;
}
cmd_list_free(cmdlist);
}
void
cmd_if_shell_free(void *data)
{
struct cmd_if_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
xfree(cdata->cmd);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.7 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-kill-pane.c,v 1.14 2009-10-25 10:41:03 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,43 +30,47 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp",
CMD_PANE_WINDOW_USAGE,
0,
cmd_pane_init,
cmd_pane_parse,
"[-a] " CMD_TARGET_PANE_USAGE,
0, CMD_CHFLAG('a'),
cmd_target_init,
cmd_target_parse,
cmd_kill_pane_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
cmd_target_free,
cmd_target_print
};
int
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct window_pane *loopwp, *nextwp, *wp;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (window_count_panes(wl->window) == 1) {
ctx->error(ctx, "can't kill pane: %d", data->pane);
return (-1);
/* Only one pane, kill the window. */
server_kill_window(wl->window);
recalculate_sizes();
return (0);
}
window_remove_pane(wl->window, wp);
if (data->chflags & CMD_CHFLAG('a')) {
loopwp = TAILQ_FIRST(&wl->window->panes);
while (loopwp != NULL) {
nextwp = TAILQ_NEXT(loopwp, entry);
if (loopwp != wp) {
layout_close_pane(loopwp);
window_remove_pane(wl->window, loopwp);
}
loopwp = nextwp;
}
} else {
layout_close_pane(wp);
window_remove_pane(wl->window, wp);
}
server_redraw_window(wl->window);
layout_refresh(wl->window, 0);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-server.c,v 1.6 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-kill-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,13 +32,11 @@ 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,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-session.c,v 1.12 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-kill-session.c,v 1.15 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,12 +32,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -55,7 +53,7 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c->session == s) {
if (c != NULL && c->session == s) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-kill-window.c,v 1.20 2009-09-20 22:15:32 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,25 +42,11 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct session *s;
struct client *c;
u_int i;
int destroyed;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
server_kill_window(wl->window);
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-last-window.c,v 1.16 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-last-window.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-link-window.c,v 1.28 2009-01-23 16:59:14 nicm Exp $ */
/* $Id: cmd-link-window.c,v 1.35 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
CMD_DFLAG|CMD_KFLAG,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_link_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free,
cmd_srcdst_print
};
@@ -45,64 +43,23 @@ int
cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *dst;
struct winlink *wl_src, *wl_dst;
struct session *src, *dst;
struct winlink *wl;
char *cause;
int idx;
int idx, kflag, dflag;
if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL)
if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
if (arg_parse_window(data->dst, &dst, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->dst);
return (-1);
}
if (dst == NULL)
dst = ctx->cursession;
if (dst == NULL)
dst = cmd_current_session(ctx);
if (dst == NULL) {
ctx->error(ctx, "session not found: %s", data->dst);
return (-1);
}
wl_dst = NULL;
if (idx != -1)
wl_dst = winlink_find_by_index(&dst->windows, idx);
if (wl_dst != NULL) {
if (wl_dst->window == wl_src->window)
return (0);
if (data->flags & CMD_KFLAG) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(dst, wl_dst);
winlink_stack_remove(&dst->lastw, wl_dst);
winlink_remove(&dst->windows, wl_dst);
/* Force select/redraw if current. */
if (wl_dst == dst->curw) {
data->flags &= ~CMD_DFLAG;
dst->curw = NULL;
}
}
}
wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) {
ctx->error(ctx, "create session failed: %s", cause);
kflag = data->chflags & CMD_CHFLAG('k');
dflag = data->chflags & CMD_CHFLAG('d');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't link window: %s", cause);
xfree(cause);
return (-1);
}
if (data->flags & CMD_DFLAG)
server_status_session(dst);
else {
session_select(dst, wl_dst->idx);
server_redraw_session(dst);
}
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-buffers.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-list-buffers.c,v 1.12 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -48,44 +46,33 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct paste_buffer *pb;
u_int idx;
char *tmp;
size_t size, in, out;
char tmp[51 * 4 + 1];
size_t size, len;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
if (s->sx > 35) { /* leave three for ... */
size = s->sx - 32;
tmp = xmalloc(size + 1);
} else {
size = 0;
tmp = NULL;
}
idx = 0;
while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
if (tmp != NULL) {
in = out = 0;
while (out < size && pb->data[in] != '\0') {
if (pb->data[in] > 31 && pb->data[in] != 127)
tmp[out++] = pb->data[in];
in++;
}
tmp[out] = '\0';
if (out == size) {
tmp[out - 1] = '.';
tmp[out - 2] = '.';
tmp[out - 3] = '.';
}
size = pb->size;
ctx->print(ctx, "%d: %zu bytes: \"%s\"",
idx - 1, strlen(pb->data), tmp);
} else
ctx->print(ctx, "%d: %zu bytes", idx, strlen(pb->data));
/* 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);
}
if (tmp != NULL)
xfree(tmp);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-clients.c,v 1.16 2009-06-25 16:34:50 nicm Exp $ */
/* $Id: cmd-list-clients.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,13 +32,11 @@ 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,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-commands.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-list-commands.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,13 +29,11 @@ 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,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-keys.c,v 1.14 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-list-keys.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,8 @@
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/*
@@ -26,33 +28,97 @@
int cmd_list_keys_exec(struct cmd *, struct cmd_ctx *);
int cmd_list_keys_table(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk",
"",
0,
NULL,
NULL,
"[-t key-table]",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_list_keys_exec,
NULL,
NULL,
NULL,
NULL
cmd_target_free,
cmd_target_print
};
int
cmd_list_keys_exec(unused struct cmd *self, struct cmd_ctx *ctx)
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];
char tmp[BUFSIZ], keytmp[64];
int width, keywidth;
if (data->target != NULL)
return (cmd_list_keys_table(self, ctx));
width = 0;
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
keywidth = strlen(key) + 1;
if (!(bd->key & KEYC_PREFIX))
keywidth += 2;
if (keywidth > width)
width = keywidth;
}
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
if ((key = key_string_lookup_key(bd->key)) == NULL)
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
*tmp = '\0';
cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
ctx->print(ctx, "%11s: %s", key, tmp);
if (!(bd->key & KEYC_PREFIX)) {
xsnprintf(keytmp, sizeof keytmp, "[%s]", key);
key = keytmp;
}
ctx->print(ctx, "%*s: %s", width, key, tmp);
}
return (0);
}
int
cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind;
const char *key, *cmdstr, *mode;
int width, keywidth;
if ((mtab = mode_key_findtable(data->target)) == NULL) {
ctx->error(ctx, "unknown key table: %s", data->target);
return (-1);
}
width = 0;
SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
if (key == NULL)
continue;
keywidth = strlen(key) + 1;
if (keywidth > width)
width = keywidth;
}
SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
if (key == NULL)
continue;
mode = "";
if (mbind->mode != 0)
mode = "(command mode) ";
cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
if (cmdstr != NULL)
ctx->print(ctx, "%*s: %s%s", width, key, mode, cmdstr);
}
return (0);

View File

@@ -1,7 +1,7 @@
/* $Id: cmd-scroll-mode.c,v 1.19 2009-07-01 23:06:32 nicm Exp $ */
/* $Id: cmd-list-panes.c,v 1.2 2009-10-15 20:10:28 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* 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
@@ -18,57 +18,57 @@
#include <sys/types.h>
#include <unistd.h>
#include "tmux.h"
/*
* Enter scroll mode.
* List panes on given window..
*/
void cmd_scroll_mode_init(struct cmd *, int);
int cmd_scroll_mode_exec(struct cmd *, struct cmd_ctx *);
int cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_scroll_mode_entry = {
"scroll-mode", NULL,
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
CMD_TARGET_WINDOW_USAGE,
CMD_UFLAG,
cmd_scroll_mode_init,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_scroll_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_list_panes_exec,
cmd_target_free,
cmd_target_print
};
void
cmd_scroll_mode_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case KEYC_PPAGE:
data->flags |= CMD_UFLAG;
break;
}
}
int
cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct grid *gd;
struct grid_line *gl;
u_int i, n;
unsigned long long size;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
wp = wl->window->active;
window_pane_set_mode(wp, &window_scroll_mode);
if (wp->mode == &window_scroll_mode && data->flags & CMD_UFLAG)
window_scroll_pageup(wp);
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];
size += gl->cellsize * sizeof *gl->celldata;
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++;
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-sessions.c,v 1.19 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-list-sessions.c,v 1.23 2009-11-04 22:42:31 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,36 +31,43 @@ 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,
NULL,
NULL,
NULL,
NULL
};
int
cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
struct session *s;
char *tim;
u_int i;
time_t t;
struct session *s;
struct session_group *sg;
char *tim, tmp[64];
u_int i, idx;
time_t t;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
t = s->tv.tv_sec;
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
else {
idx = session_group_index(sg);
xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
}
t = s->creation_time.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s",
ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s%s",
s->name, winlink_count(&s->windows), tim, s->sx, s->sy,
s->flags & SESSION_UNATTACHED ? "" : " (attached)");
tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.35 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-list-windows.c,v 1.41 2009-10-12 00:08:12 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -47,41 +45,13 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct grid *gd;
u_int i;
unsigned long long size;
const char *name;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
ctx->print(ctx,
"%3d: %s [%ux%u]", wl->idx, w->name, w->sx, w->sy);
TAILQ_FOREACH(wp, &w->panes, entry) {
gd = wp->base.grid;
size = 0;
for (i = 0; i < gd->hsize; i++) {
size += gd->size[i] * sizeof **gd->data;
size += gd->usize[i] * sizeof **gd->udata;
}
size += gd->hsize * (sizeof *gd->data);
size += gd->hsize * (sizeof *gd->size);
if (wp->fd != -1)
name = ttyname(wp->fd);
else
name = "unknown";
ctx->print(ctx,
" %s [%ux%u %s] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, layout_name(w), gd->hsize,
gd->hlimit, size);
}
ctx->print(ctx, "%d: %s [%ux%u]",
wl->idx, wl->window->name, wl->window->sx, wl->window->sy);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.5 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-list.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -86,41 +86,6 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
return (0);
}
void
cmd_list_send(struct cmd_list *cmdlist, struct buffer *b)
{
struct cmd *cmd;
u_int n;
n = 0;
TAILQ_FOREACH(cmd, cmdlist, qentry)
n++;
buffer_write(b, &n, sizeof n);
TAILQ_FOREACH(cmd, cmdlist, qentry)
cmd_send(cmd, b);
}
struct cmd_list *
cmd_list_recv(struct buffer *b)
{
struct cmd_list *cmdlist;
struct cmd *cmd;
u_int n;
buffer_read(b, &n, sizeof n);
cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist);
while (n-- > 0) {
cmd = cmd_recv(b);
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
}
return (cmdlist);
}
void
cmd_list_free(struct cmd_list *cmdlist)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.4 2009-05-21 19:38:51 nicm Exp $ */
/* $Id: cmd-load-buffer.c,v 1.11 2009-10-28 23:10:05 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -35,12 +35,10 @@ 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,
CMD_ARG1, 0,
cmd_buffer_init,
cmd_buffer_parse,
cmd_load_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
@@ -50,25 +48,22 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct session *s;
struct stat statbuf;
struct stat sb;
FILE *f;
char *buf;
u_int limit;
u_char *buf;
u_int limit;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
if (stat(data->arg, &statbuf) < 0) {
if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
if (!S_ISREG(statbuf.st_mode)) {
ctx->error(ctx, "%s: not a regular file", data->arg);
return (-1);
}
if ((f = fopen(data->arg, "rb")) == NULL) {
if (fstat(fileno(f), &sb) < 0) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
fclose(f);
return (-1);
}
@@ -76,27 +71,27 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
* We don't want to die due to memory exhaustion, hence xmalloc can't
* be used here.
*/
if ((buf = malloc(statbuf.st_size + 1)) == NULL) {
if ((buf = malloc(sb.st_size + 1)) == NULL) {
ctx->error(ctx, "malloc error: %s", strerror(errno));
fclose(f);
return (-1);
}
if (fread(buf, 1, statbuf.st_size, f) != (size_t) statbuf.st_size) {
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);
}
buf[statbuf.st_size] = '\0';
fclose(f);
limit = options_get_number(&s->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&s->buffers, buf, limit);
paste_add(&s->buffers, buf, sb.st_size, limit);
return (0);
}
if (paste_replace(&s->buffers, data->buffer, buf) != 0) {
if (paste_replace(&s->buffers, data->buffer, buf, sb.st_size) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf);
return (-1);

53
cmd-lock-client.c Normal file
View File

@@ -0,0 +1,53 @@
/* $Id: cmd-lock-client.c,v 1.1 2009-09-25 17:51:39 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"
/*
* Lock a single client.
*/
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,
cmd_target_init,
cmd_target_parse,
cmd_lock_client_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_lock_client_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);
server_lock_client(c);
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-server.c,v 1.4 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cmd-lock-server.c,v 1.7 2009-09-25 17:47:42 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,20 +33,19 @@ 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,
NULL,
NULL,
NULL,
NULL,
};
int
cmd_lock_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{
server_lock();
recalculate_sizes();
return (0);
}

53
cmd-lock-session.c Normal file
View File

@@ -0,0 +1,53 @@
/* $Id: cmd-lock-session.c,v 1.1 2009-09-25 17:51:39 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"
/*
* Lock all clients attached to a session.
*/
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,
cmd_target_init,
cmd_target_parse,
cmd_lock_session_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_lock_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
server_lock_session(s);
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-move-window.c,v 1.5 2009-01-23 16:59:14 nicm Exp $ */
/* $Id: cmd-move-window.c,v 1.12 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
CMD_DFLAG|CMD_KFLAG,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_move_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free,
cmd_srcdst_print
};
@@ -46,77 +44,23 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *src, *dst;
struct winlink *wl_src, *wl_dst;
struct client *c;
u_int i;
int destroyed, idx;
struct winlink *wl;
char *cause;
int idx, kflag, dflag;
if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
if (arg_parse_window(data->dst, &dst, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->dst);
return (-1);
}
if (dst == NULL)
dst = ctx->cursession;
if (dst == NULL)
dst = cmd_current_session(ctx);
if (dst == NULL) {
ctx->error(ctx, "session not found: %s", data->dst);
return (-1);
}
wl_dst = NULL;
if (idx != -1)
wl_dst = winlink_find_by_index(&dst->windows, idx);
if (wl_dst != NULL) {
if (wl_dst->window == wl_src->window)
return (0);
if (data->flags & CMD_KFLAG) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(dst, wl_dst);
winlink_stack_remove(&dst->lastw, wl_dst);
winlink_remove(&dst->windows, wl_dst);
/* Force select/redraw if current. */
if (wl_dst == dst->curw) {
data->flags &= ~CMD_DFLAG;
dst->curw = NULL;
}
}
}
wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) {
ctx->error(ctx, "attach window failed: %s", cause);
kflag = data->chflags & CMD_CHFLAG('k');
dflag = data->chflags & CMD_CHFLAG('d');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't move window: %s", cause);
xfree(cause);
return (-1);
}
destroyed = session_detach(src, wl_src);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != src)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
if (data->flags & CMD_DFLAG)
server_status_session(dst);
else {
session_select(dst, wl_dst->idx);
server_redraw_session(dst);
}
server_unlink_window(src, wl);
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.41 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-new-session.c,v 1.69 2009-10-12 00:49:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,9 @@
#include <sys/types.h>
#include <string.h>
#include <termios.h>
#include "tmux.h"
/*
@@ -26,13 +29,12 @@
int cmd_new_session_parse(struct cmd *, int, char **, char **);
int cmd_new_session_exec(struct cmd *, struct cmd_ctx *);
void cmd_new_session_send(struct cmd *, struct buffer *);
void cmd_new_session_recv(struct cmd *, struct buffer *);
void cmd_new_session_free(struct cmd *);
void cmd_new_session_init(struct cmd *, int);
size_t cmd_new_session_print(struct cmd *, char *, size_t);
struct cmd_new_session_data {
char *target;
char *newname;
char *winname;
char *cmd;
@@ -41,13 +43,11 @@ struct cmd_new_session_data {
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"[-d] [-n window-name] [-s session-name] [command]",
CMD_STARTSERVER|CMD_CANTNEST,
"[-d] [-n window-name] [-s session-name] [-t target-session] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, 0,
cmd_new_session_init,
cmd_new_session_parse,
cmd_new_session_exec,
cmd_new_session_send,
cmd_new_session_recv,
cmd_new_session_free,
cmd_new_session_print
};
@@ -59,6 +59,7 @@ cmd_new_session_init(struct cmd *self, unused int arg)
self->data = data = xmalloc(sizeof *data);
data->flag_detached = 0;
data->target = NULL;
data->newname = NULL;
data->winname = NULL;
data->cmd = NULL;
@@ -70,10 +71,10 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_new_session_data *data;
int opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "ds:n:")) != -1) {
while ((opt = getopt(argc, argv, "ds:t:n:")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
@@ -82,6 +83,10 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
if (data->newname == NULL)
data->newname = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'n':
if (data->winname == NULL)
data->winname = xstrdup(optarg);
@@ -95,6 +100,9 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
if (argc != 0 && argc != 1)
goto usage;
if (data->target != NULL && (argc == 1 || data->winname != NULL))
goto usage;
if (argc == 1)
data->cmd = xstrdup(argv[0]);
@@ -111,106 +119,166 @@ int
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_new_session_data *data = self->data;
struct client *c = ctx->cmdclient;
struct session *s;
char *cmd, *cwd, *cause;
struct session *s, *groupwith;
struct window *w;
struct environ env;
struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
int detached, idx;
u_int sx, sy;
if (ctx->curclient != NULL)
return (0);
if (!data->flag_detached) {
if (c == NULL) {
ctx->error(ctx, "no client to attach to");
return (-1);
}
if (!(c->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
}
if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname);
return (-1);
}
cmd = data->cmd;
if (cmd == NULL)
cmd = options_get_string(&global_options, "default-command");
if (c == NULL || c->cwd == NULL)
cwd = options_get_string(&global_options, "default-path");
else
cwd = c->cwd;
sx = 80;
sy = 25;
if (!data->flag_detached) {
sx = c->tty.sx;
sy = c->tty.sy;
}
if (options_get_number(&global_options, "status")) {
if (sy == 0)
sy = 1;
else
sy--;
}
if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause);
xfree(cause);
groupwith = NULL;
if (data->target != NULL &&
(groupwith = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
/*
* There are three cases:
*
* 1. If cmdclient is non-NULL, new-session has been called from the
* command-line - cmdclient is to become a new attached, interactive
* client. Unless -d is given, the terminal must be opened and then
* the client sent MSG_READY.
*
* 2. If cmdclient is NULL, new-session has been called from an
* existing client (such as a key binding).
*
* 3. Both are NULL, the command was in the configuration file. Treat
* this as if -d was given even if it was not.
*
* In all cases, a new additional session needs to be created and
* (unless -d) set as the current session for the client.
*/
/* Set -d if no client. */
detached = data->flag_detached;
if (ctx->cmdclient == NULL && ctx->curclient == NULL)
detached = 1;
/*
* Save the termios settings, part of which is used for new windows in
* this session.
*
* This is read again with tcgetattr() rather than using tty.tio as if
* detached, tty_open won't be called. Because of this, it must be done
* before opening the terminal as that calls tcsetattr() to prepare for
* tmux taking over.
*/
if (ctx->cmdclient != NULL && ctx->cmdclient->tty.fd != -1) {
if (tcgetattr(ctx->cmdclient->tty.fd, &tio) != 0)
fatal("tcgetattr failed");
tiop = &tio;
} else
tiop = NULL;
/* Open the terminal if necessary. */
if (!detached && ctx->cmdclient != NULL) {
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
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);
xfree(cause);
return (-1);
}
}
/* 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");
s = session_create(data->newname, cmd, cwd, sx, sy, &cause);
/* Find new session size. */
if (detached) {
sx = 80;
sy = 24;
} else if (ctx->cmdclient != NULL) {
sx = ctx->cmdclient->tty.sx;
sy = ctx->cmdclient->tty.sy;
} else {
sx = ctx->curclient->tty.sx;
sy = ctx->curclient->tty.sy;
}
if (sy > 0 && options_get_number(&global_s_options, "status"))
sy--;
if (sx == 0)
sx = 1;
if (sy == 0)
sy = 1;
/* Figure out the command for the new window. */
if (data->target != NULL)
cmd = NULL;
else if (data->cmd != NULL)
cmd = data->cmd;
else
cmd = options_get_string(&global_s_options, "default-command");
/* Construct the environment. */
environ_init(&env);
update = options_get_string(&global_s_options, "update-environment");
if (ctx->cmdclient != NULL)
environ_update(update, &ctx->cmdclient->environ, &env);
/* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(
data->newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
if (s == NULL) {
ctx->error(ctx, "create session failed: %s", cause);
xfree(cause);
return (-1);
}
if (data->winname != NULL) {
xfree(s->curw->window->name);
s->curw->window->name = xstrdup(data->winname);
options_set_number(
&s->curw->window->options, "automatic-rename", 0);
environ_free(&env);
/* Set the initial window name if one given. */
if (cmd != NULL && data->winname != NULL) {
w = s->curw->window;
xfree(w->name);
w->name = xstrdup(data->winname);
options_set_number(&w->options, "automatic-rename", 0);
}
if (data->flag_detached) {
if (c != NULL)
server_write_client(c, MSG_EXIT, NULL, 0);
} else {
c->session = s;
server_write_client(c, MSG_READY, NULL, 0);
server_redraw_client(c);
/*
* If a target session is given, this is to be part of a session group,
* so add it to the group and synchronize.
*/
if (groupwith != NULL) {
session_group_add(groupwith, s);
session_group_synchronize_to(s);
session_select(s, RB_ROOT(&s->windows)->idx);
}
/*
* 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 (ctx->cmdclient != NULL) {
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
ctx->cmdclient->session = s;
server_redraw_client(ctx->cmdclient);
} else {
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
}
}
recalculate_sizes();
return (1);
}
void
cmd_new_session_send(struct cmd *self, struct buffer *b)
{
struct cmd_new_session_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->newname);
cmd_send_string(b, data->winname);
cmd_send_string(b, data->cmd);
}
void
cmd_new_session_recv(struct cmd *self, struct buffer *b)
{
struct cmd_new_session_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->newname = cmd_recv_string(b);
data->winname = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
return (!detached); /* 1 means don't tell command client to exit */
}
void

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-window.c,v 1.31 2009-01-23 16:59:14 nicm Exp $ */
/* $Id: cmd-new-window.c,v 1.39 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,8 +28,6 @@
int cmd_new_window_parse(struct cmd *, int, char **, char **);
int cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_new_window_send(struct cmd *, struct buffer *);
void cmd_new_window_recv(struct cmd *, struct buffer *);
void cmd_new_window_free(struct cmd *);
void cmd_new_window_init(struct cmd *, int);
size_t cmd_new_window_print(struct cmd *, char *, size_t);
@@ -45,12 +43,10 @@ struct cmd_new_window_data {
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
"[-dk] [-n window-name] [-t target-window] [command]",
0,
0, 0,
cmd_new_window_init,
cmd_new_window_parse,
cmd_new_window_exec,
cmd_new_window_send,
cmd_new_window_recv,
cmd_new_window_free,
cmd_new_window_print
};
@@ -74,7 +70,7 @@ cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_new_window_data *data;
int opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dkt:n:")) != -1) {
@@ -126,18 +122,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (data == NULL)
return (0);
if (arg_parse_window(data->target, &s, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->target);
if ((idx = cmd_find_index(ctx, data->target, &s)) == -2)
return (-1);
}
if (s == NULL)
s = ctx->cursession;
if (s == NULL)
s = cmd_current_session(ctx);
if (s == NULL) {
ctx->error(ctx, "session not found: %s", data->target);
return (-1);
}
wl = NULL;
if (idx != -1)
@@ -164,10 +150,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (cmd == NULL)
cmd = options_get_string(&s->options, "default-command");
if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
cwd = options_get_string(&global_options, "default-path");
cwd = options_get_string(&s->options, "default-path");
else
cwd = ctx->cmdclient->cwd;
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, data->name, cmd, cwd, idx, &cause);
if (wl == NULL) {
ctx->error(ctx, "create window failed: %s", cause);
@@ -176,36 +164,13 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
if (!data->flag_detached) {
session_select(s, wl->idx);
server_redraw_session(s);
} else
server_status_session(s);
server_redraw_session_group(s);
} else
server_status_session_group(s);
return (0);
}
void
cmd_new_window_send(struct cmd *self, struct buffer *b)
{
struct cmd_new_window_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->name);
cmd_send_string(b, data->cmd);
}
void
cmd_new_window_recv(struct cmd *self, struct buffer *b)
{
struct cmd_new_window_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->name = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
}
void
cmd_new_window_free(struct cmd *self)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-layout.c,v 1.2 2009-04-30 21:17:06 nicm Exp $ */
/* $Id: cmd-next-layout.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,12 +42,13 @@ cmd_next_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);
layout_next(wl->window);
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
layout = layout_set_next(wl->window);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-window.c,v 1.17 2009-06-25 15:29:34 nicm Exp $ */
/* $Id: cmd-next-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,12 +30,10 @@ 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,
CMD_AFLAG,
0, CMD_CHFLAG('a'),
cmd_next_window_init,
cmd_target_parse,
cmd_next_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -48,8 +46,8 @@ cmd_next_window_init(struct cmd *self, int key)
cmd_target_init(self, key);
data = self->data;
if (key == KEYC_ADDESC('n'))
data->flags |= CMD_AFLAG;
if (key == ('n' | KEYC_ESCAPE))
data->chflags |= CMD_CHFLAG('a');
}
int
@@ -63,7 +61,7 @@ cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
activity = 0;
if (data->flags & CMD_AFLAG)
if (data->chflags & CMD_CHFLAG('a'))
activity = 1;
if (session_next(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-paste-buffer.c,v 1.16 2009-07-02 16:23:54 nicm Exp $ */
/* $Id: cmd-paste-buffer.c,v 1.20 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,16 +27,15 @@
*/
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_paste_buffer_lf2cr(struct buffer *, const char *, size_t);
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
"[-d] " CMD_BUFFER_WINDOW_USAGE,
CMD_DFLAG,
"[-dr] " CMD_BUFFER_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('r'),
cmd_buffer_init,
cmd_buffer_parse,
cmd_paste_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
@@ -46,13 +45,13 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct session *s;
struct paste_buffer *pb;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
w = wl->window;
wp = wl->window->active;
if (data->buffer == -1)
pb = paste_get_top(&s->buffers);
@@ -63,11 +62,16 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (pb != NULL && *pb->data != '\0')
buffer_write(w->active->out, pb->data, strlen(pb->data));
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);
}
/* Delete the buffer if -d. */
if (data->flags & CMD_DFLAG) {
if (data->chflags & CMD_CHFLAG('d')) {
if (data->buffer == -1)
paste_free_top(&s->buffers);
else
@@ -76,3 +80,21 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
/* Add bytes to a buffer but change every '\n' to '\r'. */
void
cmd_paste_buffer_lf2cr(struct buffer *b, const char *data, size_t size)
{
const char *end = data + size;
const char *lf;
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
buffer_write(b, data, lf - data);
buffer_write8(b, '\r');
data = lf + 1;
}
if (end != data)
buffer_write(b, data, end - data);
}

125
cmd-pipe-pane.c Normal file
View File

@@ -0,0 +1,125 @@
/* $Id: cmd-pipe-pane.c,v 1.3 2009-10-23 17:26:40 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 <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
/*
* Open pipe to redirect pane output. If already open, close first.
*/
int cmd_pipe_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
CMD_TARGET_PANE_USAGE "[-o] [command]",
CMD_ARG01, CMD_CHFLAG('o'),
cmd_target_init,
cmd_target_parse,
cmd_pipe_pane_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct window_pane *wp;
int old_fd, pipe_fd[2], null_fd, mode;
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);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}
/* If no pipe command, that is enough. */
if (data->arg == NULL || *data->arg == '\0')
return (0);
/*
* With -o, only open the new pipe if there was no previous one. This
* allows a pipe to be toggled with a single key, for example:
*
* bind ^p pipep -o 'cat >>~/output'
*/
if (data->chflags & CMD_CHFLAG('o') && old_fd != -1)
return (0);
/* Open the new pipe. */
if (pipe(pipe_fd) != 0) {
ctx->error(ctx, "pipe error: %s", strerror(errno));
return (-1);
}
/* Fork the child. */
switch (fork()) {
case -1:
ctx->error(ctx, "fork error: %s", strerror(errno));
return (-1);
case 0:
/* Child process. */
close(pipe_fd[0]);
sigreset();
if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
_exit(1);
if (pipe_fd[1] != STDIN_FILENO)
close(pipe_fd[1]);
null_fd = open(_PATH_DEVNULL, O_WRONLY, 0);
if (dup2(null_fd, STDOUT_FILENO) == -1)
_exit(1);
if (dup2(null_fd, STDERR_FILENO) == -1)
_exit(1);
if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
close(null_fd);
execl(_PATH_BSHELL, "sh", "-c", data->arg, (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);
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");
return (0);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-layout.c,v 1.1 2009-04-30 21:17:06 nicm Exp $ */
/* $Id: cmd-previous-layout.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,12 +42,13 @@ 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);
layout_previous(wl->window);
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
layout = layout_set_previous(wl->window);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-window.c,v 1.17 2009-06-25 15:29:34 nicm Exp $ */
/* $Id: cmd-previous-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,12 +30,10 @@ 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,
CMD_AFLAG,
0, CMD_CHFLAG('a'),
cmd_previous_window_init,
cmd_target_parse,
cmd_previous_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -48,8 +46,8 @@ cmd_previous_window_init(struct cmd *self, int key)
cmd_target_init(self, key);
data = self->data;
if (key == KEYC_ADDESC('p'))
data->flags |= CMD_AFLAG;
if (key == ('p' | KEYC_ESCAPE))
data->chflags |= CMD_CHFLAG('a');
}
int
@@ -63,7 +61,7 @@ cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
activity = 0;
if (data->flags & CMD_AFLAG)
if (data->chflags & CMD_CHFLAG('a'))
activity = 1;
if (session_previous(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-refresh-client.c,v 1.8 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-refresh-client.c,v 1.10 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-session.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-rename-session.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
CMD_ARG1, 0,
cmd_target_init,
cmd_target_parse,
cmd_rename_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -53,5 +51,7 @@ cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx)
xfree(s->name);
s->name = xstrdup(data->arg);
server_status_session(s);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.27 2009-05-04 17:58:26 nicm Exp $ */
/* $Id: cmd-rename-window.c,v 1.30 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
CMD_ARG1, 0,
cmd_target_init,
cmd_target_parse,
cmd_rename_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -55,7 +53,7 @@ cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl->window->name = xstrdup(data->arg);
options_set_number(&wl->window->options, "automatic-rename", 0);
server_status_session(s);
server_status_window(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-resize-pane.c,v 1.7 2009-05-21 19:46:00 nicm Exp $ */
/* $Id: cmd-resize-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,32 +31,47 @@ int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
CMD_PANE_WINDOW_USAGE "[-DU] [adjustment]",
CMD_ARG01|CMD_BIGUFLAG|CMD_BIGDFLAG,
"[-DU] " CMD_TARGET_PANE_USAGE " [adjustment]",
CMD_ARG01,
CMD_CHFLAG('D')|CMD_CHFLAG('L')|CMD_CHFLAG('R')|CMD_CHFLAG('U'),
cmd_resize_pane_init,
cmd_pane_parse,
cmd_target_parse,
cmd_resize_pane_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
cmd_target_free,
cmd_target_print
};
void
cmd_resize_pane_init(struct cmd *self, int key)
{
struct cmd_pane_data *data;
struct cmd_target_data *data;
cmd_pane_init(self, key);
cmd_target_init(self, key);
data = self->data;
if (key == KEYC_ADDCTL(KEYC_DOWN))
data->flags |= CMD_BIGDFLAG;
if (key == KEYC_ADDESC(KEYC_UP))
if (key == (KEYC_UP | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('U');
if (key == (KEYC_DOWN | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('D');
if (key == (KEYC_LEFT | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('L');
if (key == (KEYC_RIGHT | KEYC_CTRL))
data->chflags |= CMD_CHFLAG('R');
if (key == (KEYC_UP | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('U');
data->arg = xstrdup("5");
if (key == KEYC_ADDESC(KEYC_DOWN)) {
data->flags |= CMD_BIGDFLAG;
}
if (key == (KEYC_DOWN | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('D');
data->arg = xstrdup("5");
}
if (key == (KEYC_LEFT | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('L');
data->arg = xstrdup("5");
}
if (key == (KEYC_RIGHT | KEYC_ESCAPE)) {
data->chflags |= CMD_CHFLAG('R');
data->arg = xstrdup("5");
}
}
@@ -64,23 +79,14 @@ cmd_resize_pane_init(struct cmd *self, int key)
int
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct cmd_target_data *data = self->data;
struct winlink *wl;
const char *errstr;
struct window_pane *wp;
u_int adjust;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (data->arg == NULL)
adjust = 1;
@@ -92,12 +98,14 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (!(data->flags & CMD_BIGDFLAG))
adjust = -adjust;
if (layout_resize(wp, adjust) != 0) {
ctx->error(ctx, "layout %s "
"does not support resizing", layout_name(wp->window));
return (-1);
if (data->chflags & (CMD_CHFLAG('L')|CMD_CHFLAG('R'))) {
if (data->chflags & CMD_CHFLAG('L'))
adjust = -adjust;
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
} else {
if (data->chflags & CMD_CHFLAG('U'))
adjust = -adjust;
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
}
server_redraw_window(wl->window);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-respawn-window.c,v 1.14 2009-03-04 17:24:07 nicm Exp $ */
/* $Id: cmd-respawn-window.c,v 1.22 2009-09-16 12:36:27 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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_KFLAG,
CMD_ARG01, CMD_CHFLAG('k'),
cmd_target_init,
cmd_target_parse,
cmd_respawn_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -49,14 +47,14 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w;
struct window_pane *wp;
struct session *s;
const char **env;
struct environ env;
char *cause;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
w = wl->window;
if (!(data->flags & CMD_KFLAG)) {
if (!(data->chflags & CMD_CHFLAG('k'))) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1)
continue;
@@ -66,22 +64,31 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
env = server_fill_environ(s);
environ_init(&env);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry);
layout_free(w);
window_destroy_panes(w);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy);
if (window_pane_spawn(wp, data->arg, NULL, env, &cause) != 0) {
if (window_pane_spawn(
wp, data->arg, NULL, NULL, &env, s->tio, &cause) != 0) {
ctx->error(ctx, "respawn window failed: %s", cause);
xfree(cause);
environ_free(&env);
return (-1);
}
layout_init(w);
screen_reinit(&wp->base);
window_set_active_pane(w, wp);
recalculate_sizes();
server_redraw_window(w);
environ_free(&env);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rotate-window.c,v 1.4 2009-06-25 15:28:08 nicm Exp $ */
/* $Id: cmd-rotate-window.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,12 +30,10 @@ 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,
CMD_BIGUFLAG|CMD_BIGDFLAG,
0, CMD_CHFLAG('D')|CMD_CHFLAG('U'),
cmd_rotate_window_init,
cmd_target_parse,
cmd_rotate_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -48,8 +46,8 @@ cmd_rotate_window_init(struct cmd *self, int key)
cmd_target_init(self, key);
data = self->data;
if (key == KEYC_ADDESC('o'))
data->flags |= CMD_BIGDFLAG;
if (key == ('o' | KEYC_ESCAPE))
data->chflags |= CMD_CHFLAG('D');
}
int
@@ -59,64 +57,68 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl;
struct window *w;
struct window_pane *wp, *wp2;
struct layout_cell *lc;
u_int sx, sy, xoff, yoff;
int flags;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
w = wl->window;
if (data->flags & CMD_BIGDFLAG) {
if (data->chflags & CMD_CHFLAG('D')) {
wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
lc = wp->layout_cell;
xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH(wp, &w->panes, entry) {
if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL)
break;
wp->layout_cell = wp2->layout_cell;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy);
}
wp->layout_cell = lc;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
wp = TAILQ_LAST(&w->panes, window_panes);
window_set_active_pane(w, wp);
server_redraw_window(w);
} else {
wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_TAIL(&w->panes, wp, entry);
lc = wp->layout_cell;
xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) {
if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL)
break;
wp->layout_cell = wp2->layout_cell;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy);
}
wp->layout_cell = lc;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)
wp = TAILQ_FIRST(&w->panes);
window_set_active_pane(w, wp);
server_redraw_window(w);
}
layout_refresh(w, 0);
return (0);
}

137
cmd-run-shell.c Normal file
View File

@@ -0,0 +1,137 @@
/* $Id: cmd-run-shell.c,v 1.4 2009-11-02 21:38:26 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
* Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include "tmux.h"
/*
* Runs a command without a window.
*/
int cmd_run_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *);
const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run",
"command",
CMD_ARG1, 0,
cmd_target_init,
cmd_target_parse,
cmd_run_shell_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_run_shell_data {
char *cmd;
struct cmd_ctx ctx;
};
int
cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_run_shell_data *cdata;
struct job *job;
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg);
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
ctx->cmdclient->references++;
if (ctx->curclient != NULL)
ctx->curclient->references++;
job = job_add(NULL, 0, NULL,
data->arg, cmd_run_shell_callback, cmd_run_shell_free, cdata);
job_run(job);
return (1); /* don't let client exit */
}
void
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;
int retcode;
buf = BUFFER_OUT(job->out);
len = BUFFER_USED(job->out);
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)
xasprintf(&msg, "'%s' returned %d", cmd, retcode);
} else if (WIFSIGNALED(job->status)) {
retcode = WTERMSIG(job->status);
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL) {
if (len != 0)
ctx->print(ctx, "%s", msg);
else
ctx->info(ctx, "%s", msg);
xfree(msg);
}
}
void
cmd_run_shell_free(void *data)
{
struct cmd_run_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
xfree(cdata->cmd);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-save-buffer.c,v 1.5 2009-05-18 16:22:30 nicm Exp $ */
/* $Id: cmd-save-buffer.c,v 1.9 2009-10-28 23:08:52 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -33,12 +33,10 @@ 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_AFLAG|CMD_ARG1,
CMD_ARG1, CMD_CHFLAG('a'),
cmd_buffer_init,
cmd_buffer_parse,
cmd_save_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
@@ -68,23 +66,23 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
mask = umask(S_IRWXG | S_IRWXO);
if (data->flags & CMD_AFLAG)
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 (fwrite(pb->data, 1, strlen(pb->data), f) != strlen(pb->data)) {
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
ctx->error(ctx, "%s: fwrite error", data->arg);
fclose(f);
return (-1);
}
fclose(f);
umask(mask);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-layout.c,v 1.3 2009-06-25 16:34:50 nicm Exp $ */
/* $Id: cmd-select-layout.c,v 1.8 2009-07-28 23:04:29 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,13 +29,11 @@ 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_ARG1,
CMD_TARGET_WINDOW_USAGE " [layout-name]",
CMD_ARG01, 0,
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -49,17 +47,17 @@ cmd_select_layout_init(struct cmd *self, int key)
data = self->data;
switch (key) {
case KEYC_ADDESC('0'):
data->arg = xstrdup("manual-vertical");
break;
case KEYC_ADDESC('1'):
case ('1' | KEYC_ESCAPE):
data->arg = xstrdup("even-horizontal");
break;
case KEYC_ADDESC('2'):
case ('2' | KEYC_ESCAPE):
data->arg = xstrdup("even-vertical");
break;
case ('3' | KEYC_ESCAPE):
data->arg = xstrdup("main-horizontal");
break;
case KEYC_ADDESC('9'):
data->arg = xstrdup("active-only");
case ('4' | KEYC_ESCAPE):
data->arg = xstrdup("main-vertical");
break;
}
}
@@ -74,13 +72,17 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if ((layout = layout_lookup(data->arg)) == -1) {
ctx->error(ctx, "unknown or ambiguous layout: %s", data->arg);
if (data->arg == NULL) {
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);
}
if (layout_select(wl->window, layout) == 0)
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
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.4 2009-04-01 21:10:08 nicm Exp $ */
/* $Id: cmd-select-pane.c,v 1.10 2009-07-30 20:45:20 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,42 +28,31 @@ int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
CMD_PANE_WINDOW_USAGE,
0,
cmd_pane_init,
cmd_pane_parse,
CMD_TARGET_PANE_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_select_pane_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
cmd_target_free,
cmd_target_print
};
int
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (wp->flags & PANE_HIDDEN) {
ctx->error(ctx, "pane %d is hidden", data->pane);
if (!window_pane_visible(wp)) {
ctx->error(ctx, "pane not visible: %s", data->target);
return (-1);
}
window_set_active_pane(wl->window, wp);
layout_refresh(wl->window, 1);
server_status_window(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-prompt.c,v 1.7 2009-02-13 18:57:55 nicm Exp $ */
/* $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>
@@ -33,12 +33,10 @@ 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, 0,
cmd_target_init,
cmd_target_parse,
cmd_select_prompt_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -55,7 +53,7 @@ cmd_select_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
if (c->prompt_string != NULL)
return (0);
status_prompt_set(c, "index ", cmd_select_prompt_callback, c, 0);
status_prompt_set(c, "index ", cmd_select_prompt_callback, NULL, c, 0);
return (0);
}
@@ -68,20 +66,20 @@ cmd_select_prompt_callback(void *data, const char *s)
char msg[128];
u_int idx;
if (s == NULL)
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, msg);
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, msg);
status_message_set(c, "%s", msg);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-window.c,v 1.21 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-select-window.c,v 1.23 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,12 +32,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-keys.c,v 1.18 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-send-keys.c,v 1.22 2009-09-22 14:03:11 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,27 +28,22 @@
int cmd_send_keys_parse(struct cmd *, int, char **, char **);
int cmd_send_keys_exec(struct cmd *, struct cmd_ctx *);
void cmd_send_keys_send(struct cmd *, struct buffer *);
void cmd_send_keys_recv(struct cmd *, struct buffer *);
void cmd_send_keys_free(struct cmd *);
size_t cmd_send_keys_print(struct cmd *, char *, size_t);
struct cmd_send_keys_data {
char *target;
int idx;
u_int nkeys;
int *keys;
};
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"[-t target-window] key ...",
0,
"[-t target-pane] key ...",
0, 0,
NULL,
cmd_send_keys_parse,
cmd_send_keys_exec,
cmd_send_keys_send,
cmd_send_keys_recv,
cmd_send_keys_free,
cmd_send_keys_print
};
@@ -62,7 +57,6 @@ cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause)
self->data = data = xmalloc(sizeof *data);
data->target = NULL;
data->idx = -1;
data->nkeys = 0;
data->keys = NULL;
@@ -110,45 +104,21 @@ int
cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_send_keys_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
u_int i;
if (data == NULL)
return (-1);
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
for (i = 0; i < data->nkeys; i++) {
window_pane_key(
wl->window->active, ctx->curclient, data->keys[i]);
}
for (i = 0; i < data->nkeys; i++)
window_pane_key(wp, ctx->curclient, data->keys[i]);
return (0);
}
void
cmd_send_keys_send(struct cmd *self, struct buffer *b)
{
struct cmd_send_keys_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
buffer_write(b, data->keys, data->nkeys * sizeof *data->keys);
}
void
cmd_send_keys_recv(struct cmd *self, struct buffer *b)
{
struct cmd_send_keys_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->keys = xcalloc(data->nkeys, sizeof *data->keys);
buffer_read(b, data->keys, data->nkeys * sizeof *data->keys);
}
void
cmd_send_keys_free(struct cmd *self)
{
@@ -171,8 +141,6 @@ cmd_send_keys_print(struct cmd *self, char *buf, size_t len)
return (off);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->idx != -1)
off += xsnprintf(buf + off, len - off, " -i %d", data->idx);
for (i = 0; i < data->nkeys; i++) {
if (off >= len)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-prefix.c,v 1.23 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-send-prefix.c,v 1.27 2009-09-22 14:22:20 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,13 +28,11 @@ int cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
CMD_TARGET_WINDOW_USAGE,
0,
CMD_TARGET_PANE_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_send_prefix_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,14 +42,14 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct winlink *wl;
int key;
struct window_pane *wp;
struct keylist *keylist;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
return (-1);
key = options_get_number(&s->options, "prefix");
window_pane_key(wl->window->active, ctx->curclient, key);
keylist = options_get_data(&s->options, "prefix");
window_pane_key(wp, ctx->curclient, ARRAY_FIRST(keylist));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.20 2009-06-25 20:27:31 nicm Exp $ */
/* $Id: cmd-server-info.c,v 1.33 2009-11-04 22:42:31 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,13 +35,11 @@ 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,
NULL,
NULL,
NULL,
NULL
};
@@ -57,7 +55,9 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct tty_code *code;
struct tty_term_code_entry *ent;
struct utsname un;
struct job *job;
struct grid *gd;
struct grid_line *gl;
u_int i, j, k;
char out[80];
char *tim;
@@ -71,8 +71,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *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" : "");
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine);
}
if (cfg_file != NULL)
@@ -82,7 +82,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION);
ctx->print(ctx, "%u clients, %u sessions",
ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions));
ctx->print(ctx, "");
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Clients:");
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -91,11 +91,12 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
continue;
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x]", i, c->tty.path, c->fd, c->tty.fd,
c->session->name, c->tty.sx, c->tty.sy, c->tty.termname,
c->flags, c->tty.flags);
"[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.flags, c->references);
}
ctx->print(ctx, "");
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8));
@@ -104,33 +105,35 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
if (s == NULL)
continue;
t = s->tv.tv_sec;
t = s->creation_time.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x]", i, s->name, winlink_count(&s->windows),
tim, s->sx, s->sy, s->flags);
"[flags=0x%x, references=%u]", i, s->name,
winlink_count(&s->windows), tim, s->sx, s->sy, s->flags,
s->references);
RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, "
"references=%u, layout=%u]", wl->idx, w->name,
"references=%u, last layout=%d]", wl->idx, w->name,
w->sx, w->sy, w->flags, w->references,
w->layout);
w->lastlayout);
j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0;
gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) {
if (gd->data[k] != NULL) {
gl = &gd->linedata[k];
if (gl->celldata != NULL) {
lines++;
size += gd->size[k] *
sizeof (**gd->data);
size += gl->cellsize *
sizeof *gl->celldata;
}
if (gd->udata[k] != NULL) {
if (gl->utf8data != NULL) {
ulines++;
usize += gd->usize[k] *
sizeof (**gd->udata);
usize += gl->utf8size *
sizeof *gl->utf8data;
}
}
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
@@ -142,7 +145,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
}
}
ctx->print(ctx, "");
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Terminals:");
SLIST_FOREACH(term, &tty_terms, entry) {
@@ -174,7 +177,13 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
}
}
ctx->print(ctx, "");
ctx->print(ctx, "%s", "");
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);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-buffer.c,v 1.7 2009-01-25 18:51:28 tcunha Exp $ */
/* $Id: cmd-set-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,7 +18,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -31,12 +31,10 @@ 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,
CMD_ARG1, 0,
cmd_buffer_init,
cmd_buffer_parse,
cmd_set_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
@@ -47,17 +45,23 @@ 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;
size_t psize;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
limit = options_get_number(&s->options, "buffer-limit");
pdata = xstrdup(data->arg);
psize = strlen(pdata);
if (data->buffer == -1) {
paste_add(&s->buffers, xstrdup(data->arg), limit);
paste_add(&s->buffers, pdata, psize, limit);
return (0);
}
if (paste_replace(&s->buffers, data->buffer, xstrdup(data->arg)) != 0) {
if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(pdata);
return (-1);
}
return (0);

88
cmd-set-environment.c Normal file
View File

@@ -0,0 +1,88 @@
/* $Id: cmd-set-environment.c,v 1.2 2009-08-11 14:42:59 nicm 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 <string.h>
#include "tmux.h"
/*
* Set an environment variable.
*/
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'),
NULL,
cmd_target_parse,
cmd_set_environment_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct environ *env;
if (*data->arg == '\0') {
ctx->error(ctx, "empty variable name");
return (-1);
}
if (strchr(data->arg, '=') != NULL) {
ctx->error(ctx, "variable name contains =");
return (-1);
}
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
env = &s->environ;
}
if (data->chflags & CMD_CHFLAG('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')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -r");
return (-1);
}
environ_set(env, data->arg, NULL);
} else {
if (data->arg2 == NULL) {
ctx->error(ctx, "no value specified");
return (-1);
}
environ_set(env, data->arg, data->arg2);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.62 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cmd-set-option.c,v 1.85 2009-11-02 21:38:26 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,101 +31,127 @@ int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
CMD_OPTION_SESSION_USAGE,
CMD_GFLAG|CMD_UFLAG,
"[-agu] " CMD_TARGET_SESSION_USAGE " option [value]",
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'),
NULL,
cmd_option_parse,
cmd_target_parse,
cmd_set_option_exec,
cmd_option_send,
cmd_option_recv,
cmd_option_free,
cmd_option_print
cmd_target_free,
cmd_target_print
};
const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_status_justify_list[] = {
"left", "centre", "right", NULL
};
const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL
};
const struct set_option_entry set_option_table[NSETOPTION] = {
const struct set_option_entry set_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 },
{ "default-command", SET_OPTION_STRING, 0, 0, NULL },
{ "default-path", SET_OPTION_STRING, 0, 0, NULL },
{ "default-shell", SET_OPTION_STRING, 0, 0, NULL },
{ "default-terminal", SET_OPTION_STRING, 0, 0, NULL },
{ "display-panes-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 },
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-command", SET_OPTION_STRING, 0, 0, NULL },
{ "lock-server", SET_OPTION_FLAG, 0, 0, NULL },
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "prefix", SET_OPTION_KEY, 0, 0, NULL },
{ "mouse-select-pane", SET_OPTION_FLAG, 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 },
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles-string", SET_OPTION_STRING, 0, 0, NULL },
{ "status", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "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",
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 },
{ "status-left-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-left-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-left-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "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-content", 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_option_data *data = self->data;
struct cmd_target_data *data = self->data;
struct session *s;
struct client *c;
struct options *oo;
const struct set_option_entry *entry;
const struct set_option_entry *entry, *opt;
struct jobs *jobs;
struct job *job, *nextjob;
u_int i;
int try_again;
if (data->flags & CMD_GFLAG)
oo = &global_options;
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 (*data->option == '\0') {
if (*data->arg == '\0') {
ctx->error(ctx, "invalid option");
return (-1);
}
entry = NULL;
for (i = 0; i < NSETOPTION; i++) {
if (strncmp(set_option_table[i].name,
data->option, strlen(data->option)) != 0)
for (opt = set_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->option);
ctx->error(ctx, "ambiguous option: %s", data->arg);
return (-1);
}
entry = &set_option_table[i];
entry = opt;
/* Bail now if an exact match. */
if (strcmp(entry->name, data->option) == 0)
if (strcmp(entry->name, data->arg) == 0)
break;
}
if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->option);
ctx->error(ctx, "unknown option: %s", data->arg);
return (-1);
}
if (data->flags & CMD_UFLAG) {
if (data->flags & CMD_GFLAG) {
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->value != NULL) {
if (data->arg2 != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
@@ -136,34 +162,61 @@ 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->value);
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->value);
set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->value);
case SET_OPTION_KEYS:
set_option_keys(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->value);
set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->value);
set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->value);
set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->value);
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)
/*
* 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) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
jobs = &c->status_jobs;
do {
try_again = 0;
job = RB_ROOT(jobs);
while (job != NULL) {
nextjob = RB_NEXT(jobs, jobs, job);
if (job->flags & JOB_PERSIST) {
job_remove(jobs, job);
try_again = 1;
break;
}
job = nextjob;
}
} while (try_again);
server_redraw_client(c);
}
}
return (0);

View File

@@ -1,169 +0,0 @@
/* $Id: cmd-set-password.c,v 1.5 2009-06-25 16:47:00 nicm 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 <pwd.h>
#include <unistd.h>
#include "tmux.h"
/*
* Set server password.
*/
int cmd_set_password_parse(struct cmd *, int, char **, char **);
int cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_password_send(struct cmd *, struct buffer *);
void cmd_set_password_recv(struct cmd *, struct buffer *);
void cmd_set_password_free(struct cmd *);
void cmd_set_password_init(struct cmd *, int);
size_t cmd_set_password_print(struct cmd *, char *, size_t);
struct cmd_set_password_data {
char *password;
int flag_encrypted;
};
const struct cmd_entry cmd_set_password_entry = {
"set-password", "pass",
"[-c] password",
0,
cmd_set_password_init,
cmd_set_password_parse,
cmd_set_password_exec,
cmd_set_password_send,
cmd_set_password_recv,
cmd_set_password_free,
cmd_set_password_print
};
void
cmd_set_password_init(struct cmd *self, unused int arg)
{
struct cmd_set_password_data *data;
self->data = data = xmalloc(sizeof *data);
data->password = NULL;
data->flag_encrypted = 0;
}
int
cmd_set_password_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_set_password_data *data;
int opt;
char *out;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "c")) != -1) {
switch (opt) {
case 'c':
data->flag_encrypted = 1;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 1)
goto usage;
if (!data->flag_encrypted) {
if ((out = crypt(argv[0], "$1")) != NULL)
data->password = xstrdup(out);
} else
data->password = xstrdup(argv[0]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_set_password_data *data = self->data;
if (data->password == NULL) {
ctx->error(ctx, "failed to encrypt password");
return (-1);
}
if (server_password != NULL)
xfree(server_password);
if (*data->password == '\0')
server_password = NULL;
else
server_password = xstrdup(data->password);
log_debug("pw now %s", server_password);
return (0);
}
void
cmd_set_password_send(struct cmd *self, struct buffer *b)
{
struct cmd_set_password_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->password);
}
void
cmd_set_password_recv(struct cmd *self, struct buffer *b)
{
struct cmd_set_password_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->password = cmd_recv_string(b);
}
void
cmd_set_password_free(struct cmd *self)
{
struct cmd_set_password_data *data = self->data;
if (data->password != NULL)
xfree(data->password);
xfree(data);
}
size_t
cmd_set_password_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_set_password_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_encrypted)
off += xsnprintf(buf + off, len - off, " -c");
if (off < len && data->password != NULL)
off += xsnprintf(buf + off, len - off, " password");
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.28 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cmd-set-window-option.c,v 1.40 2009-10-09 13:07:04 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,15 +31,13 @@ int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw",
CMD_OPTION_WINDOW_USAGE,
CMD_GFLAG|CMD_UFLAG,
"[-agu] " CMD_TARGET_WINDOW_USAGE " option [value]",
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'),
NULL,
cmd_option_parse,
cmd_target_parse,
cmd_set_window_option_exec,
cmd_option_send,
cmd_option_recv,
cmd_option_free,
cmd_option_print
cmd_target_free,
cmd_target_print
};
const char *set_option_mode_keys_list[] = {
@@ -48,7 +46,7 @@ const char *set_option_mode_keys_list[] = {
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
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 },
@@ -56,71 +54,77 @@ const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
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_option_data *data = self->data;
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry;
const struct set_option_entry *entry, *opt;
u_int i;
if (data->flags & CMD_GFLAG)
oo = &global_window_options;
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->option == '\0') {
if (*data->arg == '\0') {
ctx->error(ctx, "invalid option");
return (-1);
}
entry = NULL;
for (i = 0; i < NSETWINDOWOPTION; i++) {
if (strncmp(set_window_option_table[i].name,
data->option, strlen(data->option)) != 0)
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->option);
ctx->error(ctx, "ambiguous option: %s", data->arg);
return (-1);
}
entry = &set_window_option_table[i];
entry = opt;
/* Bail now if an exact match. */
if (strcmp(entry->name, data->option) == 0)
if (strcmp(entry->name, data->arg) == 0)
break;
}
if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->option);
ctx->error(ctx, "unknown option: %s", data->arg);
return (-1);
}
if (data->flags & CMD_UFLAG) {
if (data->flags & CMD_GFLAG) {
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->value != NULL) {
if (data->arg2 != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
@@ -131,25 +135,26 @@ cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else {
switch (entry->type) {
case SET_OPTION_STRING:
set_option_string(ctx, oo, entry, data->value);
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->value);
set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->value);
case SET_OPTION_KEYS:
set_option_keys(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->value);
set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->value);
set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->value);
set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->value);
set_option_choice(ctx, oo, entry, data->arg2);
break;
}
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-buffer.c,v 1.4 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-show-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,6 @@
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
@@ -31,12 +29,10 @@ 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,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
@@ -47,9 +43,9 @@ cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_buffer_data *data = self->data;
struct session *s;
struct paste_buffer *pb;
u_int size;
char *buf, *ptr;
size_t len;
char *in, *buf, *ptr;
size_t size, len;
u_int width;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
@@ -63,27 +59,43 @@ cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "no buffer %d", data->buffer);
return (-1);
}
if (pb == NULL)
return (0);
if (pb != NULL) {
size = s->sx;
size = pb->size;
if (size > SIZE_MAX / 4 - 1)
size = SIZE_MAX / 4 - 1;
in = xmalloc(size * 4 + 1);
strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB);
buf = xmalloc(size + 1);
len = 0;
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';
ptr = pb->data;
do {
buf[len++] = *ptr++;
if (len == size) {
buf[len] = '\0';
ctx->print(ctx, buf);
len = 0;
}
} while (*ptr != '\0');
ctx->print(ctx, "%s", buf);
len = 0;
}
} while (*ptr != '\0');
if (len != 0) {
buf[len] = '\0';
ctx->print(ctx, buf);
ctx->print(ctx, "%s", buf);
}
xfree(buf);
xfree(in);
return (0);
}

67
cmd-show-environment.c Normal file
View File

@@ -0,0 +1,67 @@
/* $Id: cmd-show-environment.c,v 1.1 2009-08-09 17:48:55 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 <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Show environment.
*/
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'),
cmd_target_init,
cmd_target_parse,
cmd_show_environment_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct environ *env;
struct environ_entry *envent;
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
env = &s->environ;
}
RB_FOREACH(envent, environ, env) {
if (envent->value != NULL)
ctx->print(ctx, "%s=%s", envent->name, envent->value);
else
ctx->print(ctx, "-%s", envent->name);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.11 2009-01-27 20:22:33 nicm Exp $ */
/* $Id: cmd-show-options.c,v 1.17 2009-09-22 13:56:02 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,12 +32,10 @@ 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,
CMD_GFLAG,
0, CMD_CHFLAG('g'),
cmd_target_init,
cmd_target_parse,
cmd_show_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -48,62 +46,23 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
u_int i;
char *vs;
long long vn;
const char *optval;
if (data->flags & CMD_GFLAG)
oo = &global_options;
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;
}
for (i = 0; i < NSETOPTION; i++) {
entry = &set_option_table[i];
if (options_find1(oo, entry->name) == NULL)
for (entry = set_option_table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
continue;
switch (entry->type) {
case SET_OPTION_STRING:
vs = options_get_string(oo, entry->name);
ctx->print(ctx, "%s \"%s\"", entry->name, vs);
break;
case SET_OPTION_NUMBER:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %lld", entry->name, vn);
break;
case SET_OPTION_KEY:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, key_string_lookup_key(vn));
break;
case SET_OPTION_COLOUR:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, colour_tostring(vn));
break;
case SET_OPTION_ATTRIBUTES:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, attributes_tostring(vn));
break;
case SET_OPTION_FLAG:
vn = options_get_number(oo, entry->name);
if (vn)
ctx->print(ctx, "%s on", entry->name);
else
ctx->print(ctx, "%s off", entry->name);
break;
case SET_OPTION_CHOICE:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, entry->choices[vn]);
break;
}
optval = set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-window-options.c,v 1.7 2009-01-27 20:22:33 nicm Exp $ */
/* $Id: cmd-show-window-options.c,v 1.13 2009-09-22 13:56:02 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,12 +32,10 @@ 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,
CMD_GFLAG,
0, CMD_CHFLAG('g'),
cmd_target_init,
cmd_target_parse,
cmd_show_window_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -48,62 +46,23 @@ 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;
u_int i;
char *vs;
long long vn;
const char *optval;
if (data->flags & CMD_GFLAG)
oo = &global_window_options;
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 (i = 0; i < NSETWINDOWOPTION; i++) {
entry = &set_window_option_table[i];
if (options_find1(oo, entry->name) == NULL)
for (entry = set_window_option_table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
continue;
switch (entry->type) {
case SET_OPTION_STRING:
vs = options_get_string(oo, entry->name);
ctx->print(ctx, "%s \"%s\"", entry->name, vs);
break;
case SET_OPTION_NUMBER:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %lld", entry->name, vn);
break;
case SET_OPTION_KEY:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, key_string_lookup_key(vn));
break;
case SET_OPTION_COLOUR:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, colour_tostring(vn));
break;
case SET_OPTION_ATTRIBUTES:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, attributes_tostring(vn));
break;
case SET_OPTION_FLAG:
vn = options_get_number(oo, entry->name);
if (vn)
ctx->print(ctx, "%s on", entry->name);
else
ctx->print(ctx, "%s off", entry->name);
break;
case SET_OPTION_CHOICE:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, entry->choices[vn]);
break;
}
optval = set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-source-file.c,v 1.5 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-source-file.c,v 1.9 2009-09-22 14:06:40 tcunha Exp $ */
/*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -26,8 +26,6 @@
int cmd_source_file_parse(struct cmd *, int, char **, char **);
int cmd_source_file_exec(struct cmd *, struct cmd_ctx *);
void cmd_source_file_send(struct cmd *, struct buffer *);
void cmd_source_file_recv(struct cmd *, struct buffer *);
void cmd_source_file_free(struct cmd *);
void cmd_source_file_init(struct cmd *, int);
size_t cmd_source_file_print(struct cmd *, char *, size_t);
@@ -39,12 +37,10 @@ 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,
cmd_source_file_send,
cmd_source_file_recv,
cmd_source_file_free,
cmd_source_file_print
};
@@ -64,7 +60,7 @@ cmd_source_file_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_source_file_data *data;
int opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "")) != -1) {
@@ -94,7 +90,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_source_file_data *data = self->data;
char *cause;
if (load_cfg(data->path, &cause) != 0) {
if (load_cfg(data->path, ctx, &cause) != 0) {
ctx->error(ctx, "%s", cause);
xfree(cause);
return (-1);
@@ -103,25 +99,6 @@ cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
void
cmd_source_file_send(struct cmd *self, struct buffer *b)
{
struct cmd_source_file_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->path);
}
void
cmd_source_file_recv(struct cmd *self, struct buffer *b)
{
struct cmd_source_file_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->path = cmd_recv_string(b);
}
void
cmd_source_file_free(struct cmd *self)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-split-window.c,v 1.15 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cmd-split-window.c,v 1.28 2009-09-22 14:06:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,8 +29,6 @@
int cmd_split_window_parse(struct cmd *, int, char **, char **);
int cmd_split_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_split_window_send(struct cmd *, struct buffer *);
void cmd_split_window_recv(struct cmd *, struct buffer *);
void cmd_split_window_free(struct cmd *);
void cmd_split_window_init(struct cmd *, int);
size_t cmd_split_window_print(struct cmd *, char *, size_t);
@@ -39,25 +37,24 @@ struct cmd_split_window_data {
char *target;
char *cmd;
int flag_detached;
int flag_horizontal;
int percentage;
int lines;
int size;
};
const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"[-d] [-p percentage|-l lines] [-t target-window] [command]",
0,
"[-dhv] [-p percentage|-l size] [-t target-window] [command]",
0, 0,
cmd_split_window_init,
cmd_split_window_parse,
cmd_split_window_exec,
cmd_split_window_send,
cmd_split_window_recv,
cmd_split_window_free,
cmd_split_window_print
};
void
cmd_split_window_init(struct cmd *self, unused int arg)
cmd_split_window_init(struct cmd *self, int key)
{
struct cmd_split_window_data *data;
@@ -65,50 +62,63 @@ cmd_split_window_init(struct cmd *self, unused int arg)
data->target = NULL;
data->cmd = NULL;
data->flag_detached = 0;
data->flag_horizontal = 0;
data->percentage = -1;
data->lines = -1;
data->size = -1;
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
case '"':
data->flag_horizontal = 0;
break;
}
}
int
cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_split_window_data *data;
int opt, n;
int opt;
const char *errstr;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dl:p:t:")) != -1) {
while ((opt = getopt(argc, argv, "dhl:p:t:v")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
break;
case 'h':
data->flag_horizontal = 1;
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'l':
if (data->percentage == -1 && data->lines == -1) {
n = strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "lines %s", errstr);
goto error;
}
data->lines = n;
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->lines == -1 && data->percentage == -1) {
n = strtonum(optarg, 1, 100, &errstr);
if (errstr != NULL) {
xasprintf(
cause, "percentage %s", errstr);
goto error;
}
data->percentage = n;
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;
}
@@ -139,38 +149,53 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl;
struct window *w;
struct window_pane *wp;
const char **env;
struct environ env;
char *cmd, *cwd, *cause;
const char *shell;
u_int hlimit;
int lines;
int size;
enum layout_type type;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
w = wl->window;
env = server_fill_environ(s);
environ_init(&env);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
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(&global_options, "default-path");
cwd = options_get_string(&s->options, "default-path");
else
cwd = ctx->cmdclient->cwd;
lines = -1;
if (data->lines != -1)
lines = data->lines;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1)
lines = (w->active->sy * data->percentage) / 100;
size = (w->active->sy * data->percentage) / 100;
hlimit = options_get_number(&s->options, "history-limit");
wp = window_add_pane(w, lines, cmd, cwd, env, hlimit, &cause);
if (wp == NULL) {
ctx->error(ctx, "create pane failed: %s", cause);
xfree(cause);
return (-1);
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
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) {
cause = xstrdup("pane too small");
goto error;
}
server_redraw_window(w);
if (!data->flag_detached) {
@@ -179,30 +204,17 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_session(s);
} else
server_status_session(s);
layout_refresh(w, 0);
environ_free(&env);
return (0);
}
void
cmd_split_window_send(struct cmd *self, struct buffer *b)
{
struct cmd_split_window_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
cmd_send_string(b, data->cmd);
}
void
cmd_split_window_recv(struct cmd *self, struct buffer *b)
{
struct cmd_split_window_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
error:
environ_free(&env);
if (wp != NULL)
window_remove_pane(w, wp);
ctx->error(ctx, "create pane failed: %s", cause);
xfree(cause);
return (-1);
}
void
@@ -228,6 +240,14 @@ cmd_split_window_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->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->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->cmd != NULL)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-start-server.c,v 1.6 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-start-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,13 +29,11 @@ int cmd_start_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_start_server_entry = {
"start-server", "start",
"",
CMD_STARTSERVER,
CMD_STARTSERVER, 0,
NULL,
NULL,
cmd_start_server_exec,
NULL,
NULL,
NULL,
NULL
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.17 2009-06-25 16:21:32 nicm Exp $ */
/* $Id: cmd-string.c,v 1.24 2009-10-28 23:12:38 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,9 +19,11 @@
#include <sys/types.h>
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
@@ -33,6 +35,7 @@ int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(const char *, 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 *);
int
cmd_string_getc(const char *s, size_t *p)
@@ -56,21 +59,11 @@ int
cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
{
size_t p;
int ch, argc, rval, have_arg;
char **argv, *buf, *t, *u;
int ch, i, argc, rval, have_arg;
char **argv, *buf, *t;
const char *whitespace, *equals;
size_t len;
if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL)
t = strchr(s, '\0');
if ((u = strchr(s, '=')) != NULL && u < t) {
if (putenv(xstrdup(s)) != 0) {
xasprintf(cause, "assignment failed: %s", s);
return (-1);
}
*cmdlist = NULL;
return (0);
}
argv = NULL;
argc = 0;
@@ -114,6 +107,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
@@ -143,6 +137,18 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
if (argc == 0)
goto out;
for (i = 0; i < argc; i++) {
equals = strchr(argv[i], '=');
whitespace = argv[i] + strcspn(argv[i], " \t");
if (equals == NULL || equals > whitespace)
break;
environ_put(&global_environ, argv[i]);
memmove(&argv[i], &argv[i + 1], argc - i - 1);
argc--;
}
if (argc == 0)
goto out;
*cmdlist = cmd_list_parse(argc, argv, cause);
if (*cmdlist == NULL)
goto out;
@@ -153,6 +159,17 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
rval = 0;
goto out;
case '~':
if (have_arg == 0) {
if ((t = cmd_string_expand_tilde(s, &p)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
break;
}
/* FALLTHROUGH */
default:
if (len >= SIZE_MAX - 2)
goto error;
@@ -187,30 +204,33 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
char *buf, *t;
size_t len;
buf = NULL;
buf = NULL;
len = 0;
while ((ch = cmd_string_getc(s, p)) != endch) {
switch (ch) {
while ((ch = cmd_string_getc(s, p)) != endch) {
switch (ch) {
case EOF:
goto error;
case '\\':
case '\\':
if (!esc)
break;
switch (ch = cmd_string_getc(s, p)) {
switch (ch = cmd_string_getc(s, p)) {
case EOF:
goto error;
case 'r':
ch = '\r';
break;
case 'n':
ch = '\n';
break;
case 't':
ch = '\t';
break;
}
break;
case 'e':
ch = '\033';
break;
case 'r':
ch = '\r';
break;
case 'n':
ch = '\n';
break;
case 't':
ch = '\t';
break;
}
break;
case '$':
if (!esc)
break;
@@ -219,14 +239,15 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
continue;
}
}
if (len >= SIZE_MAX - 2)
goto error;
buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch;
}
buf[len++] = ch;
}
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
@@ -251,7 +272,7 @@ cmd_string_variable(const char *s, size_t *p)
((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z') || \
((ch) >= '0' && (ch) <= '9'))
buf = NULL;
buf = NULL;
len = 0;
fch = EOF;
@@ -307,3 +328,31 @@ error:
xfree(buf);
return (NULL);
}
char *
cmd_string_expand_tilde(const char *s, size_t *p)
{
struct passwd *pw;
char *home, *path, *username;
home = NULL;
if (cmd_string_getc(s, p) == '/') {
if ((home = getenv("HOME")) == NULL) {
if ((pw = getpwuid(getuid())) != NULL)
home = pw->pw_dir;
}
} else {
cmd_string_ungetc(s, 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);
}
if (home == NULL)
return (NULL);
xasprintf(&path, "%s/", home);
return (path);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-suspend-client.c,v 1.2 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-suspend-client.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -37,12 +37,10 @@ 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,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-pane.c,v 1.6 2009-06-25 15:28:08 nicm Exp $ */
/* $Id: cmd-swap-pane.c,v 1.13 2009-07-30 21:04:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,269 +26,118 @@
* Swap two panes.
*/
int cmd_swap_pane_parse(struct cmd *, int, char **, char **);
int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_swap_pane_send(struct cmd *, struct buffer *);
void cmd_swap_pane_recv(struct cmd *, struct buffer *);
void cmd_swap_pane_free(struct cmd *);
void cmd_swap_pane_init(struct cmd *, int);
size_t cmd_swap_pane_print(struct cmd *, char *, size_t);
struct cmd_swap_pane_data {
char *target;
int src;
int dst;
int flag_detached;
int flag_up;
int flag_down;
};
int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp",
"[-dDU] [-t target-window] [-p src-index] [-q dst-index]",
0,
"[-dDU] " CMD_SRCDST_PANE_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('D')|CMD_CHFLAG('U'),
cmd_swap_pane_init,
cmd_swap_pane_parse,
cmd_srcdst_parse,
cmd_swap_pane_exec,
cmd_swap_pane_send,
cmd_swap_pane_recv,
cmd_swap_pane_free,
cmd_swap_pane_print
cmd_srcdst_free,
cmd_srcdst_print
};
void
cmd_swap_pane_init(struct cmd *self, int key)
{
struct cmd_swap_pane_data *data;
struct cmd_target_data *data;
self->data = data = xmalloc(sizeof *data);
data->target = NULL;
data->src = -1;
data->dst = -1;
data->flag_detached = 0;
data->flag_up = 0;
data->flag_down = 0;
switch (key) {
case '{':
data->flag_up = 1;
break;
case '}':
data->flag_down = 1;
break;
}
}
int
cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_swap_pane_data *data;
int opt, n;
const char *errstr;
self->entry->init(self, 0);
cmd_srcdst_init(self, key);
data = self->data;
while ((opt = getopt(argc, argv, "dDt:p:q:U")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
break;
case 'D':
data->flag_up = 0;
data->flag_down = 1;
data->dst = -1;
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'p':
if (data->src == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "src %s", errstr);
goto error;
}
data->src = n;
}
break;
case 'q':
if (data->dst == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "dst %s", errstr);
goto error;
}
data->dst = n;
}
data->flag_up = 0;
data->flag_down = 0;
break;
case 'U':
data->flag_up = 1;
data->flag_down = 0;
data->dst = -1;
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);
if (key == '{')
data->chflags |= CMD_CHFLAG('U');
else if (key == '}')
data->chflags |= CMD_CHFLAG('D');
}
int
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_swap_pane_data *data = self->data;
struct winlink *wl;
struct window *w;
struct window_pane *tmp_wp, *src_wp, *dst_wp;
u_int xx, yy;
int flags;
struct cmd_srcdst_data *data = self->data;
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w;
struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *src_lc, *dst_lc;
u_int sx, sy, xoff, yoff;
if (data == NULL)
return (0);
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if ((dst_wl = cmd_find_pane(ctx, data->dst, NULL, &dst_wp)) == NULL)
return (-1);
w = wl->window;
dst_w = dst_wl->window;
if (data->src == -1)
src_wp = w->active;
else {
src_wp = window_pane_at_index(w, data->src);
if (src_wp == NULL) {
ctx->error(ctx, "no pane: %d", data->src);
if (data->src == NULL) {
src_w = dst_w;
if (data->chflags & CMD_CHFLAG('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')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
} else
return (0);
} else {
src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp);
if (src_wl == NULL)
return (-1);
}
}
if (data->dst == -1)
dst_wp = w->active;
else {
dst_wp = window_pane_at_index(w, data->dst);
if (dst_wp == NULL) {
ctx->error(ctx, "no pane: %d", data->dst);
return (-1);
}
}
if (data->dst == -1 && data->flag_up) {
if ((dst_wp = TAILQ_PREV(src_wp, window_panes, entry)) == NULL)
dst_wp = TAILQ_LAST(&w->panes, window_panes);
}
if (data->dst == -1 && data->flag_down) {
if ((dst_wp = TAILQ_NEXT(src_wp, entry)) == NULL)
dst_wp = TAILQ_FIRST(&w->panes);
src_w = src_wl->window;
}
if (src_wp == dst_wp)
return (0);
tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
TAILQ_REMOVE(&w->panes, dst_wp, entry);
TAILQ_REPLACE(&w->panes, src_wp, dst_wp, entry);
TAILQ_REMOVE(&dst_w->panes, dst_wp, entry);
TAILQ_REPLACE(&src_w->panes, src_wp, dst_wp, entry);
if (tmp_wp == src_wp)
tmp_wp = dst_wp;
if (tmp_wp == NULL)
TAILQ_INSERT_HEAD(&w->panes, src_wp, entry);
TAILQ_INSERT_HEAD(&dst_w->panes, src_wp, entry);
else
TAILQ_INSERT_AFTER(&w->panes, tmp_wp, src_wp, entry);
TAILQ_INSERT_AFTER(&dst_w->panes, tmp_wp, src_wp, entry);
xx = src_wp->xoff;
yy = src_wp->yoff;
flags = src_wp->flags;
src_wp->xoff = dst_wp->xoff;
src_wp->yoff = dst_wp->yoff;
src_wp->flags &= ~PANE_HIDDEN;
src_wp->flags |= dst_wp->flags & PANE_HIDDEN;
dst_wp->xoff = xx;
dst_wp->yoff = yy;
dst_wp->flags &= ~PANE_HIDDEN;
dst_wp->flags |= flags & PANE_HIDDEN;
src_lc = src_wp->layout_cell;
dst_lc = dst_wp->layout_cell;
src_lc->wp = dst_wp;
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;
xx = src_wp->sx;
yy = src_wp->sy;
sx = src_wp->sx; sy = src_wp->sy;
xoff = src_wp->xoff; yoff = src_wp->yoff;
src_wp->xoff = dst_wp->xoff; src_wp->yoff = dst_wp->yoff;
window_pane_resize(src_wp, dst_wp->sx, dst_wp->sy);
window_pane_resize(dst_wp, xx, yy);
dst_wp->xoff = xoff; dst_wp->yoff = yoff;
window_pane_resize(dst_wp, sx, sy);
if (!data->flag_detached) {
tmp_wp = dst_wp;
if (tmp_wp->flags & PANE_HIDDEN)
tmp_wp = src_wp;
window_set_active_pane(w, tmp_wp);
layout_refresh(w, 0);
if (!(data->chflags & CMD_CHFLAG('d'))) {
if (src_w != dst_w) {
window_set_active_pane(src_w, dst_wp);
window_set_active_pane(dst_w, src_wp);
} else {
tmp_wp = dst_wp;
if (!window_pane_visible(tmp_wp))
tmp_wp = src_wp;
window_set_active_pane(src_w, tmp_wp);
}
} else {
if (src_w->active == src_wp)
window_set_active_pane(src_w, dst_wp);
if (dst_w->active == dst_wp)
window_set_active_pane(dst_w, src_wp);
}
server_redraw_window(src_w);
server_redraw_window(dst_w);
return (0);
}
void
cmd_swap_pane_send(struct cmd *self, struct buffer *b)
{
struct cmd_swap_pane_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
}
void
cmd_swap_pane_recv(struct cmd *self, struct buffer *b)
{
struct cmd_swap_pane_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
}
void
cmd_swap_pane_free(struct cmd *self)
{
struct cmd_swap_pane_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
xfree(data);
}
size_t
cmd_swap_pane_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_swap_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_down || data->flag_up || data->flag_detached)) {
off += xsnprintf(buf + off, len - off, " -");
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, "d");
if (off < len && data->flag_up)
off += xsnprintf(buf + off, len - off, "D");
if (off < len && data->flag_down)
off += xsnprintf(buf + off, len - off, "U");
}
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->src != -1)
off += xsnprintf(buf + off, len - off, " -p %d", data->src);
if (off < len && data->dst != -1)
off += xsnprintf(buf + off, len - off, " -q %d", data->dst);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-window.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-swap-window.c,v 1.18 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,12 +31,10 @@ 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,
CMD_DFLAG,
0, CMD_CHFLAG('d'),
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_swap_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free,
cmd_srcdst_print
};
@@ -46,6 +44,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *src, *dst;
struct session_group *sg_src, *sg_dst;
struct winlink *wl_src, *wl_dst;
struct window *w;
@@ -54,6 +53,14 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl_dst = cmd_find_window(ctx, data->dst, &dst)) == NULL)
return (-1);
sg_src = session_group_find(src);
sg_dst = session_group_find(dst);
if (src != dst &&
sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) {
ctx->error(ctx, "can't move window, sessions are grouped");
return (-1);
}
if (wl_dst->window == wl_src->window)
return (0);
@@ -61,14 +68,17 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl_dst->window = wl_src->window;
wl_src->window = w;
if (!(data->flags & CMD_DFLAG)) {
if (!(data->chflags & CMD_CHFLAG('d'))) {
session_select(dst, wl_dst->idx);
if (src != dst)
session_select(src, wl_src->idx);
}
server_redraw_session(src);
if (src != dst)
server_redraw_session(dst);
session_group_synchronize_from(src);
server_redraw_session_group(src);
if (src != dst) {
session_group_synchronize_from(dst);
server_redraw_session_group(dst);
}
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-switch-client.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-switch-client.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,8 +29,6 @@
int cmd_switch_client_parse(struct cmd *, int, char **, char **);
int cmd_switch_client_exec(struct cmd *, struct cmd_ctx *);
void cmd_switch_client_send(struct cmd *, struct buffer *);
void cmd_switch_client_recv(struct cmd *, struct buffer *);
void cmd_switch_client_free(struct cmd *);
size_t cmd_switch_client_print(struct cmd *, char *, size_t);
@@ -42,12 +40,10 @@ 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,
cmd_switch_client_send,
cmd_switch_client_recv,
cmd_switch_client_free,
cmd_switch_client_print
};
@@ -111,27 +107,6 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
void
cmd_switch_client_send(struct cmd *self, struct buffer *b)
{
struct cmd_switch_client_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->name);
cmd_send_string(b, data->target);
}
void
cmd_switch_client_recv(struct cmd *self, struct buffer *b)
{
struct cmd_switch_client_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->name = cmd_recv_string(b);
data->target = cmd_recv_string(b);
}
void
cmd_switch_client_free(struct cmd *self)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unbind-key.c,v 1.16 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-unbind-key.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,23 +26,24 @@
int cmd_unbind_key_parse(struct cmd *, int, char **, char **);
int cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *);
void cmd_unbind_key_send(struct cmd *, struct buffer *);
void cmd_unbind_key_recv(struct cmd *, struct buffer *);
void cmd_unbind_key_free(struct cmd *);
int cmd_unbind_key_table(struct cmd *, struct cmd_ctx *);
struct cmd_unbind_key_data {
int key;
int command_key;
char *tablename;
};
const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind",
"key",
0,
"[-cn] [-t key-table] key",
0, 0,
NULL,
cmd_unbind_key_parse,
cmd_unbind_key_exec,
cmd_unbind_key_send,
cmd_unbind_key_recv,
cmd_unbind_key_free,
NULL
};
@@ -51,12 +52,23 @@ int
cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_unbind_key_data *data;
int opt;
int opt, no_prefix = 0;
self->data = data = xmalloc(sizeof *data);
data->command_key = 0;
data->tablename = NULL;
while ((opt = getopt(argc, argv, "")) != -1) {
while ((opt = getopt(argc, argv, "cnt:")) != -1) {
switch (opt) {
case 'c':
data->command_key = 1;
break;
case 'n':
no_prefix = 1;
break;
case 't':
data->tablename = xstrdup(optarg);
break;
default:
goto usage;
}
@@ -70,6 +82,8 @@ cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
xasprintf(cause, "unknown key: %s", argv[0]);
goto error;
}
if (!no_prefix)
data->key |= KEYC_PREFIX;
return (0);
@@ -88,27 +102,33 @@ cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
if (data == NULL)
return (0);
if (data->tablename != NULL)
return (cmd_unbind_key_table(self, ctx));
key_bindings_remove(data->key);
return (0);
}
void
cmd_unbind_key_send(struct cmd *self, struct buffer *b)
int
cmd_unbind_key_table(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_unbind_key_data *data = self->data;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
buffer_write(b, data, sizeof *data);
}
if ((mtab = mode_key_findtable(data->tablename)) == NULL) {
ctx->error(ctx, "unknown key table: %s", data->tablename);
return (-1);
}
void
cmd_unbind_key_recv(struct cmd *self, struct buffer *b)
{
struct cmd_unbind_key_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
mtmp.key = data->key & ~KEYC_PREFIX;
mtmp.mode = data->command_key ? 1 : 0;
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
SPLAY_REMOVE(mode_key_tree, mtab->tree, mbind);
xfree(mbind);
}
return (0);
}
void
@@ -116,5 +136,7 @@ cmd_unbind_key_free(struct cmd *self)
{
struct cmd_unbind_key_data *data = self->data;
if (data->tablename != NULL)
xfree(data->tablename);
xfree(data);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unlink-window.c,v 1.13 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-unlink-window.c,v 1.19 2009-10-11 23:38:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,13 +28,11 @@ int cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
CMD_TARGET_WINDOW_USAGE,
0,
"[-k] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('k'),
cmd_target_init,
cmd_target_parse,
cmd_unlink_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,30 +42,29 @@ cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct session *s;
struct client *c;
u_int i;
int destroyed;
struct window *w;
struct session *s, *s2;
struct session_group *sg;
u_int references;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
w = wl->window;
if (wl->window->references == 1) {
sg = session_group_find(s);
if (sg != NULL) {
references = 0;
TAILQ_FOREACH(s2, &sg->sessions, gentry)
references++;
} else
references = 1;
if (!(data->chflags & CMD_CHFLAG('k')) && w->references == references) {
ctx->error(ctx, "window is only linked to one session");
return (-1);
}
destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
server_unlink_window(s, wl);
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-up-pane.c,v 1.7 2009-04-01 21:10:08 nicm Exp $ */
/* $Id: cmd-up-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,12 +29,10 @@ int cmd_up_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_up_pane_entry = {
"up-pane", "upp",
CMD_TARGET_WINDOW_USAGE,
0,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_up_pane_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -54,8 +52,8 @@ cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_PREV(w->active, window_panes, entry);
if (w->active == NULL)
w->active = TAILQ_LAST(&w->panes, window_panes);
layout_refresh(w, 1);
} while (w->active->flags & PANE_HIDDEN);
} while (!window_pane_visible(w->active));
server_status_window(wl->window);
return (0);
}

869
cmd.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $Id: colour.c,v 1.6 2009-05-18 15:42:30 nicm Exp $ */
/* $Id: colour.c,v 1.7 2009-09-11 14:13:52 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,13 +18,42 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
const char *
colour_tostring(u_char c)
/*
* Colour to string conversion functions. Bit 8 of the colour means it is one
* of the 256 colour palette.
*/
void
colour_set_fg(struct grid_cell *gc, int c)
{
if (c & 0x100)
gc->flags |= GRID_FLAG_FG256;
gc->fg = c;
}
void
colour_set_bg(struct grid_cell *gc, int c)
{
if (c & 0x100)
gc->flags |= GRID_FLAG_BG256;
gc->bg = c;
}
const char *
colour_tostring(int c)
{
static char s[32];
if (c & 0x100) {
xsnprintf(s, sizeof s, "colour%u", c & ~0x100);
return (s);
}
switch (c) {
case 0:
return ("black");
@@ -51,6 +80,16 @@ colour_tostring(u_char c)
int
colour_fromstring(const char *s)
{
const char *errstr;
int n;
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
if (errstr != NULL)
return (-1);
return (n | 0x100);
}
if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0'))
return (0);
if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0'))

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