1285 Commits
0.8 ... 1.4

Author SHA1 Message Date
no_author
2365b09d6a This commit was manufactured by cvs2svn to create tag 'TMUX_1_4'. 2010-12-27 21:37:43 +00:00
Tiago Cunha
dcef4f8084 Major changes since the previous version. 2010-12-27 21:37:42 +00:00
Tiago Cunha
030d284006 No point in talking about this here when it's already covered by other files. 2010-12-27 21:36:37 +00:00
Tiago Cunha
1b037f74f4 Bump VERSION and comment FDEBUG. 2010-12-27 21:32:16 +00:00
Tiago Cunha
750e6ad542 usage output should fit on a 80 column display. 2010-12-27 21:22:24 +00:00
Tiago Cunha
5f72510edf Sync OpenBSD patchset 810:
tweak previous;
2010-12-27 21:17:25 +00:00
Tiago Cunha
5d86284a1a Sync OpenBSD patchset 809:
Add a missing .Pp and sort options alphabetically, from Tiago Cunha.
2010-12-27 21:13:59 +00:00
Tiago Cunha
3cd9ea1789 Sync OpenBSD patchset 808:
server_kill_window can modify the RB tree so don't use RB_FOREACH, fixes
crash seen by Dan Harnett.
2010-12-25 23:44:37 +00:00
Tiago Cunha
3585feca54 Sync OpenBSD patchset 807:
Style tweaks.
2010-12-25 23:43:53 +00:00
Tiago Cunha
a373235106 Sync OpenBSD patchset 806:
Store sessions in an RB tree by name rather than a list, this is tidier
and allows them to easily be shown sorted in various lists
(list-sessions/choose-sessions).

Keep a session index which is used in a couple of places internally but
make it an ever-increasing number rather than filling in gaps with new
sessions.
2010-12-22 15:36:44 +00:00
Tiago Cunha
9f3399da00 Sync OpenBSD patchset 805:
Fix another stray addition that was too early. Oops.
2010-12-22 15:33:14 +00:00
Tiago Cunha
c05a47ad0d Sync OpenBSD patchset 804:
Undo a change to next/previous session that got mixed in prematurely.
2010-12-22 15:32:40 +00:00
Tiago Cunha
a932742a8a Sync OpenBSD patchset 803:
Dead sessions are never on the active sessions list, so the SESSION_DEAD
flag is effectively unused. Remove it.
2010-12-22 15:31:56 +00:00
Tiago Cunha
bb728b89a7 Sync OpenBSD patchset 802:
Use pointer rather than index for the client's last session.
2010-12-22 15:31:00 +00:00
Tiago Cunha
64d16cf2d6 Sync OpenBSD patchset 801:
Unify the way sessions are used by callbacks - store the address and use
the reference count, then check it is still on the global sessions list
in the callback.
2010-12-22 15:28:51 +00:00
Tiago Cunha
b8eae3902b Sync OpenBSD patchset 800:
Don't nuke the index counter when a session group comes up.
2010-12-22 15:25:07 +00:00
Tiago Cunha
d1bdc9a161 Sync OpenBSD patchset 799:
Add other-pane-height and other-pane-width options, allowing the width
or height of the smaller panes in the main-horizontal and main-vertical
layouts to be set. Mostly from David Goodlad.
2010-12-22 15:23:59 +00:00
Nicholas Marriott
cd92f44686 "So you have screwed up your /dev/null?" From Mathias Gumz. 2010-12-15 23:31:30 +00:00
Nicholas Marriott
206ae727f9 Read ${X} environment variables in strings and $HOME from the global
environment rather than getenv, this allows them to be updated during
the configuration file.
2010-12-13 22:53:56 +00:00
Nicholas Marriott
5fcd6711e4 Track the last session for a client and add a flag to switch-client and
a key binding (L) to move a client back to its last session.
2010-12-11 18:42:20 +00:00
Nicholas Marriott
d227a2e661 Remove a bunch of stuff that is done a few that aren't going to happen
and remove the priority list for now.
2010-12-11 18:06:42 +00:00
Nicholas Marriott
0b8ce56d73 Fix rectangle copy to behave like emacs - the cursor is not part of the
selection on the right edge but on the left it is.
2010-12-11 17:57:28 +00:00
Nicholas Marriott
095ffe9cd1 Make the prompt history global for all clients which is much more useful
than per-client history.
2010-12-11 16:15:02 +00:00
Nicholas Marriott
1a4d78c7af -V to report version, SF issue 3038862. 2010-12-10 21:19:13 +00:00
Nicholas Marriott
286fef9b4d Rephrase a confusing sentence. 2010-12-10 21:05:22 +00:00
Nicholas Marriott
1891f1ce99 Some do still need -lrt. 2010-12-08 19:55:31 +00:00
Micah Cowan
3ab25ac5b5 In the built-in layouts, distribute the panes more evenly.
Set the default value of main-pane-width to 80, rather than 81.
2010-12-07 20:23:21 +00:00
Nicholas Marriott
3a4f765a51 Add an option to alert (monitor) for silence (lack of activity) in a
window. From Thomas Adam.
2010-12-06 22:52:21 +00:00
Nicholas Marriott
d0adcbc98a PatchSet 790
Date: 2010/11/29 19:45:58
Author: nicm
Branch: HEAD
Tag: (none)
Log:
If VISUAL or EDITOR contains "vi", configure mode-keys and status-keys
to vi.

Based on a diff from martynas@, previously requested by a couple of
other people.

Members:
        tmux.1:1.190->1.191
        tmux.c:1.93->1.94
2010-12-06 21:59:42 +00:00
Nicholas Marriott
e75187310d PatchSet 789
Date: 2010/11/22 21:13:13
Author: nicm
Branch: HEAD
Tag: (none)
Log:
There is somewhere that WINDOW_HIDDEN is getting set when it shouldn't
be and I can't find it, but the flag itself is a useless optimisation
that only applies to automatic-resize windows, so just dispose of it
entirely.

Fixes problems reported by Nicholas Riley.

Members:
        resize.c:1.5->1.6
        tmux.h:1.246->1.247
        tty.c:1.92->1.93
2010-12-06 21:57:56 +00:00
Nicholas Marriott
7a0468c95c PatchSet 788
Date: 2010/11/15 06:52:11
Author: nicm
Branch: HEAD
Tag: (none)
Log:
Show more window and pane flags in list-* output, and put layout on the
same line.

Members:
        cmd-list-panes.c:1.5->1.6
        cmd-list-windows.c:1.9->1.10
2010-12-06 21:56:32 +00:00
Nicholas Marriott
1b0d235e3a PatchSet 787
Date: 2010/11/14 09:04:22
Author: nicm
Branch: HEAD
Tag: (none)
Log:
Update man page for update-environment.

Members:
        tmux.1:1.189->1.190
2010-12-06 21:55:42 +00:00
Nicholas Marriott
36e537bcef PatchSet 786
Date: 2010/11/14 08:58:25
Author: nicm
Branch: HEAD
Tag: (none)
Log:
Don't allow last and active window to become the same - a very bad move
when the active window is closed and freed. Reported by sthen@.

Members:
        window.c:1.58->1.59
2010-12-06 21:53:50 +00:00
Nicholas Marriott
fd51bf61c9 Add XAUTHORITY to update-environment, requested by Andreas Kloeckner. 2010-12-06 21:53:00 +00:00
Nicholas Marriott
fe4f760eba PatchSet 784
Date: 2010/11/11 20:54:06
Author: nicm
Branch: HEAD
Tag: (none)
Log:
Flag to flush all key bindings from Rob Paisley.

Members:
        cmd-unbind-key.c:1.7->1.8
        tmux.1:1.188->1.189
2010-12-06 21:51:02 +00:00
Nicholas Marriott
3a4b82d27a PatchSet 783
Date: 2010/11/11 20:51:30
Author: nicm
Branch: HEAD
Tag: (none)
Log:
Declaration in header should be extern.

Members:
        tmux.h:1.245->1.246
2010-12-06 21:50:24 +00:00
Nicholas Marriott
ccdafdabca PatchSet 782
Date: 2010/11/01 20:59:45
Author: nicm
Branch: HEAD
Tag: (none)
Log:
Typo, from Rob Paisley.

Members:
        tmux.1:1.187->1.188
2010-12-06 21:49:57 +00:00
Nicholas Marriott
39e277be3c |---------------------
|PatchSet 781
|Date: 2010/10/29 21:11:57
|Author: nicm
|Branch: HEAD
|Tag: (none)
|Log:
|We now send argv to the server after parsing it in the client to get the
|command, so the client should not modify it. Instead, take a copy. Fixes
|parsing command lists, reported by mcbride@.
|
|Members:
|       cmd-list.c:1.5->1.6
|       cmd.c:1.45->1.46
|       tmux.h:1.244->1.245
2010-12-06 21:48:56 +00:00
Nicholas Marriott
1650155589 Another. 2010-12-06 17:10:42 +00:00
Nicholas Marriott
42327f06df And moar. 2010-12-06 17:09:00 +00:00
Nicholas Marriott
1585b1e928 Moar. 2010-12-06 17:05:31 +00:00
Nicholas Marriott
9ab191b053 + SF requests. 2010-12-06 17:03:22 +00:00
Nicholas Marriott
13032d1d88 Using working directory always, from Vivien Mallet. 2010-12-06 17:00:34 +00:00
Nicholas Marriott
64387d18dd +. 2010-12-04 15:28:14 +00:00
Nicholas Marriott
25bf0faf21 +. 2010-11-22 22:29:30 +00:00
Nicholas Marriott
112fc58e6e +. 2010-11-15 20:34:38 +00:00
Nicholas Marriott
ba68bed10e +. 2010-11-13 16:55:30 +00:00
Nicholas Marriott
30e8ed393e Whoops, get the logic the right way round. 2010-11-13 16:29:05 +00:00
Nicholas Marriott
a6fc49ae08 Fix AIX warnings. 2010-11-11 20:45:49 +00:00
Nicholas Marriott
94c2adf499 malloc(0) may return NULL, so only assume that is an error if allocating
more than zero.
2010-11-11 20:41:08 +00:00
Nicholas Marriott
9c541e42f0 AIX doesn't have daemon(). 2010-11-11 20:37:53 +00:00
Nicholas Marriott
96601ce9fe Bring back fuzz.c. 2010-11-02 20:55:13 +00:00
Nicholas Marriott
1cec111af3 >4 now. 2010-11-01 21:42:20 +00:00
Nicholas Marriott
ae7a7be819 I am almost certain we don't need crypt or rt now, and it builds fine on
Linux without.
2010-10-27 21:40:03 +00:00
Nicholas Marriott
58684ea998 And more. 2010-10-27 21:34:59 +00:00
Nicholas Marriott
914f8584ef Style tweaks. 2010-10-27 21:33:15 +00:00
Nicholas Marriott
2287ec7b3e Compat for closefrom(). 2010-10-27 20:21:01 +00:00
Nicholas Marriott
8f84217023 Put setproctitle back under HAVE_SETPROCTITLE. 2010-10-24 19:54:41 +00:00
Tiago Cunha
83447580b1 Remove redundant preprocessor check (it's already taken care of by tmux.h). 2010-10-24 01:55:21 +00:00
Tiago Cunha
1cd9ff4460 Ugh. Don't know how this happened, but make it compile by removing duplicate
code.
2010-10-24 01:51:34 +00:00
Tiago Cunha
cd079e8fbf Sync OpenBSD patchset 780:
Add a last-pane command (bound to ; by default). Requested ages ago by
somebody whose name I have forgotten.
2010-10-24 01:34:30 +00:00
Tiago Cunha
8703e9f2f9 Sync OpenBSD patchset 779:
When removing a pane, don't change the active pane unless the active
pane is actually the one being removed.
2010-10-24 01:32:35 +00:00
Tiago Cunha
2da0730f78 Sync OpenBSD patchset 778:
Mark repeating keys with "(repeat)" in the key list.
2010-10-24 01:31:57 +00:00
Tiago Cunha
bdbd4e28c2 Sync OpenBSD patchset 777:
Merge the before and after attach client code into one in client.c
(instead of two in tmux.c and client.c).
2010-10-24 01:31:08 +00:00
Tiago Cunha
1276ea3653 Zap paths.h compat include. 2010-10-24 00:50:11 +00:00
Tiago Cunha
f79b467dce Sync OpenBSD patchset 776:
Make stdio blocking again before calling shell command with -c.
2010-10-24 00:47:46 +00:00
Tiago Cunha
d4b58c71a2 Sync OpenBSD patchset 775:
Trying to set FD_CLOEXEC on every fd is a lost cause, just use
closefrom() before exec.
2010-10-24 00:45:57 +00:00
Tiago Cunha
5fb4f8c1fa Helper script which greps for compat includes that shouldn't be present in all files but compat.h. 2010-10-24 00:42:04 +00:00
Tiago Cunha
5a0ecc5931 Sync OpenBSD patchset 774:
Fall back on normal session choice method if $TMUX exists but is invalid
rather than rejecting.
2010-10-24 00:32:35 +00:00
Tiago Cunha
e7a4b68f73 Sync OpenBSD patchset 773:
Use an explicit event rather than event_once for the main event so it
can be removed when the client becomes ready.
2010-10-24 00:31:57 +00:00
Tiago Cunha
a7e5092bd4 Sync OpenBSD patchset 772:
Treat the meta bit in the xterm extended modifier key set as the same as
escape (tmux's meta). From Emanuele Giaquinta.
2010-10-24 00:30:51 +00:00
Tiago Cunha
b73ac822fb Sync OpenBSD patchset 771:
Put "or" on new line from command with .Ic.
2010-10-24 00:29:57 +00:00
Nicholas Marriott
0ad532d9c2 Rewrite the screen vs tmux bit to be more accurate and complete and less
subjective.
2010-10-23 14:09:29 +00:00
Nicholas Marriott
b0ad6e94bb +ttyfast. 2010-10-18 19:01:07 +00:00
Tiago Cunha
b2ae7c6261 Sync OpenBSD patchset 770:
Set cause when failing due to linking a window to itself, from Martin
Pieuchot.
2010-10-09 14:31:50 +00:00
Tiago Cunha
6c9269baa7 Sync OpenBSD patchset 769:
Skip NULL entries in the sessions list when choosing the next session,
from Simon Olofsson.
2010-10-09 14:31:14 +00:00
Tiago Cunha
45784bd5d6 Sync OpenBSD patchset 767:
Nuke a leftover RB tree declaration spotted by blambert.
2010-10-09 14:30:26 +00:00
Tiago Cunha
b5349ab5d9 Sync OpenBSD patchset 766:
Two new options:

- server option "exit-unattached" makes the server exit when no clients
  are attached, even if sessions are present;

- session option "destroy-unattached" destroys a session once no clients
  are attached to it.

These are useful for preventing tmux remaining in the background where
it is undesirable and when using tmux as a login shell to keep a limit
on new sessions.
2010-10-09 14:29:32 +00:00
Tiago Cunha
7874b00d4c Sync OpenBSD patchset 765:
Modify the permissions on the socket when adding or removing +x to show
attached sessions, rather than replacing them.
2010-10-09 14:26:29 +00:00
Tiago Cunha
6139fac10d Sync OpenBSD patchset 764:
detach-on-destroy is a session option, not server.
2010-10-09 14:25:40 +00:00
Nicholas Marriott
d0d98d4ec0 done 2010-09-25 20:21:51 +00:00
Tiago Cunha
29f04400b5 Sync OpenBSD patchset 763:
Ugh. Pass the right type into tty_term_has. Teaches me to make last
minute changes :-/.
2010-09-18 15:45:03 +00:00
Tiago Cunha
5126037ea0 Sync OpenBSD patchset 762:
Use UTF-8 line drawing characters on UTF-8 terminals. Fixes some stupid
terminals (I'm looking at you, putty) which disable the vt100 ACS mode
switching sequences in UTF-8 mode.

Also on terminals without ACS at all, use ASCII equivalents where
obvious.
2010-09-18 15:43:53 +00:00
Tiago Cunha
d7a3fc3df4 Sync OpenBSD patchset 761:
Ignore terminal overrides settings without a value.
2010-09-18 15:41:50 +00:00
Tiago Cunha
59dc08a7a0 Sync OpenBSD patchset 760:
When resizing the copy mode screen, don't allow it to end up with the
viewable position beyond the size of the history.
2010-09-18 15:41:18 +00:00
Nicholas Marriott
fe3621cbc5 Update, from Daniel Thau. 2010-09-18 09:36:15 +00:00
Tiago Cunha
89c07dedd9 Sync OpenBSD patchset 759:
Add -n and -p flags to switch-client to move to the next and previous
session (yes, it doesn't match window/pane, but so what, nor does
switch-client).

Based on a diff long ago from "edsouza".
2010-09-10 13:36:17 +00:00
Tiago Cunha
28a0b6fd20 Sync OpenBSD patchset 758:
Do not crash if the screen size is too small for the indicator in copy mode.
2010-09-10 13:34:12 +00:00
Nicholas Marriott
f54482a461 Solaris 9 has no stdint.h, ugh. Reported by a couple of people most
recently Timothy Larson.
2010-09-07 19:32:58 +00:00
Tiago Cunha
afcc29a51d Sync OpenBSD patchset 757:
Simplify xterm modifier detection by treating as a bitmask + 1. Spotted
by and diff from Emanuele Giaquinta.
2010-09-07 13:21:18 +00:00
Tiago Cunha
33df467d40 Sync OpenBSD patchset 756:
Reset running jobs when the status line is enabled or disabled as well,
some people have it bound to a key.
2010-09-07 13:20:28 +00:00
Tiago Cunha
510b43569f Sync OpenBSD patchset 755:
Add missing prototype.
2010-09-07 13:19:53 +00:00
Nicholas Marriott
a8b22d3673 +. 2010-09-01 20:39:32 +00:00
Nicholas Marriott
19923625d4 +. 2010-09-01 20:37:20 +00:00
Nicholas Marriott
3b4d26d16b +. 2010-08-31 22:44:01 +00:00
Tiago Cunha
01052ca38e Sync OpenBSD patchset 754:
When destroying a pane, reset any mode (which reenables pane
bufferevent) before freeing the bufferevent.
2010-08-29 14:46:13 +00:00
Tiago Cunha
ee44a8dca9 Sync OpenBSD patchset 753:
Can't call event_del() without event_set() first - so call event_set()
when setting up the client.
2010-08-29 14:44:55 +00:00
Tiago Cunha
89acd757d0 Sync OpenBSD patchset 752:
MSG_EXIT can now have a return code in the message, so check for that
size as well. Stops the client fatal()ing on exit.
2010-08-29 14:43:45 +00:00
Tiago Cunha
56040be346 Sync OpenBSD patchset 751:
Do not call event_del() for signals after fork(), just use sigaction()
directly instead - calling libevent functions after fork() w/o
event_reinit() is a bad idea, even if in this case it was harmless.
2010-08-29 14:42:11 +00:00
Tiago Cunha
e6bb3d6942 Sync OpenBSD patchset 750:
Do not need to dup() the tty fd sent from the client because it is
already dup()d again later. Fixes a leak seen by espie@.
2010-08-29 14:39:45 +00:00
Nicholas Marriott
aba555509e +-. 2010-08-19 18:04:56 +00:00
Tiago Cunha
c50c4ec834 Sync OpenBSD patchset 749:
Do not allow duplicate session names to be created, reported by Dominik
Honnef, patch from Thomas Adam.
2010-08-11 22:19:03 +00:00
Tiago Cunha
9858071dd0 Sync OpenBSD patchset 748:
Handle failure to change mode, to avoid dying when switching into copy
mode when already in a different mode. Reported by "Florian".
2010-08-11 22:18:28 +00:00
Tiago Cunha
b0169d9b84 Sync OpenBSD patchset 747:
Usage string fixes from Ben Boeckel.
2010-08-11 22:17:32 +00:00
Tiago Cunha
e34c6e2305 Sync OpenBSD patchset 746:
Treat trying to link or move to the same window as an error to avoid
removing it accidentally.
2010-08-11 22:16:43 +00:00
Tiago Cunha
761bd3c9e3 Sync OpenBSD patchset 745:
Change the way backoff works. Instead of stopping reading from the pty
when the client tty backs up too much, just stop updating the tty and
only update the internal screen. Then when the tty recovers, force a
redraw.

This prevents a dodgy client from causing other clients to go into
backoff while still allowing tmux to be responsive (locally) when seeing
lots of output.
2010-08-11 22:16:04 +00:00
Tiago Cunha
5e9429e2d6 Sync OpenBSD patchset 744:
Show which pane is active in the list-panes output, suggested by Dominik
Honnef.
2010-08-11 22:14:23 +00:00
Tiago Cunha
4387db506f Sync OpenBSD patchset 742:
dup() the stdin fd so it isn't closed twice (once for stdin, once for tty).
2010-08-09 21:45:37 +00:00
Tiago Cunha
d7bae0edce Sync OpenBSD patchset 741:
When changing so that the client passes its stdout and stderr as well as
stdin up to the server, I forgot one essential point - the tmux server
could now be both the producer and consumer. This happens when tmux is
run inside tmux, as well as when piping tmux commands together.

So, using stdio(3) was a bad idea - if sufficient data was written, this
could block in write(2). When that happened and the server was both
producer and consumer, it deadlocks.

Change to use libevent bufferevents for the client stdin, stdout and
stderr instead. This is trivial enough for output but requires a
callback mechanism to trigger when stdin is finished.

This relies on the underlying polling mechanism for libevent to work
with whatever devices to which the user could redirect stdin, stdout or
stderr, hence the change to use poll(2) over kqueue(2) for tmux.
2010-08-09 21:44:25 +00:00
Nicholas Marriott
482bd7b65e Basic GNU bash completion from Frank Barknecht. 2010-08-09 18:22:33 +00:00
Nicholas Marriott
f42364b4b5 How to blank on lock, from Thomas Adam, slightly tweaked by me. 2010-07-31 11:46:28 +00:00
Nicholas Marriott
5be8175b0b No more up-pane/down-pane. 2010-07-31 11:39:13 +00:00
Tiago Cunha
5576fe42b2 Sync with reality, per SF bug #3035214. 2010-07-27 18:29:07 +00:00
Micah Cowan
1944747759 Don't enable/disable invalid event pointers. Fixes SF #3033119. 2010-07-22 19:51:48 +00:00
Tiago Cunha
28c4c86589 Sync OpenBSD patchset 738:
Don't return if in the current window since we may want to report a bell
(if bell-action any/current), just clear the flag so the status line
doesn't show the bell.
2010-07-20 17:36:41 +00:00
Tiago Cunha
7ed9b0f8fb Sync OpenBSD patchset 737:
Send the \n to stdout with the message, not stderr... doh.
2010-07-20 17:36:03 +00:00
Nicholas Marriott
11497af4dd Solaris has MAXHOSTNAMELEN in netdb.h. 2010-07-19 18:31:42 +00:00
Tiago Cunha
b0878774e0 Don't hard-code the username. 2010-07-19 13:57:22 +00:00
Tiago Cunha
e71f0842ce Working on 1.4. 2010-07-18 14:53:27 +00:00
Tiago Cunha
9b47a48393 Changes for 1.3. 2010-07-18 13:40:59 +00:00
Tiago Cunha
0482983d53 Done. 2010-07-18 13:39:02 +00:00
Tiago Cunha
2b512dc49d Bump VERSION, and comment FDEBUG. 2010-07-18 13:36:52 +00:00
Tiago Cunha
ae45c2ea45 Sync OpenBSD patchset 736:
some escapes i missed;
2010-07-17 14:39:01 +00:00
Tiago Cunha
11f81e8134 Sync OpenBSD patchset 735:
Make pane/window wrapping more logical (so with 10 windows, +10 from
window 5 stays in the same place), and tidy the code. From Tiago Cunha.
2010-07-17 14:38:13 +00:00
Tiago Cunha
ad6a528f61 Sync OpenBSD patchset 734:
Return the command client return code with MSG_EXIT now that MSG_ERROR and
MSG_PRINT are unused.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Moving the server stuff over to bufferevents and timers and so on will come
later.
2009-11-08 22:40:36 +00:00
Tiago Cunha
5ce49941fb Working on 1.2. 2009-11-05 13:18:19 +00:00
Tiago Cunha
09c34be825 Use %%VERSION%% so the Makefile can replace it by VERSION. 2009-11-05 13:13:19 +00:00
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
Nicholas Marriott
b8bd24817f If using the default login shell (empty default-command), strip any - prefix. 2009-07-02 18:26:55 +00:00
Nicholas Marriott
08c7249636 Change default_window_name to use window_default_command if the actual cmd is
empty. From Josh Elsasser.
2009-07-02 18:17:46 +00:00
Nicholas Marriott
29ac832cb3 Fix two copy/paste bugs: forbid zero-length buffers to prevent a fatal error
when trying to paste them, found by me, and miscalculation of the start/end
causing random fatal errors when copying in copy-mode, reported by sthen.
2009-07-02 16:23:54 +00:00
Tiago Cunha
85dac1e378 Update. 2009-07-02 13:50:27 +00:00
Nicholas Marriott
1f1623e04d Solaris has no strcasestr. 2009-07-02 07:31:02 +00:00
Nicholas Marriott
3c0500f282 Don't see a reason for sys/cdefs.h here; remove it. 2009-07-01 23:22:46 +00:00
Nicholas Marriott
9f0653386b $Id$. 2009-07-01 23:06:32 +00:00
Nicholas Marriott
ec818b8791 Move defines after includes to avoid multiple definition. 2009-07-01 22:46:13 +00:00
Nicholas Marriott
81f06ba170 Typo: bsdpoll.h -> bsd-poll.h. 2009-07-01 22:43:48 +00:00
Nicholas Marriott
851a35eb5e Change >| to rm/> as apparently Solaris /bin/sh doesn't like it. 2009-07-01 22:28:56 +00:00
Nicholas Marriott
8f2950f4ee Try to make a bit more sense here. 2009-07-01 22:15:16 +00:00
Nicholas Marriott
e0a6376690 Comment FDEBUG and bump dist version. 2009-07-01 22:10:06 +00:00
Nicholas Marriott
1903756171 Changes for 0.9. 2009-07-01 22:08:33 +00:00
Nicholas Marriott
81010f52db Update with new UTF-8 environment variable information for 0.9. 2009-07-01 19:49:56 +00:00
Nicholas Marriott
22d1b9412e Using -l to specify a login shell is non-POSIX and causes problems with shells
that do not support it. Instead, set an empty default-command to invoke $SHELL
with - prefixed to argv[0], and make this the default setting.
2009-07-01 19:42:55 +00:00
Nicholas Marriott
d50810267e This file is not going to be used as much any longer, make a note. 2009-07-01 19:33:53 +00:00
Nicholas Marriott
82b070ddfa Update ready for 0.9 2009-07-01 19:33:11 +00:00
Nicholas Marriott
55f8219d3c 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-01 19:15:12 +00:00
Nicholas Marriott
35092835b0 Fix two errors with character/line insertion and deletion: the maximum number
of characters which may be inserted or deleted is the screen width, not one
less (and similarly for lines and height); and if characters or lines are
deleted by moving the ones that follow, the space at the end needs to be
cleared.

This appears to solve long-standing redraw issues most visible when using the
force-width option then scrolling in view(1) or unwrapping lines in emacs.
2009-07-01 19:14:33 +00:00
Nicholas Marriott
8fe3f1dcb2 $Id$. 2009-07-01 19:03:34 +00:00
Nicholas Marriott
eed4f7600d Fix $Id$. 2009-06-29 22:04:51 +00:00
Nicholas Marriott
503c6a3377 Don't try to page up with scroll-mode -u or copy-mode -u unless the mode was
successfully changed - if already in a different mode, it would corrupt the
mode data.
2009-06-29 22:04:07 +00:00
Nicholas Marriott
18ebc99906 Use gmtime_r so the current time isn't overwritten, the minute comparison works
and the clock is actually updated. It was already used for lock-server but not
here.
2009-06-29 22:03:36 +00:00
Nicholas Marriott
edc2e7da98 Copy the 256-colour flag into the tty saved cell as well as the actual colour,
otherwise colour 8 isn't reset.
2009-06-29 22:03:09 +00:00
Nicholas Marriott
796b2e3ec9 Add missing spaces before some alias closing brackets, otherwise they are
shown in the wrong style.
2009-06-29 22:02:20 +00:00
Nicholas Marriott
1fb3948ff1 Whoops, revert. 2009-06-26 22:18:36 +00:00
Nicholas Marriott
1496aa5dbc Remove some unused function declarations; no binary change. 2009-06-26 22:18:03 +00:00
Nicholas Marriott
6ce734cec0 After logging (if enabled) is switched to file, there is no reason to keep
stdin/stdout/stderr active, so dup them to /dev/null.
2009-06-26 22:13:57 +00:00
Nicholas Marriott
826add53f1 Set LC_ALL=C to stop i18n breaking gcc test. 2009-06-26 16:01:12 +00:00
Nicholas Marriott
1aaf47e698 Apparently NetBSD's tcgetpgrp is good enough to use, so don't need to play
complicated games, from Roy Marples.
2009-06-26 15:54:52 +00:00
Nicholas Marriott
de2ea2d178 Status line fixes: don't truncate status-right now the length calculation is
done for UTF-8, limit to the maximum length correctly when printing, and always
print a space even if the left string is longer than the width available.
2009-06-26 15:34:12 +00:00
no_author
3fcbe1e27b Remove some dead assignments, found by sthen with clang. 2009-06-26 15:32:00 +00:00
Nicholas Marriott
81b4aca934 #ifndef nitems. 2009-06-26 15:31:15 +00:00
Nicholas Marriott
63753735ec Update TODO. 2009-06-25 21:25:36 +00:00
Nicholas Marriott
32312e0252 vis compat stuff. 2009-06-25 20:27:32 +00:00
Nicholas Marriott
802e129fd7 Start of portability update: bitstring.h. 2009-06-25 17:02:59 +00:00
Nicholas Marriott
f1463ff3c1 Lose -V. 2009-06-25 16:56:08 +00:00
Nicholas Marriott
0af7fa08d2 Skip 8 line diffs ($Id$ change only). 2009-06-25 16:54:21 +00:00
Nicholas Marriott
20002ec6cd Comparison script. 2009-06-25 16:49:22 +00:00
Nicholas Marriott
8fc34ca044 libgen.h. 2009-06-25 16:49:02 +00:00
Nicholas Marriott
a9e3d5c56a More diff-to-OpenBSD reduction. Move a lot of compat stuff into compat.h. 2009-06-25 16:47:00 +00:00
Nicholas Marriott
bb459beb03 Whitespace and more syncing. 2009-06-25 16:34:50 +00:00
Nicholas Marriott
8df98d1f5b Don't need linker magic anymore. 2009-06-25 16:25:55 +00:00
Nicholas Marriott
6cde05147e No more xmalloc-debug. 2009-06-25 16:25:15 +00:00
Nicholas Marriott
8565ae234b Fix rejects. 2009-06-25 16:23:35 +00:00
Nicholas Marriott
3eb1bfddd4 Sync this properly. 2009-06-25 16:22:36 +00:00
Nicholas Marriott
a5830b9603 Restore $Id$ and add script to do so. 2009-06-25 16:21:32 +00:00
Nicholas Marriott
f17a5f1e82 If getcwd() fails, use the user's home directory, or /, instead of failing with
an error.
2009-06-25 16:11:12 +00:00
Nicholas Marriott
bfa46e8f91 lines variable can be -1 (to be ignored), so should be signed. Found by lint. 2009-06-25 16:10:18 +00:00
Nicholas Marriott
f0bcbcfa7f Remove error about using -L and -S together which was never displayed as
logging wasn't yet enabled, was unnecessary, and contradicted the man page
which says using -S will cause -L to be ignored.
2009-06-25 16:09:38 +00:00
Nicholas Marriott
1b9ac18565 tmux doesn't and won't need syslog logging, so remove it and some other unused
functions found by lint.
2009-06-25 16:09:25 +00:00
Nicholas Marriott
582660bdf3 Miscellaneous unused functions, including one which was basically a
duplicate. Found by lint.
2009-06-25 16:09:11 +00:00
Nicholas Marriott
62822b1848 Nuke unused buffer functions. Found by lint.
Also remove some old debug output which was #if 0.
2009-06-25 16:07:00 +00:00
Nicholas Marriott
abb5e36199 Unused prototypes. Found by lint, no binary change. 2009-06-25 16:06:09 +00:00
Nicholas Marriott
947fabc751 Unused variables. Found by lint, no binary change. 2009-06-25 16:05:39 +00:00
Nicholas Marriott
a03ae97fbf Now that a UTF-8-capable puts function exists, use it for printing strings in
choice/more modes - lines with UTF-8 now display properly in find-window
results.
2009-06-25 16:05:00 +00:00
Nicholas Marriott
3ec8efc803 Fix a type mismatch warning in assignment. 2009-06-25 16:04:43 +00:00
Nicholas Marriott
f7a9eb46fc Change find-window and monitor-content to use fnmatch(3). For convenience and
compatibility, *s are implicitly added at the start and end of the pattern.
2009-06-25 16:04:24 +00:00
Nicholas Marriott
853ad68162 Add a dedicated function to convert a line into a string and use it to simplify the search window function. 2009-06-25 16:02:37 +00:00
Nicholas Marriott
e6e1b45fa1 Change to match xterm's resizing behaviour, including pushing lines into the
history from the top when reducing vertical size and pulling them again when
increasing size.
2009-06-25 16:02:10 +00:00
Nicholas Marriott
944520b3a8 Make remain-on-exit work again when there is only one pane left, which was
broken sometime during the pane/layout changes. Reported/tested by Iain Morgan,
thanks.
2009-06-25 16:01:42 +00:00
Nicholas Marriott
942ea4267d Trying to predict the cursor position for UTF-8 output in the same way as for
normal eight-bit output is wrong, separate it into a different function. Fixes
spacing when mixing UTF-8 with some escape sequences, notably the way w3m does
it.
2009-06-25 16:01:26 +00:00
Nicholas Marriott
245685433e Constify utf8_width() function argument. 2009-06-25 16:00:50 +00:00
Nicholas Marriott
7eff7f7629 If a pane is "zombified" (remain-on-exit flag), don't continue to queue key and
mouse input for it (otherwise they are processed after respawn).
2009-06-25 16:00:25 +00:00
Nicholas Marriott
cd5a4f4c35 LC_ALL overrides LC_CTYPE and LANG. Comment was correct but the code
wrong. Pointed out by Hannah Schroeter, thanks.
2009-06-25 16:00:02 +00:00
Nicholas Marriott
7be69bfa03 Terminate cwd buffer before running xstrdup on it. 2009-06-25 15:59:42 +00:00
Nicholas Marriott
6f4600c533 Check the first of LC_CTYPE, LC_ALL and LANG, rather than just the last, when
trying to decide about UTF-8, and use strcasestr. Reported by Geert Hendrickx.
2009-06-25 15:59:27 +00:00
Nicholas Marriott
fbcee9f114 strdup the input to putenv to avoid in one case passing a string that is later
freed and in the other const strings.
2009-06-25 15:58:58 +00:00
Nicholas Marriott
0e95769b43 Call setproctitle earlier in the client, and include the socket name. Makes it
easier to match client to server in ps/pgrep when using several servers.
2009-06-25 15:58:33 +00:00
Nicholas Marriott
b9155e835a Print a better message than '(null)' if no command is specified ("tmux \;"). 2009-06-25 15:56:39 +00:00
Nicholas Marriott
f90450f854 Zero the password given to -U in the client as well. 2009-06-25 15:56:25 +00:00
Nicholas Marriott
418128bebc If the prompt is hidden or a password is sent with -U, zero it before freeing
it.
2009-06-25 15:55:34 +00:00
Nicholas Marriott
63b38ef628 Implement the CBT (backward tab) sequence (\033[Z). 2009-06-25 15:54:57 +00:00
Nicholas Marriott
1b245388b5 Proper support for tab stops (\033H etc), using a bitstring(3). Makes another
vttest test happy.
2009-06-25 15:54:38 +00:00
Nicholas Marriott
cd71a13a14 Okay, so I screwed up when testing this, doh. Unbreak so that CAN/SUB actually
do cancel the sequence, and tweak to make the code more clear.
2009-06-25 15:54:03 +00:00
Nicholas Marriott
4eed190649 Oops, CAN and SUB should abort the sequence (return to first state), not remain
in the same state.
2009-06-25 15:53:44 +00:00
Nicholas Marriott
c3c14817c9 More input compatibility love. Support C0 within escape sequences, and the C0
control character VT (vertical tab, \013), which is treated as LF like
VT102. Makes another vttest happy.
2009-06-25 15:52:59 +00:00
Nicholas Marriott
b8ec0c713f Support insert mode by using insert character to shift the cells before writing
as normal.
2009-06-25 15:52:12 +00:00
Nicholas Marriott
93631b3ca7 Implement the DEC alignment test. With the last change this is enough for the
first cursor test in vttest (in ports) to pass; it still shops a few more
problems though.
2009-06-25 15:51:54 +00:00
Nicholas Marriott
49477de55c Fix some miscalculations when clearing to start of screen: the number of lines
to the cursor is cy not cy - 1, and the current cursor cell should be included.
2009-06-25 15:50:48 +00:00
Nicholas Marriott
dff949747c Use vis(3) instead of handrolled function. 2009-06-25 15:50:03 +00:00
Nicholas Marriott
7597cb6834 Pass window titles through vis(1). <0x20 is dropped anyway by the input state
machine but top-bit-set nonprintables could cause trouble, and they are neater
like this anyway.
2009-06-25 15:49:27 +00:00
Nicholas Marriott
4f2e5f8c50 Do not set the window title by default (make set-titles option default to off),
wiping over the title is rude and annoying.
2009-06-25 15:48:59 +00:00
Nicholas Marriott
28bcf774e5 New session option, status-utf8, to control the interpretation of top-bit-set
characters in status-left and status-right (if on, they are treated as UTF-8;
otherwise passed through).
2009-06-25 15:48:25 +00:00
Nicholas Marriott
1e06ec41dc Add a UTF-8 aware string length function and make UTF-8 in
status-left/status-right work properly. At the moment any top-bit-set
characters are assumed to be UTF-8: a status-utf8 option to configure this will
come shortly.
2009-06-25 15:47:07 +00:00
Nicholas Marriott
0828e06ad7 Nuke unused pane flag. 2009-06-25 15:46:09 +00:00
Nicholas Marriott
d3d4bacd82 Cast char to u_char before passing to isalnum(). By ray 2009-06-25 15:45:24 +00:00
Nicholas Marriott
94f5ddb60c remove unused flag; while here, make usage's output fit on 80-column displays. 2009-06-25 15:44:44 +00:00
Nicholas Marriott
658659532a Use login shells by default. 2009-06-25 15:44:03 +00:00
Nicholas Marriott
6528d47ed8 Don't leak memory if multiple -f flags are given. From ray 2009-06-25 15:42:35 +00:00
Nicholas Marriott
5b3db7b56c Sync man page with OpenBSD. 2009-06-25 15:30:29 +00:00
Nicholas Marriott
3d7cf00359 Add missing -a flag. 2009-06-25 15:29:34 +00:00
Nicholas Marriott
e2a0c5ad7a When swapping pane positions, swap the PANE_HIDDEN flag as well, otherwise tmux
crashes when trying to find the new active pane.

While here, nuke an unused pane flag.

Fixes PR 6160, reported by and a slightly different version of diff tested by
ralf.horstmann at gmx.de.
2009-06-25 15:28:08 +00:00
Nicholas Marriott
32398b98a8 Sync to OpenBSD: fixes from ray@. 2009-06-25 15:25:45 +00:00
Nicholas Marriott
0fdd47660a UTF-8 detection is broken on sparc64; disable until I get time to test it further. 2009-06-24 17:31:03 +00:00
Nicholas Marriott
6208128fa2 Sync with private copy. 2009-06-03 17:52:29 +00:00
Nicholas Marriott
940e2ae1fd endpwent() is not required after getpwuid(). 2009-06-01 20:38:59 +00:00
Nicholas Marriott
144aed48fa +. 2009-05-29 23:26:11 +00:00
Nicholas Marriott
f63f5e6489 Clear status line on incorrect password. 2009-05-29 23:25:26 +00:00
Nicholas Marriott
17a6c01d58 Don't show real character under cursor when hidden. Doh. 2009-05-29 05:40:56 +00:00
Nicholas Marriott
8536ad0ce7 Reset activity time to avoid relock on -U. 2009-05-28 16:24:02 +00:00
Nicholas Marriott
3a55871d04 Now in base. 2009-05-26 18:31:10 +00:00
Nicholas Marriott
cd4566cd69 Spacing. 2009-05-26 18:30:51 +00:00
Nicholas Marriott
133539a2d4 Update. 2009-05-21 19:51:33 +00:00
Nicholas Marriott
89404788c9 Spacing. 2009-05-21 19:47:57 +00:00
Nicholas Marriott
6c442c19ba UPPER -> BIG, sort, and bump protocol version. 2009-05-21 19:46:00 +00:00
Nicholas Marriott
a8ec5f1d09 stat(2) files before trying to load them to avoid problems, for example with "source-file /dev/zero".
This commit dedicated to Tom: protecting idiots from their own stupidity for more than 20 years.
2009-05-21 19:38:51 +00:00
Nicholas Marriott
eb6007102e new layout plan 2009-05-20 15:46:48 +00:00
Nicholas Marriott
cdce5f739d Indentation. 2009-05-19 16:29:35 +00:00
Nicholas Marriott
5707eb3256 +. 2009-05-19 16:12:40 +00:00
Nicholas Marriott
6db7bd6791 Try to guess if the window is UTF-8 by outputting a three-byte UTF-8 wide character and seeing how much the cursor moves. Currently tries to figure out if this works by some stupid checks on the terminal, these need to be rethought. Also might be better using a width 1 character rather than width 2. 2009-05-19 16:08:35 +00:00
Nicholas Marriott
5db59a0d20 If LANG contains "UTF-8", assume the terminal supports UTF-8, on the grounds that anyone who configures it probably wants UTF-8. Not certain if this is a perfect idea but let's see if it causes any problems. 2009-05-19 16:03:18 +00:00
Tiago Cunha
80af85a102 - New window option monitor-content to search for a string in a window, and
highlight the status line if it matches.
- To make this possible, the function cmd_find_window_search from
  cmd-find-window.c had to be moved to window.c and renamed window_pane_search.
- While there use three new functions in server.c to check for bell, activity,
  and content, to avoid too much nesting.
2009-05-19 13:32:55 +00:00
Nicholas Marriott
a385f75792 Note. 2009-05-19 08:50:10 +00:00
Nicholas Marriott
0abd8ea84f (void). 2009-05-19 08:48:49 +00:00
Nicholas Marriott
72e464fa04 main-horizontal layout and main-pane-height option to match vertical. 2009-05-18 22:17:24 +00:00
Nicholas Marriott
c21ffbc772 left-vertical -> main-vertical.
Also update CHANGES/TODO.
2009-05-18 21:58:40 +00:00
Nicholas Marriott
6e4b947d71 New option main-pane-width to set width of pane in left-vertical mode. 2009-05-18 21:55:53 +00:00
Nicholas Marriott
3ee4b334e7 manual -> manual-vertical. 2009-05-18 21:32:36 +00:00
Nicholas Marriott
404411f5e7 horizontal -> h, vertical -> v, to shorten some function names a little. 2009-05-18 21:29:11 +00:00
Nicholas Marriott
d601c42ea2 Behave properly when resize not supported. 2009-05-18 21:16:09 +00:00
Nicholas Marriott
b233616853 Update TODO. 2009-05-18 21:08:11 +00:00
Nicholas Marriott
5518b6138d manual -> manual-vertical. 2009-05-18 21:06:16 +00:00
Nicholas Marriott
ab4e5e8574 Clean up manual layout code:
- change the one layout function into two _refresh and _resize
- create layout-manual.c for manual layout code
- move the fit panes/update panes code from window.c to the new file as it is only used by manual layout now
- move the resize pane code into layout-manual.c as well
- get rid of the direct calls to fit/update and make them go through layout
- rename a couple of variables

This is mainly as a first step before reworking the manual layout code to see if anything breaks.
2009-05-18 21:01:38 +00:00
Nicholas Marriott
b6b00c53bd Fix comment. 2009-05-18 20:18:08 +00:00
Nicholas Marriott
2f5c3d881d #undef everything in config.h. This is the only bit of the scripting work I am
using now :-).
2009-05-18 19:18:41 +00:00
Nicholas Marriott
a03cf0e183 +b on fopen. 2009-05-18 16:22:30 +00:00
Nicholas Marriott
d2275f4abf chmod +x configure 2009-05-18 15:42:30 +00:00
Nicholas Marriott
0c33b73db0 Move some crap into the attic, and some other stuff into tools/. 2009-05-17 18:27:18 +00:00
Nicholas Marriott
8dc73f2df5 Move website stuff into its own directory. 2009-05-17 18:20:59 +00:00
Nicholas Marriott
6805217783 Move dist.mk to tools/. 2009-05-17 18:15:41 +00:00
Nicholas Marriott
0f5168f971 Use >|. 2009-05-16 22:14:47 +00:00
Nicholas Marriott
c111310600 Use a better variable name and allow the uname to be overridden. 2009-05-16 22:06:01 +00:00
Nicholas Marriott
d58bfe5f0a clean-all. 2009-05-16 21:56:38 +00:00
Nicholas Marriott
095f16d64f clean-all target to clean configure stuff too. 2009-05-16 21:55:54 +00:00
Nicholas Marriott
25911d32e1 Use empty(), FreeBSD doesn't like ==. 2009-05-16 18:59:50 +00:00
Nicholas Marriott
1001902143 select-layout command and some key bindings. 2009-05-16 11:48:47 +00:00
Nicholas Marriott
03af7c99b5 Recreate server socket on SIGUSR1, per SF feature request 2792533. 2009-05-16 10:02:51 +00:00
Nicholas Marriott
92de1ad6c8 putenv can be char *. 2009-05-15 12:58:56 +00:00
Nicholas Marriott
0b54a2d723 Don't use -Wcast-qual and use explicit casts to shut gcc up in the few cases we can't avoid using a char *. 2009-05-15 12:57:36 +00:00
Nicholas Marriott
8913d853e4 +sfw for solaris too. 2009-05-14 19:49:26 +00:00
Nicholas Marriott
cba338ac13 Keys in status line (p in vi mode, M-y in emacs) to paste the first line of the upper paste buffer. Suggested by Dan Colish. 2009-05-14 19:36:56 +00:00
Nicholas Marriott
8931f0018a Separate tmux target. Doh. 2009-05-14 19:32:37 +00:00
Nicholas Marriott
b476fab34d PuTTY resizing from merdely. 2009-05-14 18:43:02 +00:00
Nicholas Marriott
96ca072482 clear-history command. 2009-05-14 16:56:23 +00:00
Nicholas Marriott
cc59ee4e6a This is okay. 2009-05-14 16:31:35 +00:00
Nicholas Marriott
dd2f8d7d74 Don't force wrapping with \n when asked, let the cursor code figure it out. Should fix terminals which use this to detect line breaks. 2009-05-14 16:21:55 +00:00
Nicholas Marriott
4b64bd7b01 It is HAVE_PTY_H, also add a cast to shut gcc up. 2009-05-14 07:58:38 +00:00
Nicholas Marriott
c495337e76 HAVE_. 2009-05-14 07:51:51 +00:00
Nicholas Marriott
cae92a2041 Needs a VERSION. 2009-05-14 07:51:25 +00:00
Nicholas Marriott
5adb342147 SunOS tweaks. 2009-05-14 07:49:23 +00:00
Nicholas Marriott
3b0bd5a3e6 +. 2009-05-14 07:49:15 +00:00
Nicholas Marriott
6099a3399e Add distribution stuff back in. 2009-05-14 07:48:42 +00:00
Nicholas Marriott
1a86934e09 NetBSD has no strtonum so needs compat/. 2009-05-14 00:40:58 +00:00
Nicholas Marriott
626fe978e1 NetBSD tree.h has no RB_PREV. 2009-05-14 00:35:53 +00:00
Nicholas Marriott
99dee98a2b Use a variable for uname. 2009-05-14 00:34:25 +00:00
Nicholas Marriott
db7357fdcc print is redundant. Doh. 2009-05-14 00:31:48 +00:00
Nicholas Marriott
5436f6be19 Sprinkle the magic anti-GCC-suckage for *BSD as well. 2009-05-14 00:28:04 +00:00
Nicholas Marriott
1b70993207 Move -lutil. 2009-05-14 00:17:37 +00:00
Nicholas Marriott
a8fe667267 Use the right osdep. 2009-05-14 00:12:42 +00:00
Nicholas Marriott
9ff8c354ab install depends on all. 2009-05-14 00:09:02 +00:00
Nicholas Marriott
de79ce38a5 Try to figure out if we are using gcc 4 and get rid of the stupid warning, while not breaking 3.x and 2.x... 2009-05-14 00:06:59 +00:00
Nicholas Marriott
6c27e434c6 compat/bsd-poll.h now we are not doing -Icompat. 2009-05-13 23:50:42 +00:00
Nicholas Marriott
41fb824cbe Sort. 2009-05-13 23:45:26 +00:00
Nicholas Marriott
ab5273d9a9 Don't bother with this. 2009-05-13 23:43:27 +00:00
Nicholas Marriott
488a67e5a3 Whoops, don't use the name of the rule here now. 2009-05-13 23:41:58 +00:00
Nicholas Marriott
df9a2886dd Add a changes entry. 2009-05-13 23:40:30 +00:00
Nicholas Marriott
4337a9b2d5 Two more to ignore. 2009-05-13 23:34:33 +00:00
Nicholas Marriott
78f6b511fd $(PROG) is gorn. 2009-05-13 23:33:54 +00:00
Nicholas Marriott
522bf77cf4 cmake build files. I wrote these but then decided to keep the cleanup
(getopt/HAVE_*) changes but add a manual configure script and clean up the
makefiles instead. Can always be resurrected if necessary.
2009-05-13 23:32:21 +00:00
Nicholas Marriott
f1bd3807ae Everything supported has working vsnprintf. 2009-05-13 23:29:45 +00:00
Nicholas Marriott
c8cf438d44 Rename all feature flags to HAVE_* and move out of makefiles into a configure
script which must be run before building.

Still two makefiles but they are a hell of a lot simpler.

HAVE_* also will make it easier to move to $buildsystem if necessary later.
2009-05-13 23:27:00 +00:00
Nicholas Marriott
e1b4a37722 Bye-bye nonworking IRIX, can be rescued from the attic if ever needed again. 2009-05-13 22:26:11 +00:00
Nicholas Marriott
792aeb926e Use getopt.c from openssh rather than OpenBSD's getopt_long. 2009-05-13 22:20:48 +00:00
Nicholas Marriott
88daeb5410 Bye-bye META. 2009-05-13 22:10:39 +00:00
Nicholas Marriott
83d984eca8 Works fine, escaping was the issue. 2009-05-11 19:03:30 +00:00
Nicholas Marriott
b21e356e56 Spacing. 2009-05-04 19:12:37 +00:00
Nicholas Marriott
525bd431b2 RB_INSERT returns &item if already exists, so use that rather than doing a
check beforehand.
2009-05-04 18:05:23 +00:00
Nicholas Marriott
143aa718e5 Space trimmage mega-diff. 2009-05-04 17:58:27 +00:00
Nicholas Marriott
59a5728527 This should be fixed by previous commit. 2009-05-04 17:53:06 +00:00
Nicholas Marriott
54a5f82588 Region can reset cursor to 0,0 - bad if there is an offset. So sort out region before cursor. 2009-05-04 17:52:14 +00:00
Nicholas Marriott
fb543c7707 Use ACS for line drawing characters. 2009-05-04 13:20:02 +00:00
Nicholas Marriott
9164dd63e7 Only worry about complete seconds for status line update. Also reduce poll interval and de-magic-number it. 2009-05-02 08:34:39 +00:00
Nicholas Marriott
827fac4c0b Support "neww; neww" as well "neww ; neww". 2009-04-30 21:53:32 +00:00
Nicholas Marriott
044e6f7660 previous-layout command. 2009-04-30 21:17:06 +00:00
Nicholas Marriott
a6f2d82335 Use a (pre)randomised binary tree for UTF-8 character widths. Probably overkill
but meh.
2009-04-30 20:54:53 +00:00
Nicholas Marriott
4a74349ff5 static const. 2009-04-30 18:39:34 +00:00
Nicholas Marriott
a583bbb730 Display the layout name in window lists. 2009-04-30 16:27:29 +00:00
Nicholas Marriott
631f81f519 DOH. 2009-04-30 16:24:20 +00:00
Nicholas Marriott
5732d666a1 Indentation. 2009-04-30 06:04:26 +00:00
Nicholas Marriott
eccaaeee6e cvs add is often a good move. 2009-04-30 06:01:35 +00:00
Nicholas Marriott
cdf472f2de Merge resize-pane-{up,down} into resize-pane. 2009-04-30 06:01:24 +00:00
Nicholas Marriott
a3f7928084 Oops, revert - need u_char. 2009-04-30 06:00:13 +00:00
Nicholas Marriott
38a33addf7 Don't need cp. 2009-04-30 05:42:46 +00:00
Nicholas Marriott
71a903d4be This should be fixed now. 2009-04-29 23:11:02 +00:00
Nicholas Marriott
91241f1457 Apply the make magic wand to pick an osdep-*.c file rather than using ifdefs. 2009-04-29 23:07:35 +00:00
Nicholas Marriott
ce989a91d1 /* $Id$ */ 2009-04-29 22:45:32 +00:00
Nicholas Marriott
8aa72ac803 tmux doesn't care about setres[ug]id. 2009-04-29 22:42:02 +00:00
Nicholas Marriott
2b967aa1d2 getopt_long.c not getopt.c 2009-04-29 22:40:52 +00:00
Nicholas Marriott
74dfb503a8 Solaris doesn't have TAILQ_REPLACE yet :-(. 2009-04-29 22:35:45 +00:00
Nicholas Marriott
3085ca7153 Don't need all this %p stuff anymore really. 2009-04-29 22:29:20 +00:00
Nicholas Marriott
cc9cc1aea8 Some tweaks for Solaris.
Get rid of vis.* in favour of a small replacement function.
2009-04-29 22:25:20 +00:00
Nicholas Marriott
323b7cbfbe Ignore tmux*.out as well. 2009-04-29 21:46:56 +00:00
Nicholas Marriott
f0a716f484 Use a u_char so top-bit-set update the cursor as well. 2009-04-29 17:50:52 +00:00
Nicholas Marriott
cd214f8f6a + item. 2009-04-29 17:07:18 +00:00
Nicholas Marriott
7c5f1af26f Ignore del too. 2009-04-29 17:06:45 +00:00
Tiago Cunha
53dc88e276 Simplify the code by using the generic _target functions. 2009-04-28 18:29:44 +00:00
Nicholas Marriott
6b148c8dce No TAILQ_REPLACE on NetBSD. 2009-04-27 18:10:10 +00:00
Nicholas Marriott
6317046bd1 Use cmd_prarg to include "s when necessary. 2009-04-27 17:28:30 +00:00
Nicholas Marriott
5d1b6888dc Convert hidden flag to a full flags word for the status line and add a flag to
accept after only one key. Use this so don't need to press enter after y/n for
confirm-before.
2009-04-27 17:27:36 +00:00
Nicholas Marriott
1f2d9e64bb +=. 2009-04-27 16:55:29 +00:00
Nicholas Marriott
d8a35ffa50 Perform some black and midnight cpp witchcraft to get rid of GRID_DEBUG, to fix
building with -DDEBUG on gcc2 platforms. From joshe.
2009-04-27 14:51:59 +00:00
Nicholas Marriott
850965584e Missing Ar. 2009-04-27 14:50:22 +00:00
Tiago Cunha
ddf2efe57b Update commands, and options. 2009-04-27 14:44:14 +00:00
Tiago Cunha
e397e3a5f8 - Add alias to the break-pane command.
- s/Asks/Ask/ in the confirm-before command for consistency's sake.
2009-04-27 14:40:45 +00:00
Tiago Cunha
c80ad456cc Avoid using the prompt history when the server is locked, and prevent any
input entered from being added to the client's prompt history. From nicm.
2009-04-27 13:56:51 +00:00
Tiago Cunha
058772e4e6 - confirm-before command.
- Bound "&" and "x" by default to confirm-before "kill-window" and
  confirm-before "kill-pane", respectively.
2009-04-27 13:21:16 +00:00
Nicholas Marriott
7d6896ae79 Support NEL. 2009-04-23 21:28:45 +00:00
Nicholas Marriott
5fbdca890a Use the xenl terminfo flag to detect early-wrap terminals like the FreeBSD
console. Many thanks for a very informative email from Christian Weisgerber.
2009-04-23 21:09:17 +00:00
Nicholas Marriott
a91ecf44fa Note it. 2009-04-23 17:51:57 +00:00
Nicholas Marriott
f8771a538e Gearing up for 0.9.... 2009-04-21 21:11:46 +00:00
Nicholas Marriott
ba3ad75002 Mouse supprot isn't so bad. 2009-04-21 20:57:10 +00:00
Nicholas Marriott
22b44cbb2b 0.9 here we go. 2009-04-21 20:54:18 +00:00
214 changed files with 26492 additions and 14610 deletions

358
CHANGES
View File

@@ -1,3 +1,353 @@
CHANGES FROM 1.3 TO 1.4, 27 December 2010
* Window bell reporting fixed.
* Show which pane is active in the list-panes output.
* Backoff reworked.
* Prevent the server from dying when switching into copy mode when already
in a different mode.
* Reset running jobs when the status line is enabled or disabled.
* Simplify xterm modifier detection.
* Avoid crashing in copy mode if the screen size is too small for the
indicator.
* Flags -n and -p added to switch-client.
* Use UTF-8 line drawing characters on UTF-8 terminals, thus fixing some
terminals (eg putty) which disable the vt100 ACS mode switching sequences
in UTF-8 mode. On terminals without ACS, use ASCII equivalents.
* New server option exit-unattached added.
* New session option destroy-unattached added.
* Fall back on normal session choice method if $TMUX exists but is invalid
rather than rejecting.
* Mark repeating keys with "(repeat)" in the key list.
* When removing a pane, don't change the active pane unless the active pane
is actually the one being removed.
* New command last-pane added.
* AIX fixes.
* Flag -a added to unbind-key.
* Add XAUTHORITY to update-environment.
* More info regarding window and pane flags is now shown in list-*.
* If VISUAL or EDITOR contains "vi" configure mode-keys and status-key to vi.
* New window option monitor-silence and session option visual-silence added.
* In the built-in layouts distribute the panes more evenly.
* Set the default value of main-pane-width to 80 instead of 81.
* Command-line flag -V added.
* Instead of keeping a per-client prompt history make it global.
* Fix rectangle copy to behave like emacs (the cursor is not part of the
selection on the right edge but on the left it is).
* Flag -l added to switch-client.
* Retrieve environment variables from the global environment rather than
getenv(3), thus allowing them to be updated during the configuration file.
* New window options other-pane-{height,width} added.
* More minor bugs fixed and manpage improvements.
CHANGES FROM 1.2 TO 1.3, 18 July 2010
* New input parser.
* Flags to move through panes -UDLR added to select-pane.
* Commands up-pane, and down-pane removed, since equivalent behaviour is now
available through the target flag (-t:+ and -t:-).
* Jump-forward/backward in copy move (based on vi's F, and f commands).
* Make paste-buffer accept a pane as a target.
* Flag -a added to new-window to insert a window after an existing one, moving
windows up if necessary.
* Merge more mode into copy mode.
* Run job commands explicitly in the global environment (which can be modified
with setenv -g), rather than with the environment tmux started with.
* Use the machine's hostname as the default title, instead of an empty string.
* Prevent double free if the window option remain-on-exit is set.
* Key string conversions rewritten.
* Mark zombie windows as dead in the choose-window list.
* Tiled layout added.
* Signal handling reworked.
* Reset SIGCHLD after fork to fix problems with some shells.
* Select-prompt command removed. Therefore, bound ' to command-prompt -p index
"select-window -t:%%" by default.
* Catch SIGHUP and terminate if running as a client, thus avoiding clients from
being left hanging around when, for instance, a SSH session is disconnected.
* Solaris 9 fixes (such as adding compat {get,set}env(3) code).
* Accept none instead of default for attributes.
* Window options window-status-alert-{alert,bg,fg} added.
* Flag -s added to the paste-buffer command to specify a custom separator.
* Allow dragging to make a selection in copy mode if the mode-mouse option is
set.
* Support the mouse scroll wheel.
* Make pipe-pane accept special character sequences (eg #I).
* Fix problems with window sizing when starting tmux from .xinitrc.
* Give tmux sockets (but not the containing folder) group permissions.
* Extend the target flags (ie -t) to accept an offset (for example -t:+2), and
make it wrap windows, and panes.
* New command choose-buffer added.
* New server option detach-on-destroy to set what happens to a client when the
session it is attached to is destroyed. If on (default), the client is
detached. Otherwise, the client is switched to the most recently active of
the remaining sessions.
* The commands load-buffer, and save-buffer now accept a dash (-) as the file
to read from stdin, or write to stdout.
* Custom layouts added.
* Additional code reduction, bug fixes, and manpage enhancements.
CHANGES FROM 1.1 TO 1.2, 10 March 2010
* Switch to libevent.
* Emulate the ri (reverse index) capability, ergo allowing tmux to at least
start on Sun consoles (TERM=sun, or sun-color).
* Assign each entry a number, or lowercase letter in choose mode, and accept
that as a shortcut key.
* Permit top-bit-set characters to be entered in the status line.
* Mark no-prefix keys with (no prefix), rather than [] in list-keys.
* New command show-messages (alias showmsgs), and new session option
message-limit, to show a per-client log of status lines messages up to the
number defined by message-limit.
* Do not interpret #() for display-message to avoid leaking commands.
* New window options window-status-format, and window-status-current-format to
control the format of each window in the status line.
* Add a -p flag to display-message to print the output, instead of displaying
it in the status line.
* Emulate il1, dl1, ich1 to run with vt100 feature set.
* New command capture-pane (alias capturep) to copy the entire pane contents
to a paste buffer.
* Avoid duplicating code by adding a -w flag to set-option, and show-options to
set, and show window options. The commands set-window-option, and
show-window-options are now aliases.
* Panes can now be referred to as top, bottom, top-left, etc.
* Add server-wide options, which can be set with set-option -s, and shown with
show-options -s.
* New server option quiet (like -q from the command line).
* New server option escape-time to set the timeout used to detect if escapes
are alone, part of a function key, or meta sequence.
* New session options pane-active-border-bg, pane-active-border-fg,
pane-border-bg, and pane-border-fg to set pane colours.
* Make split-window accept a pane target, instead of a window.
* New command join-pane (alias joinp) to split, and move an existing pane into
the space (the opposite of break-pane), thus simplifying calls to
split-window, followed by move-window.
* Permit S- prefix on keys for shift when the terminal/terminfo supports them.
* Window targets (-t flag) can now refer to the last window (!), next (+), and
previous (-) window by number.
* Mode keys to jump to the bottom/top of history, end of the next word, scroll
up/down, and reverse search in copy mode.
* New session option display-panes-active-colour to display the active pane in
a different colour with the display-panes command.
* Read the socket path from $TMUX if it's present, and -L, and -S are not
given.
* Vi-style mode keys B, W, and E to navigate between words in copy mode.
* Start in more mode when configuration file errors are detected.
* Rectangle copy support added.
* If attach-session was specified with the -r flag, make the client read-only.
* Per-window alternate-screen option.
* Make load-buffer work with FIFOs.
* New window option word-separators to set the characters considered as word
separators in copy mode.
* Permit keys in copy mode to be prefixed by a repeat count, entered with [1-9]
in vi mode, or M-[1-9] in emacs mode.
* utf8 improvements.
* As usual, additional code reduction, bug fixes, and manpage enhancements.
CHANGES FROM 1.0 TO 1.1, 05 November 2009
* New run-shell (alias run) command to run an external command without a
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
of a configure script.
* monitor-content window option to monitor a window for a specific fnmatch(3)
pattern. The find-window command also now accepts fnmatch(3) patterns.
* previous-layout and select-layout commands, and a main-horizontal layout.
* Recreate the server socket on SIGUSR1.
* clear-history command.
* Use ACS line drawing characters for pane separator lines.
* UTF-8 improvements, and code to detect UTF-8 support by looking at
environment variables.
* The resize-pane-up and resize-pane-down commands are now merged together
into a new resize-pane command with -U and -D flags.
* confirm-before command to request a yes/no answer before executing dangerous
commands.
* Status line bug fixes, support for UTF-8 (status-utf8 option), and a key to
paste from the paste buffer.
* Support for some additional escape sequences and terminal features, including
better support for insert mode and tab stops.
* Improved window resizing behaviour, modelled after xterm.
* Some code reduction and a number of miscellaneous bug fixes.
================================================================================
On 01 June 2009, tmux was imported into the OpenBSD base system. From this date
onward changes are logged as part of the normal CVS commit message to either
OpenBSD or SourceForge CVS. This file will be updated to contain a summary of
major changes with each release, and to mention important configuration or
command syntax changes during development.
The list of older changes is below.
================================================================================
21 May 2009
* stat(2) files before trying to load them to avoid problems, for example
with "source-file /dev/zero".
19 May 2009
* Try to guess if the window is UTF-8 by outputting a three-byte UTF-8 wide
character and seeing how much the cursor moves. Currently tries to figure out
if this works by some stupid checks on the terminal, these need to be
rethought. Also might be better using a width 1 character rather than width 2.
* If LANG contains "UTF-8", assume the terminal supports UTF-8, on the grounds
that anyone who configures it probably wants UTF-8. Not certain if this is
a perfect idea but let's see if it causes any problems.
* New window option: monitor-content. Searches for a string in a window and if
it matches, highlight the status line.
18 May 2009
* main-horizontal layout and main-pane-height option to match vertical.
* New window option main-pane-width to set the width of the large left pane with
main-vertical (was left-vertical) layout.
* Lots of layout cleanup. manual layout is now manual-vertical.
16 May 2009
* select-layout command and a few default key bindings (M-0, M-1, M-2, M-9) to
select layouts.
* Recreate server socket on SIGUSR1, per SF feature request 2792533.
14 May 2009
* Keys in status line (p in vi mode, M-y in emacs) to paste the first line
of the upper paste buffer. Suggested by Dan Colish.
* clear-history command to clear a pane's history.
* Don't force wrapping with \n when asked, let the cursor code figure it out.
Should fix terminals which use this to detect line breaks.
* Major cleanup and restructuring of build infrastructure. Still separate files
for GNU and BSD make, but they are now hugely simplified at the expense of
adding a configure script which must be run before make. Now build and
install with:
$ ./configure && make && sudo make install
04 May 2009
* Use ACS line drawing characters for pane separator lines.
30 April 2009
* Support command sequences without a space before the semicolon, for example
"neww; neww" now works as well as "neww ; neww". "neww;neww" is still an
error.
* previous-layout command.
* Display the layout name in window lists.
* Merge resize-pane-up and resize-pane-down into resize-pane with -U and -D
flags.
29 April 2009
* Get rid of compat/vis.* - only one function was used which is easily
replaced,and less compat code == good.
27 April 2009
* Avoid using the prompt history when the server is locked, and prevent any
input entered from being added to the client's prompt history.
* New command, confirm-before (alias confirm), which asks for confirmation
before executing a command. Bound "&" and "x" by default to confirm-before
"kill-window" and confirm-before "kill-pane", respectively.
23 April 2009
* Support NEL, yet another way of making newline. Fixes the output from some
Gentoo packaging thing. Reported by someone on SF then logs that allowed a
fix sent by tcunha.
* Use the xenl terminfo flag to detect early-wrap terminals like the FreeBSD
console. Many thanks for a very informative email from Christian Weisgerber.
21 April 2009
* tmux 0.8 released.
17 April 2009
* Remove the right number of characters from the buffer when escape then
@@ -247,7 +597,7 @@
18 January 2009
* Unbreak UTF-8.
* -a flag to next-window and previous-window to select the next or previous
* -a flag to next-window and previous-window to select the next or previous
window with activity or bell. Bound to M-n and M-p.
* find-window command to search window names, titles and visible content (but
not history) for a string. If only one is found, the window is selected
@@ -332,7 +682,7 @@
* Vertical window splitting. Currently can only split a window into two panes.
New split-window command splits (bound to ") and switch-pane command (bound to
o) switches between panes.
o) switches between panes.
close-pane, swap-pane commands are to follow. Also to come are pane resizing,
>2 panes, the ability to break a pane out to a full window and vice versa and
@@ -351,7 +701,7 @@
* New option, lock-after-time. If there is no activity in the period specified
by this option (in seconds), tmux will lock the server. Default is 1800 (30
minutes), set to 0 to disable.
minutes), set to 0 to disable.
* Server locking. Two new commands: set-password to set a password (a
preencrypted password may be specified with -c); and lock-server to lock the
server until the password is entered. Also an additional command line flag,
@@ -1204,7 +1554,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
$Id: CHANGES,v 1.272 2009-04-17 12:36:21 nicm Exp $
$Id: CHANGES,v 1.304 2010-12-27 21:37:42 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

288
FAQ
View File

@@ -1,33 +1,116 @@
tmux frequently asked questions
* How is tmux different from GNU screen? What else does it offer?
******************************************************************************
* PLEASE NOTE: most display problems are due to incorrect TERM! Before *
* reporting problems make SURE that TERM settings are correct inside and *
* outside tmux. *
* *
* Inside tmux TERM must be "screen" or similar (such as "screen-256color"). *
* Don't bother reporting problems where it isn't! *
* *
* Outside, it must match your terminal: particularly, use "rxvt" for rxvt *
* and derivatives. *
******************************************************************************
tmux offers several advantages over screen:
* How is tmux different from GNU screen?
- a clearly-defined client-server model: windows are independent entities which
may be attached simultaneously to multiple sessions and viewed from multiple
clients (terminals), as well as moved freely between sessions within the same
tmux server;
- a consistent, well-documented command interface, with the same syntax
whether used interactively, as a key binding, or from the shell;
- easily scriptable from the shell;
- multiple paste buffers;
- choice of vi or emacs key layouts;
- an option to limit the window size;
- a more usable status line syntax, with the ability to display the first line
of output of a specific command;
- a cleaner, modern, easily extended, BSD-licensed codebase.
tmux and GNU screen have many similarities. Some of the main differences I am
aware of are (bearing in mind I haven't used screen for a few years now):
There are still a few features screen includes that tmux omits:
- tmux uses a client-server model. Each server has single Unix domain socket in
/tmp and within one server there are multiple sessions which may be attached
to multiple clients (terminals).
- builtin serial and telnet support; this is bloat and is unlikely to be added
to tmux;
- wider platform support, for example IRIX and HP-UX, and for odd terminals.
This has advantages, notably: windows may be linked simultaneously to
multiple sessions; windows may be moved freely between sessions; and a client
may be switched between sessions easily (C-b D). There is one major
disadvantage: if the server crashes, game over, all sessions die. In
practice, however, tmux is quite stable and gets more so as people report any
bugs they hit :-).
This model is different from screen, where typically each new screen instance
is independent. tmux supports the same behaviour by using multiple servers
with the -L option but it is not typically recommended.
- Different command interfaces. One of the goals of tmux is that the shell
should be easily usable as a scripting language - almost all tmux commands
can be used from the shell and behave identically whether used from the
shell, from a key binding or from the command prompt. Personally I also find
tmux's command interface much more consistent and clearer, but this is
subjective.
- tmux calls window names (what you see in the status line) "names", screen
calls them "titles".
- tmux has a multiple paste buffers. Not a major one but comes in handy quite a
lot.
- tmux supports automatically renaming windows to the running application
without gross hacks using escape sequences. Its even on by default.
- tmux has a choice of vi or emacs key layouts. Again, not major, but I use
emacs so if tmux did support only one key set it would be emacs and then all
the vi users would get humpy. Key bindings may be completely reconfigured in
any case.
- tmux has an option to limit the window size.
- tmux has search in windows (C-b f).
- The window split (pane) model is different. tmux has two objects, windows and
panes; screen has just windows. This difference has several implications:
* In screen you can have a window appear in several layouts, in tmux a pane
can only be in one window (fixing this is a big todo item but quite
invasive).
* tmux layouts are immutable and do not get changed unless you modify them.
* In tmux, all panes are closed when you kill a window.
* tmux panes do not have individual names, titles and so on.
I think tmux's model is much easier to manage and navigate within a window,
but breaking panes off from and joining them to windows is more clumsy.
tmux also has support for preset pane layouts.
- tmux's status line syntax is more readable and easier to use. I think it'd be
hard for anyone to argue with this. tmux doesn't support running a command
constantly and always using the last line of its output, commands must be run
again each time.
- tmux has modern, easily extended code. Again hard to argue screen is better
if you have looked at the code.
- tmux depends on libevent. I don't see this as a disadvantage: libevent is
small and portable, and on modern systems with current package management
systems dependencies are not an issue. libevent brings advantages in code
simplicity and performance.
- screen allows the window to be bigger than the terminal and can pan around
it. tmux limits the size to the largest attached client. This is a big todo
item for tmux but it is not trivial.
- screen has builtin serial and telnet support; this is bloat and is unlikely
to be added to tmux.
- screen has support for updating utmp. Nobody has really come up with a clean,
portable way to do this without making tmux setuid or setgid yet.
- Environment handling is different.
- tmux tends to be more demanding on the terminal so tends to show up terminal
and application bugs which screen does not.
- screen has wider platform support, for example IRIX and HP-UX, and for odd
terminals.
* I found a bug! What do I do?
Please send bug reports by email to nicm@users.sourceforge.net. Please
include as much of the following information as possible:
Please send bug reports by email to nicm@users.sourceforge.net or
tmux-users@lists.sourceforge.net. Please include as much of the following
information as possible:
- the version of tmux you are running;
- the operating system you are using and its version;
@@ -42,16 +125,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!
@@ -81,23 +165,31 @@ default) to the new key. For example:
* How do I use UTF-8?
When running tmux in a UTF-8 capable terminal, two things must be done to
enable support. UTF-8 must be turned on in tmux; this may be done separately
for each tmux window or globally by setting the "utf8" flag:
When running tmux in a UTF-8 capable terminal, UTF-8 must be turned on in tmux;
as of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by
checking the LC_ALL, LC_CTYPE and LANG environment variables. list-clients may
be used to check if this is detected correctly; if not, the -u command-line
flag may be specified when creating or attaching a client to a tmux session:
setw -g utf8 on
$ tmux -u new
And, as it is not possible to automatically detect that a terminal is UTF-8
capable, tmux must be told by passing the -u flag when creating or
attaching a client to a tmux session:
$ tmux -u new
Since the 1.0 release, tmux will turn on UTF-8 related options automatically
(ie status-utf8, and utf8) if the above conditions are met.
* How do I use a 256 colour terminal?
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.
@@ -105,22 +197,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?
@@ -149,6 +237,8 @@ the ctrl (bit 5 set, for example ^[[5~ to ^[[5^) modifier in non-xterm(1) mode;
it may be possible to configure vim to accept these, an example of how to do so
would be welcome.
vim users may also want to set the "ttyfast" option inside tmux.
* Why doesn't elinks set the window title inside tmux?
There isn't a way to detect if a terminal supports setting the window title, so
@@ -186,4 +276,100 @@ 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.
$Id: FAQ,v 1.21 2009-03-31 23:17:28 nicm Exp $
* I use PuTTY and my tmux window pane separators are all qqqqqqqqq's!
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.
* What is the best way to display the load average? Why no #L?
It isn't possible to get the load average portably in code and it is preferable
not to add portability goop. The following works on at least Linux, *BSD and OS
X:
uptime|awk '{split(substr($0, index($0, "load")), a, ":"); print a[2]}'
* How do I attach the same session to multiple clients but with a different
current window, like screen -x?
One or more of the windows can be linked into multiple sessions manually with
link-window, or a grouped session with all the windows can be created with
new-session -t.
* Ctrl and arrow keys doesn't work in putty! What do I do?
putty inverts the sense of the cursor key mode on ctrl, which is a bit hard for
tmux to detect properly. To get ctrl keys right, change the terminfo settings
so kUP5 (Ctrl-Up etc) are the adjusted versions, and disable smkx/rmkx so tmux
doesn't change the mode. For example with this line in .tmux.conf (assuming you
have TERM set to xterm):
set -g terminal-overrides "xterm*:kLFT5=\eOD:kRIT5=\eOC:kUP5=\eOA:kDN5=\eOB:smkx@:rmkx@"
Note that this will only work in tmux 1.2 and above.
* How can I blank the tmux window?
GNU screen has a feature whereby it will blank the screen after a period of
inactivity. To do the same thing in tmux, use the lock-command setting, for
example (with GNU bash):
set -g lock-command 'tput civis && read -s -n1'
This will remove the cursor and tell the shell to quit once a key has been
pressed. For zsh, use "read -s -k1".
In addition, it's possible to have both blanking and locking (for instance via
lock(1) or vlock(1)) by using the following:
bind x set lock-command '/usr/bin/vlock' \; lock-client \; set lock-command 'tput civis && read -s -n1'
* How can I open a new window in the same directory as the current window?
One option is to just run "TMUX= tmux" in the window. However, this only works if no
command is running, so that you can input the command.
A workaround is to let tmux know about the current path through an environment
variable. To do so, use the following command:
[ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#I") $PWD
Which sets TMUXPWD_i (where i is the number of the current window) to the path
of the current directory. This command can be added to PS1, for example:
PS1='$([ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#I") $PWD)\h$ '
When a new window is created, the shell should be asked to change
directory. You can define a new binding (for example, if using GNU bash):
bind-key C-c run-shell 'tmux neww "cd $(tmux display -p "\$TMUXPWD_#I"); exec bash"'
This solution will work even if a command is currently running in the terminal,
but it will not work from a window that has just been swapped with another
because TMUXPWD_i will not be updated after a swap. However, once a new prompt
is displayed, TMUXPWD_i is updated properly.
* tmux doesn't start with "daemon failed"
tmux shows something similar to this when started:
fatal: server_start: daemon failed: No such file or directory
fatal: main_dispatch: imsg_read failed
A possible reason is that /dev/null is not a character device or is otherwise
inaccessible.
Check with:
file /dev/null
ls -l /dev/null
If it is not a character device or has incorrect permissions, it can typically
be recreated with:
cd /dev && rm null && ./MAKEDEV null
$Id: FAQ,v 1.41 2010-12-15 23:31:30 nicm Exp $

View File

@@ -1,144 +1,87 @@
# $Id: GNUmakefile,v 1.82 2009-04-21 20:10:22 nicm Exp $
# $Id: GNUmakefile,v 1.130 2010-12-27 21:32:16 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
.PHONY: clean
PROG= tmux
VERSION= 0.8
DATE= $(shell date +%Y%m%d-%H%M)
VERSION= 1.4
#FDEBUG= 1
META?= \002
CC?= cc
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+=
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c \
screen.c screen-write.c screen-redraw.c \
grid.c grid-view.c \
window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
key-string.c key-bindings.c resize.c arg.c mode-key.c \
layout.c cmd.c cmd-generic.c cmd-string.c cmd-list.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \
cmd-refresh-client.c cmd-kill-window.c cmd-list-clients.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
cmd-rotate-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c util.c names.c \
osdep-unknown.c osdep-openbsd.c osdep-freebsd.c osdep-linux.c \
osdep-darwin.c attributes.c
# Sun CC
ifneq ($(shell ($(CC) -V 2>&1|awk '/Sun C/' || true)), )
CFLAGS+= -erroff=E_EMPTY_DECLARATION
FDEBUG=
endif
CC?= gcc
INCDIRS+= -I. -I-
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\"" -DMETA="'${META}'"
ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG
LDFLAGS+= -rdynamic
LIBS+= -ldl
endif
ifeq (${CC},gcc)
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
endif
LDFLAGS+=
LIBS+= -lncurses
# 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
INSTALLMAN= install -g bin -o root -m 444
ifeq ($(shell uname),AIX)
INCDIRS+= -I/usr/local/include/ncurses -Icompat
SRCS+= compat/vis.c compat/strlcpy.c compat/strlcat.c compat/strtonum.c \
compat/fgetln.c compat/asprintf.c compat/daemon.c compat/forkpty-aix.c \
compat/getopt_long.c compat/bsd-poll.c
CFLAGS+= -DNO_TREE_H -DNO_ASPRINTF -DNO_QUEUE_H -DNO_VSYSLOG \
-DNO_PROGNAME -DNO_STRLCPY -DNO_STRLCAT -DNO_STRTONUM \
-DNO_SETPROCTITLE -DNO_QUEUE_H -DNO_TREE_H -DNO_FORKPTY -DNO_FGETLN \
-DBROKEN_GETOPT -DBROKEN_POLL -DNO_PATHS_H
LDFLAGS+= -L/usr/local/lib
endif
ifeq ($(shell uname),IRIX64)
INCDIRS+= -Icompat -I/usr/local/include/ncurses
SRCS+= compat/strlcpy.c compat/strtonum.c compat/daemon.c \
compat/asprintf.c compat/fgetln.c compat/forkpty-irix.c
CFLAGS+= -DNO_STRLCPY -DNO_STRTONUM -DNO_TREE_H -DNO_SETPROCTITLE \
-DNO_DAEMON -DNO_FORKPTY -DNO_PROGNAME -DNO_ASPRINTF -DNO_FGETLN \
-DBROKEN_VSNPRINTF -D_SGI_SOURCE -std=c99
LDFLAGS+= -L/usr/local/lib
LIBS+= -lgen
endif
ifeq ($(shell uname),SunOS)
INCDIRS+= -Icompat -I/usr/local/include/ncurses
SRCS+= compat/strtonum.c compat/daemon.c compat/forkpty-sunos.c \
compat/asprintf.c compat/fgetln.c compat/vis.c
CFLAGS+= -DNO_STRTONUM -DNO_TREE_H -DNO_PATHS_H -DNO_SETPROCTITLE \
-DNO_DAEMON -DNO_FORKPTY -DNO_PROGNAME -DNO_ASPRINTF -DNO_FGETLN
LDFLAGS+= -L/usr/local/lib
LIBS+= -lsocket -lnsl
endif
ifeq ($(shell uname),Darwin)
INCDIRS+= -Icompat
SRCS+= compat/strtonum.c compat/bsd-poll.c compat/vis.c
CFLAGS+= -DNO_STRTONUM -DNO_SETRESUID -DNO_SETRESGID -DNO_SETPROCTITLE \
-DNO_QUEUE_H -DNO_TREE_H -DBROKEN_POLL
endif
ifeq ($(shell uname),Linux)
INCDIRS+= -Icompat
SRCS+= compat/strlcpy.c compat/strlcat.c compat/strtonum.c \
compat/fgetln.c compat/getopt_long.c compat/vis.c
CFLAGS+= $(shell getconf LFS_CFLAGS) -D_GNU_SOURCE \
-DNO_STRLCPY -DNO_STRLCAT -DNO_STRTONUM -DNO_SETPROCTITLE \
-DNO_QUEUE_H -DNO_TREE_H -DUSE_PTY_H -DNO_FGETLN \
-DBROKEN_GETOPT -std=c99
LIBS+= -lcrypt -lutil
endif
INSTALL?= install
INSTALLDIR= $(INSTALL) -d
INSTALLBIN= $(INSTALL) -m 555
INSTALLMAN= $(INSTALL) -m 444
SRCS= $(shell echo *.c|LC_ALL=C sed 's|osdep-[a-z0-9]*.c||g')
include config.mk
OBJS= $(patsubst %.c,%.o,$(SRCS))
CLEANFILES= ${PROG} *.o .depend *~ ${PROG}.core *.log compat/*.o index.html
all: tmux
CPPFLAGS:= ${INCDIRS} ${CPPFLAGS}
tmux: $(OBJS)
$(CC) $(LDFLAGS) -o tmux $+ $(LIBS)
all: $(PROG)
$(PROG): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $+ $(LIBS)
depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
install:
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/bin
$(INSTALLBIN) $(PROG) $(DESTDIR)$(PREFIX)/bin/$(PROG)
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) $(PROG).1 $(DESTDIR)$(PREFIX)/man/man1/$(PROG).1
depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
clean:
rm -f $(CLEANFILES)
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
clean-depend:
rm -f .depend
clean-all: clean clean-depend
rm -f config.h config.mk
install: all
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/bin
$(INSTALLBIN) tmux $(DESTDIR)$(PREFIX)/bin/tmux
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) tmux.1 $(DESTDIR)$(PREFIX)/man/man1/tmux.1
-include .depend

182
Makefile
View File

@@ -1,158 +1,84 @@
# $Id: Makefile,v 1.121 2009-04-21 20:10:22 nicm Exp $
# $Id: Makefile,v 1.162 2010-12-27 21:32:16 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
.SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html
.SUFFIXES: .c .o
.PHONY: clean
PROG= tmux
VERSION= 0.8
OS!= uname
REL!= uname -r
DATE!= date +%Y%m%d-%H%M
VERSION= 1.4
#FDEBUG= 1
META?= \002 # C-b
CC?= cc
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+=
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c \
screen.c screen-write.c screen-redraw.c \
grid.c grid-view.c \
window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
layout.c key-string.c key-bindings.c resize.c arg.c mode-key.c \
cmd.c cmd-generic.c cmd-string.c cmd-list.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \
cmd-refresh-client.c cmd-kill-window.c cmd-list-clients.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
cmd-rotate-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c util.c names.c attributes.c \
osdep-unknown.c osdep-openbsd.c osdep-freebsd.c osdep-linux.c \
osdep-darwin.c osdep-netbsd.c
CC?= c
INCDIRS+= -I. -I- -I/usr/local/include
CFLAGS+= -DMETA="'${META}'"
.ifdef PROFILE
# Don't use ccache
CC= /usr/bin/gcc
CFLAGS+= -pg -DPROFILE -O0
.endif
.ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG
LDFLAGS+= -Wl,-E
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\""
.else
CFLAGS+= -DBUILD="\"$(VERSION)\""
.endif
#CFLAGS+= -pedantic -std=c99
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
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
INSTALLMAN= install -g bin -o root -m 444
INSTALL?= install
INSTALLDIR= ${INSTALL} -d
INSTALLBIN= ${INSTALL} -m 555
INSTALLMAN= ${INSTALL} -m 444
LDFLAGS+= -L/usr/local/lib
.ifdef PROFILE
LDFLAGS+= -pg
.endif
LIBS+= -lutil -lncurses
# FreeBSD and DragonFly
.if ${OS} == "FreeBSD" || ${OS} == "DragonFly"
INCDIRS+= -Icompat
SRCS+= compat/vis.c
CFLAGS+= -DUSE_LIBUTIL_H -DNO_QUEUE_H -DNO_TREE_H
LIBS+= -lcrypt
.endif
# NetBSD
.if ${OS} == "NetBSD"
INCDIRS= -Icompat
SRCS+= compat/strtonum.c compat/vis.c
LIBS+= -lcrypt
CFLAGS+=-DNO_STRTONUM
.endif
OBJS= ${SRCS:S/.c/.o/:S/.y/.o/}
DISTDIR= ${PROG}-${VERSION}
DISTFILES= *.[chyl] Makefile GNUmakefile *.[1-9] NOTES TODO CHANGES FAQ \
`find examples compat -type f -and ! -path '*CVS*'`
CLEANFILES= ${PROG} *.o .depend *~ ${PROG}.core *.log compat/*.o index.html
CPPFLAGS:= ${INCDIRS} ${CPPFLAGS}
SRCS!= echo *.c|LC_ALL=C sed 's|osdep-[a-z0-9]*.c||g'
.include "config.mk"
OBJS= ${SRCS:S/.c/.o/}
.c.o:
${CC} ${CPPFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
.y.o:
${YACC} ${.IMPSRC}
${CC} ${CPPFLAGS} ${CFLAGS} -c y.tab.c -o ${.TARGET}
all: tmux
all: ${PROG}
${PROG}: ${OBJS}
${CC} ${LDFLAGS} -o ${PROG} ${OBJS} ${LIBS}
tmux: ${OBJS}
${CC} ${LDFLAGS} -o tmux ${OBJS} ${LIBS}
depend:
mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
dist: clean
grep '^#FDEBUG=' Makefile
grep '^#FDEBUG=' GNUmakefile
[ "`(grep '^VERSION' Makefile; grep '^VERSION' GNUmakefile)| \
uniq -u`" = "" ]
tar -zc \
-s '/.*/${DISTDIR}\/\0/' \
-f ${DISTDIR}.tar.gz ${DISTFILES}
lint:
lint -chvx ${CFLAGS:M-D*} ${SRCS:M*.c}
clean:
rm -f ${CLEANFILES}
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
upload-index.html: update-index.html
scp index.html images/*.png \
nicm,tmux@web.sf.net:/home/groups/t/tm/tmux/htdocs
rm -f images/small-*
clean-depend:
rm -f .depend
update-index.html:
(cd images && \
rm -f small-* && \
for i in *.png; do \
convert "$$i" -resize 200x150 "small-$$i"; \
done \
)
sed "s/%%VERSION%%/${VERSION}/g" index.html.in >index.html
clean-all: clean clean-depend
rm -f config.h config.mk
install: all
${INSTALLDIR} ${DESTDIR}${PREFIX}/bin
${INSTALLBIN} ${PROG} ${DESTDIR}${PREFIX}/bin/
${INSTALLBIN} tmux ${DESTDIR}${PREFIX}/bin/
${INSTALLDIR} ${DESTDIR}${PREFIX}/man/man1
${INSTALLMAN} ${PROG}.1 ${DESTDIR}${PREFIX}/man/man1/
${INSTALLMAN} tmux.1 ${DESTDIR}${PREFIX}/man/man1/

63
NOTES
View File

@@ -4,14 +4,15 @@ 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.8 release runs on OpenBSD, FreeBSD, Linux and OS X and may still run on
Solaris (although it hasn't been tested in a while). It is usable, although
there remain a number of missing features and some remaining bugs are expected.
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.
Since the 1.2 release that tmux depends on libevent. Download the stable
version from:
http://www.monkey.org/~provos/libevent/
tmux consists of a server part and multiple clients. The server is created when
required and runs continuously unless killed by the user. Clients access the
@@ -24,39 +25,10 @@ windows into several simultaneously displayed panes; and to bind and unbind
command keys (invoked preceded by a prefix key, by default ctrl-b). Please see
the tmux(1) man page for further information.
The following is a summary of major features implemented in this version:
- Basic multiplexing, window switching, attaching and detaching.
- Window listing and renaming.
- Key binding.
- Handling of client terminal resize.
- Terminal emulation sufficient to handle most curses applications.
- A optional status line (enabled by default).
- Window history and copy and paste.
- Support for VT100 line drawing characters.
- A large command set.
- Vertical window splitting and layout.
- Automatic server locking on inactivity.
- A configuration file.
- UTF-8 support.
And major missing features:
- Proper mouse support.
- 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.
tmux supports UTF-8. To use it, the utf8 option must be set on each window;
this may be turned on for all windows by setting it as a global option, see
tmux(1) and the FAQ file. In addition, when starting tmux or attaching to an
existing session from a UTF-8-capable terminal, the -u flag must be specified.
are missing it may refuse to run, or not behave correctly.
A Vim syntax file is available in the examples directory. To install it:
@@ -74,15 +46,6 @@ A Vim syntax file is available in the examples directory. To install it:
For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory.
The CVS HEAD version of tmux often has additional features from the release
versions; if interested, testing it is encouraged. It can be obtained by
anonymous CVS from SourceForge:
$ cvs -d:pserver:anoncvs@tmux.cvs.sf.net:/cvsroot/tmux co tmux
If running CVS HEAD, please note it is development code and there may be bugs
and undocumented features; please read the CHANGES file for information.
tmux mailing lists are available; visit:
https://sourceforge.net/mail/?group_id=200378
@@ -92,6 +55,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.45 2009-04-21 20:06:12 nicm Exp $
$Id: NOTES,v 1.54 2010-12-27 21:36:37 tcunha Exp $

203
TODO
View File

@@ -1,103 +1,130 @@
- line mode/char-at-a-time mode a la telnet?
- handle ioctl/termios stuff on window sockets
- figure out once and for all what is going on with backspace and del
backspace should be translated per the termios setting.
del passed through?
- window creation/idle time
- profile/optimise, particularly (i suspect) input.c
- 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 so you could have C-b K K for
kill-window to limit accidental presses
- 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
- commands:
extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session?
clone-session command to link all windows to a new 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
- split clients into three RB trees by fd: attached/unattached/dead?
or tailqs? what would be fastest per-char?
- c/p is still borken in some ways
- better mode features: search, back word, forward word, etc
in $x time
- lift SHRT_MAX limits for history?
- flags to centre screen in window
- better terminal emulation (identify, insert mode, some other bits)
- when resizing, use history
- audit for leftover/unused code
- 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
- 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?
- next prev word etc in command prompt
- use a better termcap internally instead of screen, perhaps xterm
- a command to display the status line briefly when it is turned off
- FAQ "Can I have some examples of cool things I can do with tmux?" -- linkw,
more??
- kill all but current pane
- fix rxvt cursor fg issue (text under cursor can have non-white fg)
- key handling sucks a bit and needs to be reworked
- some people find first window being 0 rather than 1 is awkward on the
keyboard. what about a new-window-index option that sets the base at which
tmux starts numbering new windows, then they can do: set -g new-window-index
1; bind 0 selectw -t:10
- some way to change status line colours based on something? command?
- 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?
- command to purge window history? or apply history-limit changes?
- clone session command
- make command sequences more usable: don't require space around ;, handle
errors better
- 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
- 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?
- a confirm-before command which asks "Are you sure? (y/n)" before executing
command, eg bind-key "&" confirm-before "kill-window"
- 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
- clear window title on exit
- better support for stupid margin terminals. strcmp for cons25 sucks, how can
these be autodetected?
- refer to windows by name etc (duplicates? fnmatch?)
- the output code (tty.c) could do with optimisation depending on term
capibilities
- resize-pane-up/down should be resize-pane -U/-D. ditto up-pane/down-pane
should be select-pane -U/-D
- layout/split stuff:
horiz split command, and similar resizing commands as for vert split
display the layout in a readable format somewhere
previous-layout command
select-layout command
make manual layout a bit less of a hack and make it handle a grid
should the layout be a window option???
more layouts
better resizing of shells when changing layout
find and fix bug with clear screen after horiz split
speed improvements? -- still too slow over ssh!
hardcoded 81 for left-vertical is nasty
- test bug sshing from freebsd console (tom iirc?)
- fix build on solaris 10
- rotate-window has redraw bugs... :-/
(hopefully) for 0.8, in no particular order:
- nothing!
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- make command sequences more usable: don't require space after ;, handle
errors better
- attach should have a flag to create session if it doesn't exist
- choice and more mode would be better per client than per window?
- hooks to which commands may be attached, for example: tmux add-hook
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
$HOME/.tmux-session.conf
- get it passing all the vttest tests that don't require resizing the terminal
- way to set socket path from config file
- 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??
- 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)
- support for bce
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
-- idea of a "view" onto a window, need base x/y offsets for redraw
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- commands should be able to succeed or fail and have || or && for command
lists
- some way to KEEP a command running continually and just use its LAST line of
output
- 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
- 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
- support esc-esc to quit in modes
- fix ctrl+F1-F4 output. to what?
- look into xterm clearing its selection when scrolling etc
- better utf8 support: window names, prompt input, message display
- session history for client and last-session command
- option to change status line colour when current window is in a mode?
- option to move copy mode indicator into status line
- list-buffer/show-buffer should display UTF-8
- selection behaviour closer to vi in vi mode
- live update: server started with -U connects to server, requests sessions and
windows, receives fds
- command to show a tree of sessions-windows-panes (active marked with *)
- sort out inheriting config from shell on new sessions/windows:
should pick up default-path/termios/etc from client if possible,
else leave empty/default
- link panes into multiple windows
- -h option to capture-pane to capture the history as well
- bells should be passed between sessions with visual-bell etc
- use screen-256color when started on 256 colour terminal??
- if-shell/run-shell should block further command execution in the same command
sequence until its shell exits, to allow them to be used from the config file
- better session sharing: create-socket command to create socket somewhere (-r
flag for readonly)
- allow buffer to be specified when copying in copy mode
- multiline status line (no?)
- flag for absolute pane size to resize-pane
- sanity check input to socket
- select-buffer command
- support title stack, both internally and externally
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
- copy buffers should be global, limit can be server option, nuke copy-buffer
command
- command to show status line information briefly when it is off
- some way to pad # stuff with spaces, #!2T maybe
- FreeBSD console problems
- a binding to "scroll down and exit at bottom" copy mode
- some way to pass keystrokes in copy mode through to underlying window
- last window update time and # replacement for it for display-message
- find-window across sessions - other ways to make session handling easier?
- ' and " should be parsed the same (eg "\e" vs '\e') in config and command
prompt?
- command to toggle selection not to move it in copy-mode
- why are alerts per-winlink? try per window?
- audit of escape sequence support vs xterm
- support binding keys to mouse (mouse-select-pane -> mouse-keys or something,
mouse click == select-pane -t %%, mouse scroll up == copy-mode)
- something for -t "last window in session" so a session can be used as a stack
- synchronous commands - client sends cmd and blocks, neww/splitw saves client
ptr then when program inside died, sends MSG_SOMETHING with wait status to
client
- documentation improvements - rlpowell's tutorial - build instructions
- better configure? with-libevent
- bind commands to key sequences?
- monitor, bell etc should monitor /all/ panes in the window not just one
- a history of commands that can be reversed (reverse member of each command,
and a buffer) info() when changing to same window
- don't pass UTF-8 through vis for titles
- clearing screen should push lines into history
- add a unique ever-increasing pane id to each pane, export it in $TMUX_PANE
(as %1, %2 etc) and allow it to be used as a target
- way to add dest for break-pane; maybe some easier way to unbreak-pane
- case insensitive searching
- dynamically generated jobs (eg "date ...") do not work well because
their entries are never collected, should either store status jobs in
a different tree or flush all unused persist jobs every update rather
than just updating them
- pane-index option like base-index
- option to move status line to top
- support "xterm2" mouse mode
- respawn-pane command
- configurable borders and empty space filler for when panes < window?

194
arg.c
View File

@@ -1,194 +0,0 @@
/* $Id: arg.c,v 1.5 2008-08-28 17:45:25 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 (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 (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);
}

10
array.h
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.11 2010-06-06 00:27:08 tcunha Exp $ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,6 +19,8 @@
#ifndef ARRAY_H
#define ARRAY_H
#define ARRAY_INITIALIZER { NULL, 0, 0 }
#define ARRAY_DECL(n, c) \
struct n { \
c *list; \
@@ -45,7 +47,7 @@
} \
} while (0)
#define ARRAY_EMPTY(a) ((a) == NULL || (a)->num == 0)
#define ARRAY_EMPTY(a) (((void *) (a)) == NULL || (a)->num == 0)
#define ARRAY_LENGTH(a) ((a)->num)
#define ARRAY_DATA(a) ((a)->list)
@@ -85,7 +87,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 +104,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: attributes.c,v 1.1 2009-01-27 20:22:33 nicm Exp $ */
/* $Id: attributes.c,v 1.4 2010-06-05 23:54:51 tcunha Exp $ */
/*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -23,29 +23,30 @@
#include "tmux.h"
const char *
attributes_tostring(u_char ch)
attributes_tostring(u_char attr)
{
static char buf[128];
if (ch == 0)
return ("default");
if (attr == 0)
return ("none");
buf[0] = '\0';
if (ch & GRID_ATTR_BRIGHT)
if (attr & GRID_ATTR_BRIGHT)
strlcat(buf, "bright,", sizeof (buf));
if (ch & GRID_ATTR_DIM)
if (attr & GRID_ATTR_DIM)
strlcat(buf, "dim,", sizeof (buf));
if (ch & GRID_ATTR_UNDERSCORE)
if (attr & GRID_ATTR_UNDERSCORE)
strlcat(buf, "underscore,", sizeof (buf));
if (ch & GRID_ATTR_BLINK)
if (attr & GRID_ATTR_BLINK)
strlcat(buf, "blink,", sizeof (buf));
if (ch & GRID_ATTR_REVERSE)
if (attr & GRID_ATTR_REVERSE)
strlcat(buf, "reverse,", sizeof (buf));
if (ch & GRID_ATTR_HIDDEN)
if (attr & GRID_ATTR_HIDDEN)
strlcat(buf, "hidden,", sizeof (buf));
if (ch & GRID_ATTR_ITALICS)
if (attr & GRID_ATTR_ITALICS)
strlcat(buf, "italics,", sizeof (buf));
*(strrchr(buf, ',')) = '\0';
if (*buf != '\0')
*(strrchr(buf, ',')) = '\0';
return (buf);
}
@@ -54,7 +55,7 @@ int
attributes_fromstring(const char *str)
{
const char delimiters[] = " ,|";
u_char ch;
u_char attr;
size_t end;
if (*str == '\0' || strcspn(str, delimiters) == 0)
@@ -62,31 +63,31 @@ attributes_fromstring(const char *str)
if (strchr(delimiters, str[strlen(str) - 1]) != NULL)
return (-1);
if (strcasecmp(str, "default") == 0)
if (strcasecmp(str, "default") == 0 || strcasecmp(str, "none") == 0)
return (0);
ch = 0;
attr = 0;
do {
end = strcspn(str, delimiters);
if ((end == 6 && strncasecmp(str, "bright", end) == 0) ||
(end == 4 && strncasecmp(str, "bold", end) == 0))
ch |= GRID_ATTR_BRIGHT;
attr |= GRID_ATTR_BRIGHT;
else if (end == 3 && strncasecmp(str, "dim", end) == 0)
ch |= GRID_ATTR_DIM;
attr |= GRID_ATTR_DIM;
else if (end == 10 && strncasecmp(str, "underscore", end) == 0)
ch |= GRID_ATTR_UNDERSCORE;
attr |= GRID_ATTR_UNDERSCORE;
else if (end == 5 && strncasecmp(str, "blink", end) == 0)
ch |= GRID_ATTR_BLINK;
attr |= GRID_ATTR_BLINK;
else if (end == 7 && strncasecmp(str, "reverse", end) == 0)
ch |= GRID_ATTR_REVERSE;
attr |= GRID_ATTR_REVERSE;
else if (end == 6 && strncasecmp(str, "hidden", end) == 0)
ch |= GRID_ATTR_HIDDEN;
attr |= GRID_ATTR_HIDDEN;
else if (end == 7 && strncasecmp(str, "italics", end) == 0)
ch |= GRID_ATTR_ITALICS;
attr |= GRID_ATTR_ITALICS;
else
return (-1);
str += end + strspn(str + end, delimiters);
} while (*str != '\0');
return (ch);
return (attr);
}

View File

@@ -1,99 +0,0 @@
/* $Id: buffer-poll.c,v 1.10 2008-09-09 22:16:36 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 <errno.h>
#include <unistd.h>
#include "tmux.h"
/* Set up pollfd for buffers. */
void
buffer_set(
struct pollfd *pfd, int fd, unused struct buffer *in, struct buffer *out)
{
pfd->fd = fd;
pfd->events = POLLIN;
if (BUFFER_USED(out) > 0)
pfd->events |= POLLOUT;
}
/* Fill buffers from socket based on poll results. */
int
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
{
ssize_t n;
#if 0
log_debug("buffer_poll (%ld): fd=%d, revents=%d; out=%zu in=%zu",
(long) getpid(),
pfd->fd, pfd->revents, BUFFER_USED(out), BUFFER_USED(in));
#endif
#ifndef BROKEN_POLL
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
return (-1);
#endif
if (pfd->revents & POLLIN) {
buffer_ensure(in, BUFSIZ);
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
#if 0
log_debug("buffer_poll: fd=%d, read=%zd", pfd->fd, n);
#endif
if (n == 0)
return (-1);
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
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));
#if 0
log_debug("buffer_poll: fd=%d, write=%zd", pfd->fd, n);
#endif
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
return (-1);
} else
buffer_remove(out, n);
}
return (0);
}
/* Flush buffer output to socket. */
void
buffer_flush(int fd, struct buffer *in, struct buffer *out)
{
struct pollfd pfd;
while (BUFFER_USED(out) > 0) {
buffer_set(&pfd, fd, in, out);
if (poll(&pfd, 1, INFTIM) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
if (buffer_poll(&pfd, in, out) != 0)
break;
}
}

227
buffer.c
View File

@@ -1,227 +0,0 @@
/* $Id: buffer.c,v 1.5 2008-08-07 20:20:52 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 <string.h>
#include "tmux.h"
/* Create a buffer. */
struct buffer *
buffer_create(size_t size)
{
struct buffer *b;
if (size == 0)
fatalx("zero size");
b = xcalloc(1, sizeof *b);
b->base = xmalloc(size);
b->space = size;
return (b);
}
/* Destroy a buffer. */
void
buffer_destroy(struct buffer *b)
{
xfree(b->base);
xfree(b);
}
/* Empty a buffer. */
void
buffer_clear(struct buffer *b)
{
b->size = 0;
b->off = 0;
}
/* Ensure free space for size in buffer. */
void
buffer_ensure(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (BUFFER_FREE(b) >= size)
return;
if (b->off > 0) {
if (b->size > 0)
memmove(b->base, b->base + b->off, b->size);
b->off = 0;
}
if (SIZE_MAX - b->size < size)
fatalx("size too big");
while (b->space < b->size + size) {
b->base = xrealloc(b->base, 2, b->space);
b->space *= 2;
}
}
/* Adjust buffer after data appended. */
void
buffer_add(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->space - b->size)
fatalx("overflow");
b->size += size;
}
/* Reverse buffer add. */
void
buffer_reverse_add(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
b->size -= size;
}
/* Adjust buffer after data removed. */
void
buffer_remove(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
b->size -= size;
b->off += size;
}
/* Reverse buffer remove. */
void
buffer_reverse_remove(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->off)
fatalx("overflow");
b->size += size;
b->off -= size;
}
/* Insert a section into the buffer. */
void
buffer_insert_range(struct buffer *b, size_t base, size_t size)
{
if (size == 0)
fatalx("zero size");
if (base > b->size)
fatalx("range outside buffer");
buffer_ensure(b, size);
memmove(b->base + b->off + base + size,
b->base + b->off + base, b->size - base);
b->size += size;
}
/* Delete a section from the buffer. */
void
buffer_delete_range(struct buffer *b, size_t base, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("size too big");
if (base + size > b->size)
fatalx("range outside buffer");
memmove(b->base + b->off + base,
b->base + b->off + base + size, b->size - base - size);
b->size -= size;
}
/* Copy data into a buffer. */
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);
}
/* Copy data out of a buffer. */
void
buffer_read(struct buffer *b, void *data, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
memcpy(data, BUFFER_OUT(b), size);
buffer_remove(b, size);
}
/* Store an 8-bit value. */
void
buffer_write8(struct buffer *b, uint8_t n)
{
buffer_ensure(b, 1);
BUFFER_IN(b)[0] = n;
buffer_add(b, 1);
}
/* Store a 16-bit value. */
void
buffer_write16(struct buffer *b, uint16_t n)
{
buffer_ensure(b, 2);
BUFFER_IN(b)[0] = n & 0xff;
BUFFER_IN(b)[1] = n >> 8;
buffer_add(b, 2);
}
/* Extract an 8-bit value. */
uint8_t
buffer_read8(struct buffer *b)
{
uint8_t n;
n = BUFFER_OUT(b)[0];
buffer_remove(b, 1);
return (n);
}
/* Extract a 16-bit value. */
uint16_t
buffer_read16(struct buffer *b)
{
uint16_t n;
n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8);
buffer_remove(b, 2);
return (n);
}

76
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.15 2009-03-31 22:23:43 nicm Exp $ */
/* $Id: cfg.c,v 1.27 2010-06-06 00:04:18 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -17,6 +17,7 @@
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
@@ -29,17 +30,20 @@
* argv array and executed as a command.
*/
char *cfg_string(FILE *, char, int);
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause;
char *cfg_cause;
int cfg_finished;
struct causelist cfg_causes = ARRAY_INITIALIZER;
/* ARGSUSED */
void printflike2
cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
{
}
/* ARGSUSED */
void printflike2
cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
{
@@ -50,19 +54,36 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
va_end(ap);
}
int
load_cfg(const char *path, char **cause)
void printflike2
cfg_add_cause(struct causelist *causes, const char *fmt, ...)
{
FILE *f;
char *cause;
va_list ap;
va_start(ap, fmt);
xvasprintf(&cause, fmt, ap);
va_end(ap);
ARRAY_ADD(causes, cause);
}
/*
* Load configuration file. Returns -1 for an error with a list of messages in
* causes. Note that causes must be initialised by the caller!
*/
int
load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
{
FILE *f;
u_int n;
char *buf, *line, *ptr;
char *buf, *line, *cause;
size_t len;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
if ((f = fopen(path, "rb")) == NULL) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (1);
cfg_add_cause(causes, "%s: %s", path, strerror(errno));
return (-1);
}
n = 0;
@@ -78,44 +99,45 @@ load_cfg(const char *path, char **cause)
}
n++;
if (cmd_string_parse(buf, &cmdlist, cause) != 0) {
if (*cause == NULL)
if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
if (cause == NULL)
continue;
goto error;
cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
xfree(cause);
continue;
}
if (cmdlist == NULL)
continue;
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);
if (cfg_cause != NULL) {
*cause = cfg_cause;
goto error;
cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause);
xfree(cfg_cause);
continue;
}
}
if (line != NULL)
xfree(line);
fclose(f);
if (ARRAY_LENGTH(causes) != 0)
return (-1);
return (0);
error:
fclose(f);
xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);
xfree(*cause);
*cause = ptr;
return (1);
}

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.18 2009-01-21 22:47:31 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 - 1)
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);
}

606
client.c
View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.46 2009-03-31 22:20:42 nicm Exp $ */
/* $Id: client.c,v 1.100 2010-10-24 19:54:41 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -17,212 +17,482 @@
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <errno.h>
#include <event.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "tmux.h"
void client_handle_winch(struct client_ctx *);
struct imsgbuf client_ibuf;
struct event client_event;
const char *client_exitmsg;
int client_exitval;
int client_attached;
int client_connect(char *, int);
void client_send_identify(int);
void client_send_environ(void);
void client_write_server(enum msgtype, void *, size_t);
void client_update_event(void);
void client_signal(int, short, void *);
void client_callback(int, short, void *);
int client_dispatch_attached(void);
int client_dispatch_wait(void *);
/* Connect client to server. */
int
client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
client_connect(char *path, int start_server)
{
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;
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;
}
struct sockaddr_un sa;
size_t size;
int fd, mode;
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
if (size >= sizeof sa.sun_path) {
errno = ENAMETOOLONG;
goto not_found;
return (-1);
}
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)
goto not_found;
if ((cctx->srv_fd = server_start(path)) == -1)
goto start_failed;
goto server_started;
}
goto not_found;
}
server_started:
if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
cctx->srv_in = buffer_create(BUFSIZ);
cctx->srv_out = buffer_create(BUFSIZ);
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 ((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);
start_failed:
log_warnx("server failed to start");
return (1);
not_found:
log_warn("server not found");
return (1);
}
int
client_main(struct client_ctx *cctx)
{
struct pollfd pfd;
char *error;
int xtimeout; /* Yay for ncurses namespace! */
siginit();
logfile("client");
#ifndef NO_SETPROCTITLE
setproctitle("client");
#endif
error = NULL;
xtimeout = INFTIM;
while (!sigterm) {
if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG);
sigchld = 0;
}
if (sigwinch)
client_handle_winch(cctx);
if (sigcont) {
siginit();
client_write_server(cctx, MSG_WAKEUP, NULL, 0);
sigcont = 0;
}
switch (client_msg_dispatch(cctx, &error)) {
case -1:
goto out;
case 0:
/* May be more in buffer, don't let poll block. */
xtimeout = 0;
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
if (!start_server)
goto failed;
switch (errno) {
case ECONNREFUSED:
if (unlink(path) != 0)
goto failed;
/* FALLTHROUGH */
case ENOENT:
if ((fd = server_start()) == -1)
goto failed;
break;
default:
/* Out of data, poll may block. */
xtimeout = INFTIM;
goto failed;
}
}
if ((mode = fcntl(fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
return (fd);
failed:
close(fd);
return (-1);
}
/* Client main loop. */
int
client_main(int argc, char **argv, int flags)
{
struct cmd *cmd;
struct cmd_list *cmdlist;
struct msg_command_data cmddata;
int cmdflags, fd;
enum msgtype msg;
char *cause;
/* Set up the initial command. */
cmdflags = 0;
if (shell_cmd != NULL) {
msg = MSG_SHELL;
cmdflags = CMD_STARTSERVER;
} else if (argc == 0) {
msg = MSG_COMMAND;
cmdflags = CMD_STARTSERVER|CMD_SENDENVIRON|CMD_CANTNEST;
} else {
msg = MSG_COMMAND;
/*
* It sucks parsing the command string twice (in client and
* later in server) but it is necessary to get the start server
* flag.
*/
if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
log_warnx("%s", cause);
return (1);
}
cmdflags &= ~CMD_STARTSERVER;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (cmd->entry->flags & CMD_STARTSERVER)
cmdflags |= CMD_STARTSERVER;
if (cmd->entry->flags & CMD_SENDENVIRON)
cmdflags |= CMD_SENDENVIRON;
if (cmd->entry->flags & CMD_CANTNEST)
cmdflags |= CMD_CANTNEST;
}
cmd_list_free(cmdlist);
}
/*
* Check if this could be a nested session, if the command can't nest:
* if the socket path matches $TMUX, this is probably the same server.
*/
if (shell_cmd == NULL && environ_path != NULL &&
cmdflags & CMD_CANTNEST && strcmp(socket_path, environ_path) == 0) {
log_warnx("sessions should be nested with care. "
"unset $TMUX to force.");
return (1);
}
/* Initialise the client socket and start the server. */
fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
if (fd == -1) {
log_warn("failed to connect to server");
return (1);
}
/* Set process title, log and signals now this is the client. */
#ifdef HAVE_SETPROCTITLE
setproctitle("client (%s)", socket_path);
#endif
logfile("client");
/* Create imsg. */
imsg_init(&client_ibuf, fd);
event_set(&client_event, fd, EV_READ, client_callback, shell_cmd);
/* Establish signal handlers. */
set_signals(client_signal);
/* Send initial environment. */
if (cmdflags & CMD_SENDENVIRON)
client_send_environ();
client_send_identify(flags);
/* Send first command. */
if (msg == MSG_COMMAND) {
/* Fill in command line arguments. */
cmddata.pid = environ_pid;
cmddata.idx = environ_idx;
/* Prepare command for server. */
cmddata.argc = argc;
if (cmd_pack_argv(
argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
log_warnx("command too long");
return (1);
}
client_write_server(msg, &cmddata, sizeof cmddata);
} else if (msg == MSG_SHELL)
client_write_server(msg, NULL, 0);
/* Set the event and dispatch. */
client_update_event();
event_dispatch();
/* Print the exit message, if any, and exit. */
if (client_attached && client_exitmsg != NULL && !login_shell)
printf("[%s]\n", client_exitmsg);
return (client_exitval);
}
/* Send identify message to server with the file descriptors. */
void
client_send_identify(int flags)
{
struct msg_identify_data data;
char *term;
int fd;
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);
if ((fd = dup(STDOUT_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf,
MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 0);
if ((fd = dup(STDERR_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf,
MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 0);
}
/* Forward entire environment to server. */
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);
}
}
/* Write a message to the server without a file descriptor. */
void
client_write_server(enum msgtype type, void *buf, size_t len)
{
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
/* Update client event based on whether it needs to read or read and write. */
void
client_update_event(void)
{
short events;
event_del(&client_event);
events = EV_READ;
if (client_ibuf.w.queued > 0)
events |= EV_WRITE;
event_set(
&client_event, client_ibuf.fd, events, client_callback, shell_cmd);
event_add(&client_event, NULL);
}
/* Callback to handle signals in the client. */
/* ARGSUSED */
void
client_signal(int sig, unused short events, unused void *data)
{
struct sigaction sigact;
int status;
if (!client_attached) {
switch (sig) {
case SIGCHLD:
waitpid(WAIT_ANY, &status, WNOHANG);
break;
case SIGTERM:
event_loopexit(NULL);
break;
}
} else {
switch (sig) {
case SIGHUP:
client_exitmsg = "lost tty";
client_exitval = 1;
client_write_server(MSG_EXITING, NULL, 0);
break;
case SIGTERM:
client_exitmsg = "terminated";
client_exitval = 1;
client_write_server(MSG_EXITING, NULL, 0);
break;
case SIGWINCH:
client_write_server(MSG_RESIZE, NULL, 0);
break;
case SIGCONT:
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_IGN;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
client_write_server(MSG_WAKEUP, NULL, 0);
break;
}
}
pfd.fd = cctx->srv_fd;
pfd.events = POLLIN;
if (BUFFER_USED(cctx->srv_out) > 0)
pfd.events |= POLLOUT;
client_update_event();
}
if (poll(&pfd, 1, xtimeout) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
/* Callback for client imsg read events. */
/* ARGSUSED */
void
client_callback(unused int fd, short events, void *data)
{
ssize_t n;
int retval;
if (events & EV_READ) {
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
goto lost_server;
if (client_attached)
retval = client_dispatch_attached();
else
retval = client_dispatch_wait(data);
if (retval != 0) {
event_loopexit(NULL);
return;
}
}
if (events & EV_WRITE) {
if (msgbuf_write(&client_ibuf.w) < 0)
goto lost_server;
}
client_update_event();
return;
lost_server:
client_exitmsg = "lost server";
client_exitval = 1;
event_loopexit(NULL);
}
/* Dispatch imsgs when in wait state (before MSG_READY). */
int
client_dispatch_wait(void *data)
{
struct imsg imsg;
ssize_t n, datalen;
struct msg_shell_data shelldata;
struct msg_exit_data exitdata;
const char *shellcmd = data;
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
fatalx("imsg_read failed");
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_EXIT:
case MSG_SHUTDOWN:
if (datalen != sizeof exitdata) {
if (datalen != 0)
fatalx("bad MSG_EXIT size");
} else {
memcpy(&exitdata, imsg.data, sizeof exitdata);
client_exitval = exitdata.retcode;
}
imsg_free(&imsg);
return (-1);
case MSG_READY:
if (datalen != 0)
fatalx("bad MSG_READY size");
client_attached = 1;
break;
case MSG_VERSION:
if (datalen != 0)
fatalx("bad MSG_VERSION size");
log_warnx("protocol version mismatch (client %u, "
"server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
client_exitval = 1;
imsg_free(&imsg);
return (-1);
case MSG_SHELL:
if (datalen != sizeof shelldata)
fatalx("bad MSG_SHELL size");
memcpy(&shelldata, imsg.data, sizeof shelldata);
shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
clear_signals(0);
shell_exec(shelldata.shell, shellcmd);
/* NOTREACHED */
default:
fatalx("unexpected message");
}
if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
goto server_dead;
imsg_free(&imsg);
}
out:
if (sigterm) {
printf("[terminated]\n");
return (1);
}
if (cctx->flags & CCTX_SHUTDOWN) {
printf("[server exited]\n");
return (0);
}
if (cctx->flags & CCTX_EXIT) {
printf("[exited]\n");
return (0);
}
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)
/* Dispatch imsgs in attached state (after MSG_READY). */
/* ARGSUSED */
int
client_dispatch_attached(void)
{
struct msg_resize_data data;
struct winsize ws;
struct imsg imsg;
struct msg_lock_data lockdata;
struct sigaction sigact;
ssize_t n, datalen;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl failed");
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;
data.sx = ws.ws_col;
data.sy = ws.ws_row;
client_write_server(cctx, MSG_RESIZE, &data, sizeof data);
log_debug("client got %d", imsg.hdr.type);
switch (imsg.hdr.type) {
case MSG_DETACH:
if (datalen != 0)
fatalx("bad MSG_DETACH size");
sigwinch = 0;
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "detached";
break;
case MSG_EXIT:
if (datalen != 0 &&
datalen != sizeof (struct msg_exit_data))
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";
client_exitval = 1;
break;
case MSG_SUSPEND:
if (datalen != 0)
fatalx("bad MSG_SUSPEND size");
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
break;
case MSG_LOCK:
if (datalen != sizeof lockdata)
fatalx("bad MSG_LOCK size");
memcpy(&lockdata, imsg.data, sizeof lockdata);
lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
system(lockdata.cmd);
client_write_server(MSG_UNLOCK, NULL, 0);
break;
default:
fatalx("unexpected message");
}
imsg_free(&imsg);
}
}

28
clock.c
View File

@@ -1,4 +1,4 @@
/* $Id: clock.c,v 1.3 2009-03-27 16:59:57 nicm Exp $ */
/* $Id: clock.c,v 1.9 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -97,7 +97,7 @@ const char clock_table[14][5][5] = {
};
void
clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
clock_draw(struct screen_write_ctx *ctx, int colour, int style)
{
struct screen *s = ctx->s;
struct grid_cell gc;
@@ -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,25 +119,28 @@ 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;
}
}
x = (screen_size_x(s) / 2) - 3 * strlen(tim);
y = (screen_size_y(s) / 2) - 3;
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_bg(&gc, colour);
for (ptr = tim; *ptr != '\0'; ptr++) {
if (*ptr >= '0' && *ptr <= '9')
idx = *ptr - '0';
else if (*ptr == ':')
else if (*ptr == ':')
idx = 10;
else if (*ptr == 'A')
else if (*ptr == 'A')
idx = 11;
else if (*ptr == 'P')
else if (*ptr == 'P')
idx = 12;
else if (*ptr == 'M')
else if (*ptr == 'M')
idx = 13;
else {
x += 6;
@@ -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.24 2009-01-23 16:59:14 nicm Exp $ */
/* $Id: cmd-attach-session.c,v 1.37 2010-12-22 15:36:44 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,13 +28,11 @@ 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,
"[-dr] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, "dr",
cmd_target_init,
cmd_target_parse,
cmd_attach_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,37 +42,69 @@ 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) {
if (RB_EMPTY(&sessions)) {
ctx->error(ctx, "no sessions");
return (-1);
}
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 (cmd_check_flag(data->chflags, '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 (cmd_check_flag(data->chflags, 'r'))
ctx->cmdclient->flags |= CLIENT_READONLY;
if (cmd_check_flag(data->chflags, 'd'))
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
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);
server_update_socket();
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.20 2009-03-28 14:08:09 nicm Exp $ */
/* $Id: cmd-bind-key.c,v 1.29 2010-07-02 02:43:01 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -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, "",
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,18 +58,31 @@ 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;
default:
case 't':
if (data->tablename == NULL)
data->tablename = xstrdup(optarg);
break;
default:
goto usage;
}
}
@@ -78,11 +95,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,30 +126,46 @@ 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 */
data->cmdlist->references++;
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;
cmd = mode_key_fromstring(mtab->cmdstr, data->modecmd);
if (cmd == MODEKEY_NONE) {
ctx->error(ctx, "unknown command: %s", data->modecmd);
return (-1);
}
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->cmdlist = cmd_list_recv(b);
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 +175,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);
}
@@ -147,8 +192,17 @@ cmd_bind_key_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->command_key)
off += xsnprintf(buf + off, len - off, " -c");
if (off < len && !(data->key & KEYC_PREFIX))
off += xsnprintf(buf + off, len - off, " -n");
if (off < len && data->can_repeat)
off += xsnprintf(buf + off, len - off, " -r");
if (off < len && data->tablename != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->tablename);
if (off < len) {
skey = key_string_lookup_key(data->key);
skey = key_string_lookup_key(data->key & ~KEYC_PREFIX);
off += xsnprintf(buf + off, len - off, " %s ", skey);
}
if (off < len)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.1 2009-03-07 09:29:54 nicm Exp $ */
/* $Id: cmd-break-pane.c,v 1.11 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -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, "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;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
int base_idx;
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);
}
window_fit_panes(wl->window);
layout_close_pane(wp);
w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
window_fit_panes(w);
w->name = default_window_name(w);
w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
w->name = default_window_name(w);
layout_init(w);
wl = session_attach(s, w, -1, &cause); /* can't fail */
base_idx = options_get_number(&s->options, "base-index");
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
if (!cmd_check_flag(data->chflags, 'd'))
session_select(s, wl->idx);
if (!(data->flags & CMD_DFLAG))
session_select(s, wl->idx);
server_redraw_session(s);
server_status_session_group(s);
return (0);
}

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

@@ -0,0 +1,83 @@
/* $Id: cmd-capture-pane.c,v 1.3 2010-01-22 17:29:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/*
* Write the entire contents of a pane to a buffer.
*/
int cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_capture_pane_entry = {
"capture-pane", "capturep",
CMD_BUFFER_PANE_USAGE,
0, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_capture_pane_exec,
cmd_buffer_free,
cmd_buffer_print
};
int
cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct window_pane *wp;
char *buf, *line;
struct screen *s;
struct session *sess;
u_int i, limit;
size_t len, linelen;
if (cmd_find_pane(ctx, data->target, &sess, &wp) == NULL)
return (-1);
s = &wp->base;
buf = NULL;
len = 0;
for (i = 0; i < screen_size_y(s); i++) {
line = grid_view_string_cells(s->grid, 0, i, screen_size_x(s));
linelen = strlen(line);
buf = xrealloc(buf, 1, len + linelen + 1);
memcpy(buf + len, line, linelen);
len += linelen;
buf[len++] = '\n';
xfree(line);
}
limit = options_get_number(&sess->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&sess->buffers, buf, len, limit);
return (0);
}
if (paste_replace(&sess->buffers, data->buffer, buf, len) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf);
return (-1);
}
return (0);
}

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

@@ -0,0 +1,146 @@
/* $Id: cmd-choose-buffer.c,v 1.1 2010-06-22 23:35:20 tcunha Exp $ */
/*
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <ctype.h>
#include "tmux.h"
/*
* Enter choice mode to choose a buffer.
*/
int cmd_choose_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_buffer_callback(void *, int);
void cmd_choose_buffer_free(void *);
const struct cmd_entry cmd_choose_buffer_entry = {
"choose-buffer", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, "",
cmd_target_init,
cmd_target_parse,
cmd_choose_buffer_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_choose_buffer_data {
struct client *client;
char *template;
};
int
cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_choose_buffer_data *cdata;
struct session *s;
struct winlink *wl;
struct paste_buffer *pb;
u_int idx;
char *tmp;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
s = ctx->curclient->session;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (paste_get_top(&s->buffers) == NULL)
return (0);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
idx = 0;
while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
tmp = paste_print(pb, 50);
window_choose_add(wl->window->active, idx - 1,
"%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp);
xfree(tmp);
}
cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL)
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("paste-buffer -b '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
0, cmd_choose_buffer_callback, cmd_choose_buffer_free, cdata);
return (0);
}
void
cmd_choose_buffer_callback(void *data, int idx)
{
struct cmd_choose_buffer_data *cdata = data;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause, tmp[16];
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
xsnprintf(tmp, sizeof tmp, "%u", idx);
template = cmd_template_replace(cdata->template, tmp, 1);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(cdata->client, "%s", cause);
xfree(cause);
}
xfree(template);
return;
}
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_buffer_free(void *data)
{
struct cmd_choose_buffer_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata);
}

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

@@ -0,0 +1,152 @@
/* $Id: cmd-choose-client.c,v 1.4 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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, "",
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.6 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-choose-session.c,v 1.17 2010-12-22 15:36:44 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, "",
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;
u_int i, idx, cur;
struct session_group *sg;
u_int idx, sgidx, cur;
char tmp[64];
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
@@ -61,30 +65,40 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
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(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
RB_FOREACH(s, sessions, &sessions) {
if (s == ctx->curclient->session)
cur = idx;
idx++;
window_choose_add(wl->window->active, i,
"%s: %u windows [%ux%u]%s", s->name,
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
else {
sgidx = session_group_index(sg);
xsnprintf(tmp, sizeof tmp, " (group %u)", sgidx);
}
window_choose_add(wl->window->active, s->idx,
"%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 +107,51 @@ 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;
s = session_find_by_index(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.7 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-choose-window.c,v 1.24 2010-12-22 15:28:50 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, "",
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");
@@ -63,7 +68,7 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
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);
@@ -75,32 +80,102 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx;
idx++;
flag = ' ';
if (wm->flags & WINLINK_ACTIVITY)
flag = '#';
else if (wm->flags & WINLINK_BELL)
flag = '!';
else if (wm->flags & WINLINK_CONTENT)
flag = '+';
else if (wm->flags & WINLINK_SILENCE)
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] (%u panes)", wm->idx, w->name,
w->sx, w->sy, window_count_panes(w));
wm->idx, "%3d: %s%c [%ux%u] (%u panes%s)%s%s%s",
wm->idx, w->name, flag, w->sx, w->sy, window_count_panes(w),
w->active->fd == -1 ? ", dead" : "",
left, title, right);
}
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);
return (0);
}
void
cmd_choose_window_callback(void *data, int idx)
{
struct cmd_choose_window_data *cdata = data;
struct session *s;
struct session *s = cdata->session;
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 (!session_alive(s))
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
xasprintf(&target, "%s:%d", s->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: util.c,v 1.1 2009-01-18 17:20:52 nicm Exp $ */
/* $Id: cmd-clear-history.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,33 +20,36 @@
#include "tmux.h"
/* Return a section of a string around a point. */
char *
section_string(char *buf, size_t len, size_t sectoff, size_t sectlen)
/*
* Clear pane history.
*/
int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
CMD_TARGET_PANE_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_clear_history_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{
char *s;
size_t first, last;
struct cmd_target_data *data = self->data;
struct window_pane *wp;
struct grid *gd;
if (len <= sectlen) {
first = 0;
last = len;
} else if (sectoff < sectlen / 2) {
first = 0;
last = sectlen;
} else if (sectoff + sectlen / 2 > len) {
last = len;
first = last - sectlen;
} else {
first = sectoff - sectlen / 2;
last = first + sectlen;
}
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
gd = wp->base.grid;
if (last - first > 3 && first != 0)
first += 3;
if (last - first > 3 && last != len)
last -= 3;
grid_move_lines(gd, 0, gd->hsize, gd->sy);
gd->hsize = 0;
xasprintf(&s, "%s%.*s%s", first == 0 ? "" : "...",
(int) (last - first), buf + first, last == len ? "" : "...");
return (s);
return (0);
}

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.7 2009-11-14 17:56:39 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, "",
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.28 2010-05-14 14:33:39 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,57 +27,115 @@
* 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, "",
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;
case '\'':
data->template = xstrdup("select-window -t ':%%'");
data->prompts = xstrdup("index");
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 +145,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 +252,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);
}

147
cmd-confirm-before.c Normal file
View File

@@ -0,0 +1,147 @@
/* $Id: cmd-confirm-before.c,v 1.12 2009-11-14 17:56:39 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 <ctype.h>
#include <string.h>
#include "tmux.h"
/*
* Asks for confirmation before executing a command.
*/
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 *);
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_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,
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)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case '&':
data->arg = xstrdup("kill-window");
break;
case 'x':
data->arg = xstrdup("kill-pane");
break;
}
}
int
cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_confirm_before_data *cdata;
struct client *c;
char *buf, *cmd, *ptr;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
ptr = xstrdup(data->arg);
if ((cmd = strtok(ptr, " \t")) == NULL)
cmd = ptr;
xasprintf(&buf, "Confirm '%s'? (y/n) ", cmd);
xfree(ptr);
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg);
cdata->c = c;
status_prompt_set(cdata->c, buf,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
PROMPT_SINGLE);
xfree(buf);
return (1);
}
int
cmd_confirm_before_callback(void *data, const char *s)
{
struct cmd_confirm_before_data *cdata = data;
struct client *c = cdata->c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *cause;
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, "%s", cause);
xfree(cause);
}
return (0);
}
ctx.msgdata = NULL;
ctx.curclient = c;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
return (0);
}
void
cmd_confirm_before_free(void *data)
{
struct cmd_confirm_before_data *cdata = data;
if (cdata->cmd != NULL)
xfree(cdata->cmd);
xfree(cdata);
}

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.7 2009-11-28 14:50:36 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,16 +43,15 @@ 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, "",
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
};
/* ARGSUSED */
void
cmd_copy_buffer_init(struct cmd *self, unused int arg)
{
@@ -71,7 +71,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 +126,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.16 2009-02-25 21:56:46 nicm Exp $ */
/* $Id: cmd-copy-mode.c,v 1.28 2010-08-11 22:18:28 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,33 +24,49 @@
* 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, "u",
cmd_copy_mode_init,
cmd_target_parse,
cmd_copy_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
NULL
cmd_target_print
};
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:
cmd_set_flag(&data->chflags, '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);
window_pane_set_mode(wl->window->active, &window_copy_mode);
if (data->flags & CMD_UFLAG)
window_copy_pageup(wl->window->active);
if (window_pane_set_mode(wp, &window_copy_mode) != 0)
return (0);
window_copy_init_from_pane(wp);
if (wp->mode == &window_copy_mode && cmd_check_flag(data->chflags, 'u'))
window_copy_pageup(wp);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-delete-buffer.c,v 1.4 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-delete-buffer.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,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, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_delete_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
@@ -56,6 +54,6 @@ cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "no buffer %d", data->buffer);
return (-1);
}
return (0);
}

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.11 2010-02-08 18:27:34 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,
CMD_READONLY, "",
cmd_target_init,
cmd_target_parse,
cmd_detach_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

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

@@ -0,0 +1,66 @@
/* $Id: cmd-display-message.c,v 1.7 2009-11-28 14:39:53 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",
"[-p] " CMD_TARGET_CLIENT_USAGE " [message]",
CMD_ARG01, "p",
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, NULL, template, time(NULL), 0);
if (cmd_check_flag(data->chflags, 'p'))
ctx->print(ctx, "%s", msg);
else
status_message_set(c, "%s", msg);
xfree(msg);
return (0);
}

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

@@ -0,0 +1,52 @@
/* $Id: cmd-display-panes.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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, "",
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-find-window.c,v 1.6 2009-03-29 11:18:28 nicm Exp $ */
/* $Id: cmd-find-window.c,v 1.15 2010-12-22 15:28:50 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <fnmatch.h>
#include <string.h>
#include "tmux.h"
@@ -29,23 +30,21 @@
int cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_find_window_callback(void *, int);
char *cmd_find_window_search(struct window_pane *, const char *);
void cmd_find_window_free(void *);
const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw",
CMD_TARGET_WINDOW_USAGE " match-string",
CMD_ARG1,
CMD_ARG1, "",
cmd_target_init,
cmd_target_parse,
cmd_find_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
struct cmd_find_window_data {
u_int session;
struct session *session;
};
int
@@ -59,8 +58,8 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_pane *wp;
ARRAY_DECL(, u_int) list_idx;
ARRAY_DECL(, char *) list_ctx;
char *sres, *sctx;
u_int i;
char *sres, *sctx, *searchstr;
u_int i, line;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
@@ -70,37 +69,41 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
ARRAY_INIT(&list_idx);
ARRAY_INIT(&list_ctx);
xasprintf(&searchstr, "*%s*", data->arg);
RB_FOREACH(wm, winlinks, &s->windows) {
i = 0;
TAILQ_FOREACH(wp, &wm->window->panes, entry) {
i++;
if (strstr(wm->window->name, data->arg) != NULL)
if (fnmatch(searchstr, wm->window->name, 0) == 0)
sctx = xstrdup("");
else {
sres = cmd_find_window_search(wp, data->arg);
sres = window_pane_search(wp, data->arg, &line);
if (sres == NULL &&
strstr(wp->base.title, data->arg) == NULL)
fnmatch(searchstr, wp->base.title, 0) != 0)
continue;
if (sres == NULL) {
xasprintf(&sctx,
"pane %u title: \"%s\"", i - 1,
wp->base.title);
} else {
xasprintf(&sctx, "\"%s\"", sres);
xasprintf(&sctx,
"pane %u line %u: \"%s\"", i - 1,
line + 1, sres);
xfree(sres);
}
}
ARRAY_ADD(&list_idx, wm->idx);
ARRAY_ADD(&list_ctx, sctx);
ARRAY_ADD(&list_ctx, sctx);
}
}
xfree(searchstr);
if (ARRAY_LENGTH(&list_idx) == 0) {
ctx->error(ctx, "no windows matching: %s", data->arg);
@@ -123,7 +126,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wm = winlink_find_by_index(
&s->windows, ARRAY_ITEM(&list_idx, i));
w = wm->window;
sctx = ARRAY_ITEM(&list_ctx, i);
window_choose_add(wl->window->active,
wm->idx, "%3d: %s [%ux%u] (%u panes) %s", wm->idx, w->name,
@@ -132,11 +135,11 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
cdata = xmalloc(sizeof *cdata);
if (session_index(s, &cdata->session) != 0)
fatalx("session not found");
cdata->session = s;
cdata->session->references++;
window_choose_ready(
wl->window->active, 0, cmd_find_window_callback, cdata);
window_choose_ready(wl->window->active,
0, cmd_find_window_callback, cmd_find_window_free, cdata);
out:
ARRAY_FREE(&list_idx);
@@ -149,56 +152,24 @@ void
cmd_find_window_callback(void *data, int idx)
{
struct cmd_find_window_data *cdata = data;
struct session *s;
struct session *s = cdata->session;
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);
if (idx == -1)
return;
if (!session_alive(s))
return;
if (session_select(s, idx) == 0) {
server_redraw_session(s);
recalculate_sizes();
}
}
void
cmd_find_window_free(void *data)
{
struct cmd_find_window_data *cdata = data;
cdata->session->references--;
xfree(cdata);
}
char *
cmd_find_window_search(struct window_pane *wp, const char *searchstr)
{
const struct grid_cell *gc;
const struct grid_utf8 *gu;
char *buf, *s;
size_t off;
u_int i, j, k;
buf = xmalloc(1);
for (j = 0; j < screen_size_y(&wp->base); j++) {
off = 0;
for (i = 0; i < screen_size_x(&wp->base); i++) {
gc = grid_view_peek_cell(wp->base.grid, i, j);
if (gc->flags & GRID_FLAG_UTF8) {
gu = grid_view_peek_utf8(wp->base.grid, i, j);
buf = xrealloc(buf, 1, off + 8);
for (k = 0; k < UTF8_SIZE; k++) {
if (gu->data[k] == 0xff)
break;
buf[off++] = gu->data[k];
}
} else {
buf = xrealloc(buf, 1, off + 1);
buf[off++] = gc->data;
}
}
while (off > 0 && buf[off - 1] == ' ')
off--;
buf[off] = '\0';
if ((s = strstr(buf, searchstr)) != NULL) {
s = section_string(buf, off, s - buf, 40);
xfree(buf);
return (s);
}
}
xfree(buf);
return (NULL);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.25 2009-04-03 17:31:44 nicm Exp $ */
/* $Id: cmd-generic.c,v 1.38 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,101 +23,93 @@
#include "tmux.h"
#define CMD_FLAGS "adDgkuU"
#define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_UPPERDFLAG|CMD_GFLAG|CMD_KFLAG| \
CMD_UFLAG|CMD_UPPERUFLAG)
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 *, const char *);
int cmd_parse_flags(int, const char *, uint64_t *);
size_t cmd_print_flags(char *, size_t, size_t, uint64_t);
int cmd_fill_argument(int, char **, char **, int, char **);
size_t
cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
{
if (strchr(arg, ' ' ) != NULL)
if (strchr(arg, ' ') != NULL)
return (xsnprintf(buf, len, "%s\"%s\"", prefix, arg));
return (xsnprintf(buf, len, "%s%s", prefix, arg));
}
/* Append two flag strings together and call getopt. */
int
cmd_do_flags(int opt, int iflags, int *oflags)
cmd_getopt(int argc, char **argv, const char *flagstr, const char *chflagstr)
{
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_UPPERDFLAG) {
(*oflags) |= CMD_UPPERDFLAG;
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_UPPERUFLAG) {
(*oflags) |= CMD_UPPERUFLAG;
return (0);
}
return (-1);
}
return (1);
char tmp[BUFSIZ];
if (strlcpy(tmp, flagstr, sizeof tmp) >= sizeof tmp)
fatalx("strlcpy overflow");
if (strlcat(tmp, chflagstr, sizeof tmp) >= sizeof tmp)
fatalx("strlcat overflow");
return (getopt(argc, argv, tmp));
}
size_t
cmd_print_flags(char *buf, size_t len, size_t off, int flags)
/* Return if flag character is set. */
int
cmd_check_flag(uint64_t chflags, int flag)
{
if (flag >= 'A' && flag <= 'Z')
flag = 26 + flag - 'A';
else if (flag >= 'a' && flag <= 'z')
flag = flag - 'a';
else
return (0);
return ((chflags & (1ULL << flag)) != 0);
}
/* Set flag character. */
void
cmd_set_flag(uint64_t *chflags, int flag)
{
if (flag >= 'A' && flag <= 'Z')
flag = 26 + flag - 'A';
else if (flag >= 'a' && flag <= 'z')
flag = flag - 'a';
else
return;
(*chflags) |= (1ULL << flag);
}
/* If this option is expected, set it in chflags, otherwise return -1. */
int
cmd_parse_flags(int opt, const char *chflagstr, uint64_t *chflags)
{
if (strchr(chflagstr, opt) == NULL)
return (-1);
cmd_set_flag(chflags, opt);
return (0);
}
/* Print the flags present in chflags. */
size_t
cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags)
{
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_UPPERDFLAG)
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_UPPERUFLAG)
off += xsnprintf(buf + off, len - off, "U");
for (ch = 0; ch < 26; ch++) {
if (cmd_check_flag(chflags, 'a' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'a' + ch);
if (cmd_check_flag(chflags, '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,39 +126,55 @@ 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);
}
/* ARGSUSED */
void
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_parse_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
}
switch (opt) {
case 't':
if (data->target == NULL)
@@ -179,7 +187,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 +199,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 +208,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,42 +222,43 @@ 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)
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);
}
/* ARGSUSED */
void
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_parse_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
}
switch (opt) {
case 's':
if (data->src == NULL)
@@ -284,7 +275,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 +287,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 +298,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,45 +312,46 @@ 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)
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);
}
/* ARGSUSED */
void
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_parse_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
}
switch (opt) {
case 'b':
if (data->buffer == -1) {
@@ -402,7 +374,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 +387,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 +396,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 +410,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)
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.15 2009-11-14 17:56:39 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, "",
cmd_target_init,
cmd_target_parse,
cmd_has_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};

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

@@ -0,0 +1,119 @@
/* $Id: cmd-if-shell.c,v 1.10 2010-08-09 21:44:25 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, "",
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;
struct msg_exit_data exitdata;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
exitdata.retcode = ctx->cmdclient->retcode;
ctx->cmdclient->flags |= CLIENT_EXIT;
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
xfree(cdata->cmd);
xfree(cdata);
}

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

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.6 2009-04-01 21:10:08 nicm Exp $ */
/* $Id: cmd-kill-pane.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -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, "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;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
struct window_pane *loopwp, *nextwp, *wp;
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 (cmd_check_flag(data->chflags, '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.11 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,20 +32,19 @@ int cmd_kill_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_server_entry = {
"kill-server", NULL,
"",
0,
0, "",
NULL,
NULL,
cmd_kill_server_exec,
NULL,
NULL,
NULL,
NULL
};
/* ARGSUSED */
int
cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{
sigterm = 1;
kill(getpid(), SIGTERM);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-session.c,v 1.12 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-kill-session.c,v 1.18 2010-07-02 02:43:50 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,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, "",
cmd_target_init,
cmd_target_parse,
cmd_kill_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -47,21 +45,11 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct client *c;
u_int i;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c->session == s) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
}
}
recalculate_sizes();
server_destroy_session(s);
session_destroy(s);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-kill-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,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, "",
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,7 +1,7 @@
/* $Id: cmd-up-pane.c,v 1.7 2009-04-01 21:10:08 nicm Exp $ */
/* $Id: cmd-last-pane.c,v 1.1 2010-10-24 01:34:30 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,26 +21,24 @@
#include "tmux.h"
/*
* Move up a pane.
* Move to last pane.
*/
int cmd_up_pane_exec(struct cmd *, struct cmd_ctx *);
int cmd_last_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_up_pane_entry = {
"up-pane", "upp",
const struct cmd_entry cmd_last_pane_entry = {
"last-pane", "lastp",
CMD_TARGET_WINDOW_USAGE,
0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_up_pane_exec,
cmd_target_send,
cmd_target_recv,
cmd_last_pane_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_last_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
@@ -50,12 +48,11 @@ cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
w = wl->window;
do {
w->active = TAILQ_PREV(w->active, window_panes, entry);
if (w->active == NULL)
w->active = TAILQ_LAST(&w->panes, window_panes);
layout_refresh(w, 1);
} while (w->active->flags & PANE_HIDDEN);
if (w->last == NULL) {
ctx->error(ctx, "no last pane");
return (-1);
}
window_set_active_pane(w, w->last);
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.19 2009-11-14 17:56:39 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, "",
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.36 2009-11-14 17:56:39 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, "dk",
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 = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't link window: %s", cause);
xfree(cause);
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.16 2010-06-22 23:35:20 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, "",
cmd_target_init,
cmd_target_parse,
cmd_list_buffers_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -49,43 +47,17 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
struct paste_buffer *pb;
u_int idx;
char *tmp;
size_t size, in, out;
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] = '.';
}
ctx->print(ctx, "%d: %zu bytes: \"%s\"",
idx - 1, strlen(pb->data), tmp);
} else
ctx->print(ctx, "%d: %zu bytes", idx, strlen(pb->data));
}
if (tmp != NULL)
tmp = paste_print(pb, 50);
ctx->print(ctx,
"%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp);
xfree(tmp);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-clients.c,v 1.13 2009-02-11 17:50:32 nicm Exp $ */
/* $Id: cmd-list-clients.c,v 1.20 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,29 +32,34 @@ int cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc",
"",
0,
0, "",
NULL,
NULL,
cmd_list_clients_exec,
NULL,
NULL,
NULL,
NULL
};
/* ARGSUSED */
int
cmd_list_clients_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
struct client *c;
u_int i;
const char *s_utf8;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
ctx->print(ctx, "%s: %s [%ux%u %s]", c->tty.path,
c->session->name, c->tty.sx, c->tty.sy, c->tty.termname);
if (c->tty.flags & TTY_UTF8)
s_utf8 = " (utf8)";
else
s_utf8 = "";
ctx->print(ctx, "%s: %s [%ux%u %s]%s", c->tty.path,
c->session->name, c->tty.sx, c->tty.sy,
c->tty.termname, s_utf8);
}
return (0);

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.7 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,16 +29,15 @@ int cmd_list_commands_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm",
"",
0,
0, "",
NULL,
NULL,
cmd_list_commands_exec,
NULL,
NULL,
NULL,
NULL
};
/* ARGSUSED */
int
cmd_list_commands_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-keys.c,v 1.13 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-list-keys.c,v 1.25 2010-10-24 01:31:57 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,106 @@
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, "",
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];
size_t used;
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);
used = xsnprintf(tmp, sizeof tmp, "%*s: ", width, key);
if (used >= sizeof tmp)
continue;
if (!(bd->key & KEYC_PREFIX)) {
used = strlcat(tmp, "(no prefix) ", sizeof tmp);
if (used >= sizeof tmp)
continue;
}
if (bd->can_repeat) {
used = strlcat(tmp, "(repeat) ", sizeof tmp);
if (used >= sizeof tmp)
continue;
}
cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
ctx->print(ctx, "%s", 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.16 2009-01-27 23:35:44 nicm Exp $ */
/* $Id: cmd-list-panes.c,v 1.6 2010-12-06 21:56:32 nicm 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,55 +18,59 @@
#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, "",
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);
window_pane_set_mode(wl->window->active, &window_scroll_mode);
if (data->flags & CMD_UFLAG)
window_scroll_pageup(wl->window->active);
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]%s%s",
n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size,
wp == wp->window->active ? " (active)" : "",
wp->fd == -1 ? " (dead)" : "");
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.26 2010-12-22 15:36:44 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,36 +31,40 @@ int cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", "",
0,
0, "",
NULL,
NULL,
cmd_list_sessions_exec,
NULL,
NULL,
NULL,
NULL
};
/* ARGSUSED */
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 idx;
time_t t;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
RB_FOREACH(s, sessions, &sessions) {
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->tv.tv_sec;
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.33 2009-03-28 20:17:29 nicm Exp $ */
/* $Id: cmd-list-windows.c,v 1.44 2010-12-06 21:56:32 nicm 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, "",
cmd_target_init,
cmd_target_parse,
cmd_list_windows_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -47,40 +45,17 @@ 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;
char *layout;
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] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
}
layout = layout_dump(wl->window);
ctx->print(ctx, "%d: %s [%ux%u] [layout %s]%s",
wl->idx, wl->window->name, wl->window->sx, wl->window->sy,
layout, wl == s->curw ? " (active)" : "");
xfree(layout);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.3 2009-02-16 18:57:16 nicm Exp $ */
/* $Id: cmd-list.c,v 1.10 2010-12-06 21:48:56 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,33 +28,53 @@ cmd_list_parse(int argc, char **argv, char **cause)
struct cmd_list *cmdlist;
struct cmd *cmd;
int i, lastsplit;
size_t arglen, new_argc;
char **copy_argv, **new_argv;
copy_argv = cmd_copy_argv(argc, argv);
cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist);
cmdlist->references = 1;
TAILQ_INIT(&cmdlist->list);
lastsplit = 0;
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "\\;") == 0) {
argv[i][0] = ';';
argv[i][1] = '\0';
} else if (strcmp(argv[i], ";") == 0) {
cmd = cmd_parse(i - lastsplit, argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
lastsplit = i + 1;
arglen = strlen(copy_argv[i]);
if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
continue;
copy_argv[i][arglen - 1] = '\0';
if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
copy_argv[i][arglen - 2] = ';';
continue;
}
new_argc = i - lastsplit;
new_argv = copy_argv + lastsplit;
if (arglen != 1)
new_argc++;
cmd = cmd_parse(new_argc, new_argv, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
lastsplit = i + 1;
}
cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
if (lastsplit != argc) {
cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
}
cmd_free_argv(argc, copy_argv);
return (cmdlist);
bad:
cmd_list_free(cmdlist);
cmd_free_argv(argc, copy_argv);
return (NULL);
}
@@ -62,58 +82,49 @@ int
cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
{
struct cmd *cmd;
int n;
int n, retval;
TAILQ_FOREACH(cmd, cmdlist, qentry) {
if ((n = cmd_exec(cmd, ctx)) != 0)
return (n);
retval = 0;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if ((n = cmd_exec(cmd, ctx)) == -1)
return (-1);
/*
* A 1 return value means the command client is being attached
* (sent MSG_READY).
*/
if (n == 1) {
retval = 1;
/*
* The command client has been attached, so mangle the
* context to treat any following commands as if they
* were called from inside.
*/
if (ctx->curclient == NULL) {
ctx->curclient = ctx->cmdclient;
ctx->cmdclient = NULL;
ctx->error = key_bindings_error;
ctx->print = key_bindings_print;
ctx->info = key_bindings_info;
}
}
}
return (0);
}
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);
return (retval);
}
void
cmd_list_free(struct cmd_list *cmdlist)
{
struct cmd *cmd;
while (!TAILQ_EMPTY(cmdlist)) {
cmd = TAILQ_FIRST(cmdlist);
TAILQ_REMOVE(cmdlist, cmd, qentry);
if (--cmdlist->references != 0)
return;
while (!TAILQ_EMPTY(&cmdlist->list)) {
cmd = TAILQ_FIRST(&cmdlist->list);
TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
cmd_free(cmd);
}
xfree(cmdlist);
@@ -126,7 +137,7 @@ cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
size_t off;
off = 0;
TAILQ_FOREACH(cmd, cmdlist, qentry) {
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (off >= len)
break;
off += cmd_print(cmd, buf + off, len - off);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.2 2009-01-27 23:26:15 nicm Exp $ */
/* $Id: cmd-load-buffer.c,v 1.18 2010-12-22 15:28:50 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -17,9 +17,9 @@
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -31,72 +31,155 @@
*/
int cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_load_buffer_callback(struct client *, void *);
const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb",
CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1,
CMD_ARG1, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_load_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
struct cmd_load_buffer_cdata {
struct session *session;
int buffer;
};
int
cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct session *s;
struct stat statbuf;
FILE *f;
char *buf;
u_int limit;
struct cmd_buffer_data *data = self->data;
struct cmd_load_buffer_cdata *cdata;
struct session *s;
struct client *c = ctx->cmdclient;
FILE *f;
char *pdata, *new_pdata;
size_t psize;
u_int limit;
int ch;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
if (stat(data->arg, &statbuf) < 0) {
if (strcmp(data->arg, "-") == 0) {
if (c == NULL) {
ctx->error(ctx, "%s: can't read from stdin", data->arg);
return (-1);
}
if (c->flags & CLIENT_TERMINAL) {
ctx->error(ctx, "%s: stdin is a tty", data->arg);
return (-1);
}
if (c->stdin_fd == -1) {
ctx->error(ctx, "%s: can't read from stdin", data->arg);
return (-1);
}
cdata = xmalloc(sizeof *cdata);
cdata->session = s;
cdata->session->references++;
cdata->buffer = data->buffer;
c->stdin_data = cdata;
c->stdin_callback = cmd_load_buffer_callback;
c->references++;
bufferevent_enable(c->stdin_event, EV_READ);
return (1);
}
if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
if ((f = fopen(data->arg, "r")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
pdata = NULL;
psize = 0;
while ((ch = getc(f)) != EOF) {
/* Do not let the server die due to memory exhaustion. */
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
ctx->error(ctx, "realloc error: %s", strerror(errno));
goto error;
}
pdata = new_pdata;
pdata[psize++] = ch;
}
/*
* We don't want to die due to memory exhaustion, hence xmalloc can't
* be used here.
*/
if ((buf = malloc(statbuf.st_size + 1)) == NULL) {
ctx->error(ctx, "malloc error: %s", strerror(errno));
return (-1);
if (ferror(f)) {
ctx->error(ctx, "%s: read error", data->arg);
goto error;
}
if (pdata != NULL)
pdata[psize] = '\0';
if (fread(buf, 1, statbuf.st_size, f) != (size_t) statbuf.st_size) {
ctx->error(ctx, "%s: fread error", data->arg);
xfree(buf);
fclose(f);
return (-1);
}
buf[statbuf.st_size] = '\0';
fclose(f);
f = NULL;
limit = options_get_number(&s->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&s->buffers, buf, limit);
paste_add(&s->buffers, pdata, psize, limit);
return (0);
}
if (paste_replace(&s->buffers, data->buffer, buf) != 0) {
if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf);
return (-1);
}
return (0);
error:
if (pdata != NULL)
xfree(pdata);
if (f != NULL)
fclose(f);
return (-1);
}
void
cmd_load_buffer_callback(struct client *c, void *data)
{
struct cmd_load_buffer_cdata *cdata = data;
struct session *s = cdata->session;
char *pdata;
size_t psize;
u_int limit;
/*
* Event callback has already checked client is not dead and reduced
* its reference count. But tell it to exit.
*/
c->flags |= CLIENT_EXIT;
/* Does the target session still exist? */
if (!session_alive(s))
goto out;
psize = EVBUFFER_LENGTH(c->stdin_event->input);
if (psize == 0)
goto out;
pdata = malloc(psize + 1);
if (pdata == NULL)
goto out;
bufferevent_read(c->stdin_event, pdata, psize);
pdata[psize] = '\0';
limit = options_get_number(&s->options, "buffer-limit");
if (cdata->buffer == -1) {
paste_add(&s->buffers, pdata, psize, limit);
goto out;
}
if (paste_replace(&s->buffers, cdata->buffer, pdata, psize) != 0) {
/* No context so can't use server_client_msg_error. */
evbuffer_add_printf(
c->stderr_event->output, "no buffer %d\n", cdata->buffer);
bufferevent_enable(c->stderr_event, EV_WRITE);
goto out;
}
out:
cdata->session->references--;
xfree(cdata);
}

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

@@ -0,0 +1,53 @@
/* $Id: cmd-lock-client.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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, "",
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.2 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-lock-server.c,v 1.9 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,25 +30,23 @@
int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
int cmd_lock_server_callback(void *, const char *);
const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock",
"",
0,
0, "",
NULL,
NULL,
cmd_lock_server_exec,
NULL,
NULL,
NULL,
NULL,
};
/* ARGSUSED */
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.2 2009-11-14 17:56: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, "",
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.13 2009-11-14 17:56:39 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, "dk",
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 = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't move window: %s", cause);
xfree(cause);
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.40 2009-04-01 18:21:24 nicm Exp $ */
/* $Id: cmd-new-session.c,v 1.80 2010-12-22 15:31:00 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,11 @@
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "tmux.h"
/*
@@ -26,13 +31,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,17 +45,16 @@ 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, "",
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
};
/* ARGSUSED */
void
cmd_new_session_init(struct cmd *self, unused int arg)
{
@@ -59,6 +62,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 +74,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 +86,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 +103,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 +122,197 @@ 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;
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);
}
}
struct session *s, *old_s, *groupwith;
struct window *w;
struct window_pane *wp;
struct environ env;
struct termios tio, *tiop;
struct passwd *pw;
const char *update, *cwd;
char *overrides, *cmd, *cause;
int detached, idx;
u_int sx, sy, i;
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 {
pw = getpwuid(getuid());
if (pw->pw_dir != NULL && *pw->pw_dir != '\0')
cwd = pw->pw_dir;
else
cwd = "/";
}
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);
old_s = ctx->cmdclient->session;
if (old_s != NULL)
ctx->cmdclient->last_session = old_s;
ctx->cmdclient->session = s;
server_redraw_client(ctx->cmdclient);
} else {
old_s = ctx->curclient->session;
if (old_s != NULL)
ctx->curclient->last_session = old_s;
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
}
}
recalculate_sizes();
server_update_socket();
return (1);
}
/*
* If there are still configuration file errors to display, put the new
* session's current window into more mode and display them now.
*/
if (cfg_finished && !ARRAY_EMPTY(&cfg_causes)) {
wp = s->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
window_copy_add(wp, "%s", cause);
xfree(cause);
}
ARRAY_FREE(&cfg_causes);
}
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
@@ -238,10 +340,12 @@ cmd_new_session_print(struct cmd *self, char *buf, size_t len)
return (off);
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->newname != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
if (off < len && data->winname != NULL)
off += cmd_prarg(buf + off, len - off, " -n ", data->winname);
if (off < len && data->newname != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-window.c,v 1.31 2009-01-23 16:59:14 nicm Exp $ */
/* $Id: cmd-new-window.c,v 1.47 2010-07-02 02:49:19 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -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);
@@ -38,23 +36,23 @@ struct cmd_new_window_data {
char *target;
char *name;
char *cmd;
int flag_insert_after;
int flag_detached;
int flag_kill;
};
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
"[-dk] [-n window-name] [-t target-window] [command]",
0,
"[-adk] [-n window-name] [-t target-window] [command]",
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
};
/* ARGSUSED */
void
cmd_new_window_init(struct cmd *self, unused int arg)
{
@@ -64,6 +62,7 @@ cmd_new_window_init(struct cmd *self, unused int arg)
data->target = NULL;
data->name = NULL;
data->cmd = NULL;
data->flag_insert_after = 0;
data->flag_detached = 0;
data->flag_kill = 0;
}
@@ -74,11 +73,14 @@ 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) {
while ((opt = getopt(argc, argv, "adkt:n:")) != -1) {
switch (opt) {
case 'a':
data->flag_insert_after = 1;
break;
case 'd':
data->flag_detached = 1;
break;
@@ -121,53 +123,69 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
char *cmd, *cwd, *cause;
int idx;
int idx, last;
if (data == NULL)
return (0);
if (arg_parse_window(data->target, &s, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->target);
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);
if (data->flag_insert_after) {
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
idx = wl->idx + 1;
/* Find the next free index. */
for (last = idx; last < INT_MAX; last++) {
if (winlink_find_by_index(&s->windows, last) == NULL)
break;
}
if (last == INT_MAX) {
ctx->error(ctx, "no free window indexes");
return (-1);
}
/* Move everything from last - 1 to idx up a bit. */
for (; last > idx; last--) {
wl = winlink_find_by_index(&s->windows, last - 1);
server_link_window(s, wl, s, last, 0, 0, NULL);
server_unlink_window(s, wl);
}
} else {
if ((idx = cmd_find_index(ctx, data->target, &s)) == -2)
return (-1);
}
wl = NULL;
if (idx != -1)
wl = winlink_find_by_index(&s->windows, idx);
if (wl != NULL) {
if (data->flag_kill) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(s, wl);
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
if (wl != NULL && data->flag_kill) {
/*
* Can't use session_detach as it will destroy session if this
* makes it empty.
*/
wl->flags &= ~WINLINK_ALERTFLAGS;
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
}
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
}
}
cmd = data->cmd;
if (cmd == NULL)
cmd = options_get_string(&s->options, "default-command");
if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
cwd = options_get_string(&global_options, "default-path");
else
cwd = ctx->cmdclient->cwd;
cwd = options_get_string(&s->options, "default-path");
if (*cwd == '\0') {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
cwd = ctx->cmdclient->cwd;
else
cwd = s->cwd;
}
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, data->name, cmd, cwd, idx, &cause);
if (wl == NULL) {
ctx->error(ctx, "create window failed: %s", cause);
@@ -176,36 +194,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);
server_redraw_session_group(s);
} else
server_status_session(s);
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.1 2009-04-01 18:21:26 nicm Exp $ */
/* $Id: cmd-next-layout.c,v 1.6 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,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, "",
cmd_target_init,
cmd_target_parse,
cmd_next_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -44,11 +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);
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.16 2009-03-28 14:08:09 nicm Exp $ */
/* $Id: cmd-next-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,13 +29,11 @@ int cmd_next_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_window_entry = {
"next-window", "next",
CMD_TARGET_SESSION_USAGE,
CMD_AFLAG,
"[-a] " CMD_TARGET_SESSION_USAGE,
0, "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))
cmd_set_flag(&data->chflags, '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 (cmd_check_flag(data->chflags, 'a'))
activity = 1;
if (session_next(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-paste-buffer.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-paste-buffer.c,v 1.29 2010-08-11 22:17:32 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -26,33 +27,112 @@
* Paste paste buffer if present.
*/
struct cmd_paste_buffer_data {
char *target;
int buffer;
int flag_delete;
char *sepstr;
};
void cmd_paste_buffer_init(struct cmd *, int);
int cmd_paste_buffer_parse(struct cmd *, int, char **, char **);
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_paste_buffer_filter(
struct window_pane *, const char *, size_t, char *);
void cmd_paste_buffer_free(struct cmd *);
size_t cmd_paste_buffer_print(struct cmd *, char *, size_t);
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
"[-d] " CMD_BUFFER_WINDOW_USAGE,
CMD_DFLAG,
cmd_buffer_init,
cmd_buffer_parse,
"[-dr] [-s separator] [-b buffer-index] [-t target-pane]",
0, "",
cmd_paste_buffer_init,
cmd_paste_buffer_parse,
cmd_paste_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
cmd_paste_buffer_free,
cmd_paste_buffer_print
};
/* ARGSUSED */
void
cmd_paste_buffer_init(struct cmd *self, unused int arg)
{
struct cmd_paste_buffer_data *data;
self->data = data = xmalloc(sizeof *data);
data->target = NULL;
data->buffer = -1;
data->flag_delete = 0;
data->sepstr = xstrdup("\r");
}
int
cmd_paste_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_paste_buffer_data *data;
int opt, n;
const char *errstr;
cmd_paste_buffer_init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "b:ds:t:r")) != -1) {
switch (opt) {
case 'b':
if (data->buffer == -1) {
n = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "buffer %s", errstr);
goto error;
}
data->buffer = n;
}
break;
case 'd':
data->flag_delete = 1;
break;
case 's':
if (data->sepstr != NULL)
xfree(data->sepstr);
data->sepstr = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'r':
if (data->sepstr != NULL)
xfree(data->sepstr);
data->sepstr = xstrdup("\n");
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
}
int
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct winlink *wl;
struct window *w;
struct session *s;
struct paste_buffer *pb;
struct cmd_paste_buffer_data *data = self->data;
struct window_pane *wp;
struct session *s;
struct paste_buffer *pb;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
return (-1);
w = wl->window;
if (data->buffer == -1)
pb = paste_get_top(&s->buffers);
@@ -64,15 +144,79 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
if (pb != NULL)
buffer_write(w->active->out, pb->data, strlen(pb->data));
cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr);
/* Delete the buffer if -d. */
if (data->flags & CMD_DFLAG) {
if (data->flag_delete) {
if (data->buffer == -1)
paste_free_top(&s->buffers);
else
paste_free_index(&s->buffers, data->buffer);
}
return (0);
return (0);
}
/* Add bytes to a buffer and filter '\n' according to separator. */
void
cmd_paste_buffer_filter(
struct window_pane *wp, const char *data, size_t size, char *sep)
{
const char *end = data + size;
const char *lf;
size_t seplen;
seplen = strlen(sep);
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
bufferevent_write(wp->event, data, lf - data);
bufferevent_write(wp->event, sep, seplen);
data = lf + 1;
}
if (end != data)
bufferevent_write(wp->event, data, end - data);
}
void
cmd_paste_buffer_free(struct cmd *self)
{
struct cmd_paste_buffer_data *data = self->data;
if (data->target != NULL)
xfree(data->target);
if (data->sepstr != NULL)
xfree(data->sepstr);
xfree(data);
}
size_t
cmd_paste_buffer_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_paste_buffer_data *data = self->data;
size_t off = 0;
char tmp[BUFSIZ];
int r_flag;
r_flag = 0;
if (data->sepstr != NULL)
r_flag = (data->sepstr[0] == '\n' && data->sepstr[1] == '\0');
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_delete)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && r_flag)
off += xsnprintf(buf + off, len - off, " -r");
if (off < len && data->buffer != -1)
off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
if (off < len && data->sepstr != NULL && !r_flag) {
strnvis(
tmp, data->sepstr, sizeof tmp, VIS_OCTAL|VIS_TAB|VIS_NL);
off += cmd_prarg(buf + off, len - off, " -s ", tmp);
}
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
return (off);
}

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

@@ -0,0 +1,148 @@
/* $Id: cmd-pipe-pane.c,v 1.15 2010-10-24 00:45:57 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 <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <time.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 *);
void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
CMD_TARGET_PANE_USAGE "[-o] [command]",
CMD_ARG01, "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 client *c;
struct window_pane *wp;
char *command;
int old_fd, pipe_fd[2], null_fd, mode;
if ((c = cmd_find_client(ctx, NULL)) == NULL)
return (-1);
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
/* Destroy the old pipe. */
old_fd = wp->pipe_fd;
if (wp->pipe_fd != -1) {
bufferevent_free(wp->pipe_event);
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 (cmd_check_flag(data->chflags, 'o') && old_fd != -1)
return (0);
/* Open the new pipe. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
ctx->error(ctx, "socketpair 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]);
clear_signals(1);
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);
closefrom(STDERR_FILENO + 1);
command = status_replace(c, NULL, data->arg, time(NULL), 0);
execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
_exit(1);
default:
/* Parent process. */
close(pipe_fd[1]);
wp->pipe_fd = pipe_fd[0];
wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
wp->pipe_event = bufferevent_new(wp->pipe_fd,
NULL, NULL, cmd_pipe_pane_error_callback, wp);
bufferevent_enable(wp->pipe_event, EV_WRITE);
if ((mode = fcntl(wp->pipe_fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(wp->pipe_fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
return (0);
}
}
/* ARGSUSED */
void
cmd_pipe_pane_error_callback(
unused struct bufferevent *bufev, unused short what, void *data)
{
struct window_pane *wp = data;
bufferevent_free(wp->pipe_event);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-down-pane.c,v 1.7 2009-04-01 21:10:08 nicm Exp $ */
/* $Id: cmd-previous-layout.c,v 1.6 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -21,41 +21,34 @@
#include "tmux.h"
/*
* Move down a pane.
* Switch window to previous layout.
*/
int cmd_down_pane_exec(struct cmd *, struct cmd_ctx *);
int cmd_previous_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_down_pane_entry = {
"down-pane", "downp",
const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl",
CMD_TARGET_WINDOW_USAGE,
0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_down_pane_exec,
cmd_target_send,
cmd_target_recv,
cmd_previous_layout_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_previous_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window *w;
u_int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
w = wl->window;
do {
w->active = TAILQ_NEXT(w->active, entry);
if (w->active == NULL)
w->active = TAILQ_FIRST(&w->panes);
layout_refresh(w, 1);
} while (w->active->flags & PANE_HIDDEN);
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.16 2009-03-28 14:08:09 nicm Exp $ */
/* $Id: cmd-previous-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,13 +29,11 @@ int cmd_previous_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev",
CMD_TARGET_SESSION_USAGE,
CMD_AFLAG,
"[-a] " CMD_TARGET_SESSION_USAGE,
0, "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))
cmd_set_flag(&data->chflags, '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 (cmd_check_flag(data->chflags, 'a'))
activity = 1;
if (session_previous(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-refresh-client.c,v 1.8 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-refresh-client.c,v 1.11 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,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, "",
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.21 2010-12-22 15:36:44 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, "",
cmd_target_init,
cmd_target_parse,
cmd_rename_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -47,11 +45,20 @@ cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
if (data->arg != NULL && session_find(data->arg) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->arg);
return (-1);
}
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
RB_REMOVE(sessions, &sessions, s);
xfree(s->name);
s->name = xstrdup(data->arg);
RB_INSERT(sessions, &sessions, s);
server_status_session(s);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.26 2009-01-20 19:35:03 nicm Exp $ */
/* $Id: cmd-rename-window.c,v 1.31 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,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, "",
cmd_target_init,
cmd_target_parse,
cmd_rename_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -53,9 +51,9 @@ cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx)
xfree(wl->window->name);
wl->window->name = xstrdup(data->arg);
options_set_number(&wl->window->options, "automatic-rename", 0);
options_set_number(&wl->window->options, "automatic-rename", 0);
server_status_session(s);
server_status_window(wl->window);
return (0);
}

View File

@@ -1,122 +0,0 @@
/* $Id: cmd-resize-pane-down.c,v 1.8 2009-04-02 21:11:52 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 "tmux.h"
/*
* Decrease pane size.
*/
void cmd_resize_pane_down_init(struct cmd *, int);
int cmd_resize_pane_down_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_down_entry = {
"resize-pane-down", "resizep-down",
CMD_PANE_WINDOW_USAGE " [adjustment]",
CMD_ARG01,
cmd_resize_pane_down_init,
cmd_pane_parse,
cmd_resize_pane_down_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
};
void
cmd_resize_pane_down_init(struct cmd *self, int key)
{
struct cmd_pane_data *data;
cmd_pane_init(self, key);
data = self->data;
if (key == KEYC_ADDESC(KEYC_DOWN))
data->arg = xstrdup("5");
}
int
cmd_resize_pane_down_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
const char *errstr;
struct window_pane *wp, *wq;
u_int adjust;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (wl->window->layout != 0) {
ctx->error(ctx, "window not in manual layout");
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;
else {
adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
return (-1);
}
}
/*
* If this is not the last window, keep trying to increase size and
* remove it from the next windows. If it is the last, do so on the
* previous window.
*/
if (TAILQ_NEXT(wp, entry) == NULL) {
if (wp == TAILQ_FIRST(&wl->window->panes)) {
/* Only one pane. */
return (0);
}
wp = TAILQ_PREV(wp, window_panes, entry);
}
while (adjust-- > 0) {
wq = wp;
while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
if (wq->sy > PANE_MINIMUM) {
window_pane_resize(wq, wq->sx, wq->sy - 1);
break;
}
}
if (wq == NULL)
break;
window_pane_resize(wp, wp->sx, wp->sy + 1);
}
window_update_panes(wl->window);
server_redraw_window(wl->window);
return (0);
}

View File

@@ -1,117 +0,0 @@
/* $Id: cmd-resize-pane-up.c,v 1.8 2009-04-02 21:11:52 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 "tmux.h"
/*
* Increase pane size.
*/
void cmd_resize_pane_up_init(struct cmd *, int);
int cmd_resize_pane_up_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_up_entry = {
"resize-pane-up", "resizep-up",
CMD_PANE_WINDOW_USAGE " [adjustment]",
CMD_ARG01,
cmd_resize_pane_up_init,
cmd_pane_parse,
cmd_resize_pane_up_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
};
void
cmd_resize_pane_up_init(struct cmd *self, int key)
{
struct cmd_pane_data *data;
cmd_pane_init(self, key);
data = self->data;
if (key == KEYC_ADDESC(KEYC_UP))
data->arg = xstrdup("5");
}
int
cmd_resize_pane_up_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
const char *errstr;
struct window_pane *wp, *wq;
u_int adjust;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (wl->window->layout != 0) {
ctx->error(ctx, "window not in manual layout");
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;
else {
adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
return (-1);
}
}
/*
* If this is not the last window, keep trying to reduce size and add
* to the following window. If it is the last, do so on the previous
* window.
*/
wq = TAILQ_NEXT(wp, entry);
if (wq == NULL) {
if (wp == TAILQ_FIRST(&wl->window->panes)) {
/* Only one pane. */
return (0);
}
wq = wp;
wp = TAILQ_PREV(wq, window_panes, entry);
}
while (adjust-- > 0) {
if (wp->sy <= PANE_MINIMUM)
break;
window_pane_resize(wq, wq->sx, wq->sy + 1);
window_pane_resize(wp, wp->sx, wp->sy - 1);
}
window_update_panes(wl->window);
server_redraw_window(wl->window);
return (0);
}

111
cmd-resize-pane.c Normal file
View File

@@ -0,0 +1,111 @@
/* $Id: cmd-resize-pane.c,v 1.14 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Increase or decrease pane size.
*/
void cmd_resize_pane_init(struct cmd *, int);
int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
"[-DLRU] " CMD_TARGET_PANE_USAGE " [adjustment]",
CMD_ARG01, "DLRU",
cmd_resize_pane_init,
cmd_target_parse,
cmd_resize_pane_exec,
cmd_target_free,
cmd_target_print
};
void
cmd_resize_pane_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
if (key == (KEYC_UP | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'U');
if (key == (KEYC_DOWN | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'D');
if (key == (KEYC_LEFT | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'L');
if (key == (KEYC_RIGHT | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'R');
if (key == (KEYC_UP | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'U');
data->arg = xstrdup("5");
}
if (key == (KEYC_DOWN | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'D');
data->arg = xstrdup("5");
}
if (key == (KEYC_LEFT | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'L');
data->arg = xstrdup("5");
}
if (key == (KEYC_RIGHT | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'R');
data->arg = xstrdup("5");
}
}
int
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
const char *errstr;
struct window_pane *wp;
u_int adjust;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
return (-1);
if (data->arg == NULL)
adjust = 1;
else {
adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
return (-1);
}
}
if (cmd_check_flag(data->chflags, 'L'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
else if (cmd_check_flag(data->chflags, 'R'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
else if (cmd_check_flag(data->chflags, 'U'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust);
else if (cmd_check_flag(data->chflags, 'D'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
server_redraw_window(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-respawn-window.c,v 1.14 2009-03-04 17:24:07 nicm Exp $ */
/* $Id: cmd-respawn-window.c,v 1.25 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,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, "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 (!cmd_check_flag(data->chflags, 'k')) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1)
continue;
@@ -66,22 +64,32 @@ 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);
window_destroy_panes(w);
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);
server_destroy_pane(wp);
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.2 2009-04-21 20:06:46 nicm Exp $ */
/* $Id: cmd-rotate-window.c,v 1.10 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,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_UPPERUFLAG|CMD_UPPERDFLAG,
0, "DU",
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_UPPERDFLAG;
if (key == ('o' | KEYC_ESCAPE))
cmd_set_flag(&data->chflags, 'D');
}
int
@@ -59,53 +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;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
w = wl->window;
if (data->flags & CMD_UPPERDFLAG) {
if (cmd_check_flag(data->chflags, 'D')) {
wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
lc = wp->layout_cell;
xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy;
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;
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;
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;
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;
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;
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);
}

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

@@ -0,0 +1,144 @@
/* $Id: cmd-run-shell.c,v 1.9 2010-08-09 21:44:25 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, "",
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;
size_t size;
int retcode;
u_int lines;
if (ctx->cmdclient != NULL && ctx->cmdclient->flags & CLIENT_DEAD)
return;
if (ctx->curclient != NULL && ctx->curclient->flags & CLIENT_DEAD)
return;
lines = 0;
do {
if ((line = evbuffer_readline(job->event->input)) != NULL) {
ctx->print(ctx, "%s", line);
lines++;
}
} while (line != NULL);
size = EVBUFFER_LENGTH(job->event->input);
if (size != 0) {
line = xmalloc(size + 1);
memcpy(line, EVBUFFER_DATA(job->event->input), size);
line[size] = '\0';
ctx->print(ctx, "%s", line);
lines++;
xfree(line);
}
cmd = cdata->cmd;
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 (lines != 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--;
ctx->cmdclient->flags |= CLIENT_EXIT;
}
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.4 2009-02-08 13:36:40 tcunha Exp $ */
/* $Id: cmd-save-buffer.c,v 1.12 2010-08-09 21:44:25 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, "a",
cmd_buffer_init,
cmd_buffer_parse,
cmd_save_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free,
cmd_buffer_print
};
@@ -49,7 +47,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_buffer_data *data = self->data;
struct session *s;
struct paste_buffer *pb;
mode_t mask;
mode_t mask;
FILE *f;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
@@ -67,24 +65,31 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
mask = umask(S_IRWXG | S_IRWXO);
if (data->flags & CMD_AFLAG)
f = fopen(data->arg, "a");
else
f = fopen(data->arg, "w");
if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
if (strcmp(data->arg, "-") == 0) {
if (ctx->cmdclient == NULL) {
ctx->error(ctx, "%s: can't write to stdout", data->arg);
return (-1);
}
bufferevent_write(
ctx->cmdclient->stdout_event, pb->data, pb->size);
} else {
mask = umask(S_IRWXG | S_IRWXO);
if (cmd_check_flag(data->chflags, 'a'))
f = fopen(data->arg, "ab");
else
f = fopen(data->arg, "wb");
umask(mask);
if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
ctx->error(ctx, "%s: fwrite error", data->arg);
fclose(f);
return (-1);
}
fclose(f);
}
if (fwrite(pb->data, 1, strlen(pb->data), f) != strlen(pb->data)) {
ctx->error(ctx, "%s: fwrite error", data->arg);
fclose(f);
return (-1);
}
fclose(f);
umask(mask);
return (0);
}

94
cmd-select-layout.c Normal file
View File

@@ -0,0 +1,94 @@
/* $Id: cmd-select-layout.c,v 1.12 2010-07-02 02:54:52 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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"
/*
* Switch window to selected layout.
*/
void cmd_select_layout_init(struct cmd *, int);
int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
CMD_TARGET_WINDOW_USAGE " [layout-name]",
CMD_ARG01, "",
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
cmd_target_free,
cmd_target_print
};
void
cmd_select_layout_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case ('1' | KEYC_ESCAPE):
data->arg = xstrdup("even-horizontal");
break;
case ('2' | KEYC_ESCAPE):
data->arg = xstrdup("even-vertical");
break;
case ('3' | KEYC_ESCAPE):
data->arg = xstrdup("main-horizontal");
break;
case ('4' | KEYC_ESCAPE):
data->arg = xstrdup("main-vertical");
break;
case ('5' | KEYC_ESCAPE):
data->arg = xstrdup("tiled");
break;
}
}
int
cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (data->arg == NULL) {
layout = wl->window->lastlayout;
if (layout == -1)
return (0);
} else if ((layout = layout_set_lookup(data->arg)) != -1) {
layout = layout_set_select(wl->window, layout);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
} else {
if (layout_parse(wl->window, data->arg) == -1) {
ctx->error(ctx, "can't set layout: %s", data->arg);
return (-1);
}
ctx->info(ctx, "arranging in: %s", data->arg);
}
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.13 2010-03-15 22:03:38 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,46 +24,71 @@
* Select pane.
*/
void cmd_select_pane_init(struct cmd *, int);
int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
CMD_PANE_WINDOW_USAGE,
0,
cmd_pane_init,
cmd_pane_parse,
"[-DLRU] " CMD_TARGET_PANE_USAGE,
0, "DLRU",
cmd_select_pane_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
};
void
cmd_select_pane_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
if (key == KEYC_UP)
cmd_set_flag(&data->chflags, 'U');
if (key == KEYC_DOWN)
cmd_set_flag(&data->chflags, 'D');
if (key == KEYC_LEFT)
cmd_set_flag(&data->chflags, 'L');
if (key == KEYC_RIGHT)
cmd_set_flag(&data->chflags, 'R');
if (key == 'o')
data->target = xstrdup(":.+");
}
int
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
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 (!window_pane_visible(wp)) {
ctx->error(ctx, "pane not visible: %s", data->target);
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 (cmd_check_flag(data->chflags, 'L'))
wp = window_pane_find_left(wp);
else if (cmd_check_flag(data->chflags, 'R'))
wp = window_pane_find_right(wp);
else if (cmd_check_flag(data->chflags, 'U'))
wp = window_pane_find_up(wp);
else if (cmd_check_flag(data->chflags, 'D'))
wp = window_pane_find_down(wp);
if (wp == NULL) {
ctx->error(ctx, "pane not found");
return (-1);
}
window_set_active_pane(wl->window, wp);
layout_refresh(wl->window, 1);
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

View File

@@ -1,93 +0,0 @@
/* $Id: cmd-select-prompt.c,v 1.7 2009-02-13 18:57:55 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 <stdlib.h>
#include "tmux.h"
/*
* Prompt for window index and select it.
*/
int cmd_select_prompt_exec(struct cmd *, struct cmd_ctx *);
int cmd_select_prompt_callback(void *, const char *);
const struct cmd_entry cmd_select_prompt_entry = {
"select-prompt", NULL,
CMD_TARGET_CLIENT_USAGE,
0,
cmd_target_init,
cmd_target_parse,
cmd_select_prompt_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
int
cmd_select_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
if (c->prompt_string != NULL)
return (0);
status_prompt_set(c, "index ", cmd_select_prompt_callback, c, 0);
return (0);
}
int
cmd_select_prompt_callback(void *data, const char *s)
{
struct client *c = data;
const char *errstr;
char msg[128];
u_int idx;
if (s == NULL)
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);
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);
return (0);
}
if (session_select(c->session, idx) == 0)
server_redraw_session(c->session);
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-window.c,v 1.21 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-select-window.c,v 1.24 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,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, "",
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.25 2010-05-22 21:56:04 micahcowan 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;
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, "",
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,22 @@ 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;
struct session *s;
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, &s, &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, s, 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 +142,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.29 2010-05-22 21:56:04 micahcowan 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, "",
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, s, ARRAY_FIRST(keylist));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.14 2009-04-02 23:28:16 nicm Exp $ */
/* $Id: cmd-server-info.c,v 1.38 2010-12-22 15:36:44 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,7 +23,6 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <vis.h>
#include "tmux.h"
@@ -36,16 +35,15 @@ int cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
"",
0,
0, "",
NULL,
NULL,
cmd_server_info_exec,
NULL,
NULL,
NULL,
NULL
};
/* ARGSUSED */
int
cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
@@ -58,9 +56,11 @@ 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[BUFSIZ];
char out[80];
char *tim;
time_t t;
u_int lines, ulines;
@@ -68,12 +68,12 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
tim = ctime(&start_time);
*strchr(tim, '\n') = '\0';
ctx->print(ctx,
ctx->print(ctx,
"tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(ctx, "socket path %s, debug level %d%s",
socket_path, debug_level, be_quiet ? ", quiet" : "");
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
ctx->print(
ctx, "socket path %s, debug level %d", socket_path, debug_level);
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine);
}
if (cfg_file != NULL)
@@ -81,9 +81,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
else
ctx->print(ctx, "configuration file not specified");
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,50 +89,49 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
if (c == NULL || c->session == NULL)
continue;
ctx->print(ctx, "%2d: %p %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x]", i, c, 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);
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x, references=%u]", i, c->tty.path,
c->ibuf.fd, c->tty.fd, c->session->name,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags,
c->tty.flags, c->references);
}
ctx->print(ctx, "");
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Sessions: [%zu/%zu]",
ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8));
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
t = s->tv.tv_sec;
RB_FOREACH(s, sessions, &sessions) {
t = s->creation_time.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%2u: %p %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x]", i, s, s->name, winlink_count(&s->windows),
tim, s->sx, s->sy, s->flags);
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x]", s->idx, s->name,
winlink_count(&s->windows), tim, s->sx, s->sy, s->flags);
RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
ctx->print(ctx, "%4u: %p/%p %s [%ux%u] [flags=0x%x, "
"references=%u, layout=%u]", wl->idx, wl, w, w->name,
w->sx, w->sy, w->flags, w->references, w->layout);
ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, "
"references=%u, last layout=%d]", wl->idx, w->name,
w->sx, w->sy, w->flags, w->references,
w->lastlayout);
j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0;
gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) {
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: %p %s %lu %d %u/%u, %zu "
"bytes; UTF-8 %u/%u, %zu bytes", j, wp,
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
"bytes; UTF-8 %u/%u, %zu bytes", j,
wp->tty, (u_long) wp->pid, wp->fd, lines,
gd->hsize + gd->sy, size, ulines,
gd->hsize + gd->sy, usize);
@@ -142,9 +139,9 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
}
}
ctx->print(ctx, "");
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Terminals:");
ctx->print(ctx, "Terminals:");
SLIST_FOREACH(term, &tty_terms, entry) {
ctx->print(ctx, "%s [references=%u, flags=0x%x]:",
term->name, term->references, term->flags);
@@ -157,10 +154,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ent->code, ent->name);
break;
case TTYCODE_STRING:
strnvis(out, code->value.string,
sizeof out, VIS_OCTAL|VIS_WHITE);
out[(sizeof out) - 1] = '\0';
strnvis(out, code->value.string, sizeof out,
VIS_OCTAL|VIS_TAB|VIS_NL);
ctx->print(ctx, "%2u: %s: (string) %s",
ent->code, ent->name, out);
break;
@@ -176,7 +171,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.12 2009-11-28 14:54:12 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, "",
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;
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.3 2009-11-14 17:56: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 <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, "gru",
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 (cmd_check_flag(data->chflags, 'g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
env = &s->environ;
}
if (cmd_check_flag(data->chflags, 'u')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -u");
return (-1);
}
environ_unset(env, data->arg);
} else if (cmd_check_flag(data->chflags, '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.60 2009-03-21 12:44:06 nicm Exp $ */
/* $Id: cmd-set-option.c,v 1.102 2010-12-22 15:23:59 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,102 +29,228 @@
int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const char *cmd_set_option_print(
const struct set_option_entry *, struct options_entry *);
void cmd_set_option_string(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *, int);
void cmd_set_option_number(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_keys(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_colour(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_attributes(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_flag(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_choice(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
CMD_OPTION_SESSION_USAGE,
CMD_GFLAG|CMD_UFLAG,
"[-agsuw] [-t target-session|target-window] option [value]",
CMD_ARG12, "agsuw",
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_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL
};
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[] = {
{ "escape-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "exit-unattached", SET_OPTION_FLAG, 0, 0, NULL },
{ "quiet", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_session_option_table[] = {
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "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 },
{ "destroy-unattached", SET_OPTION_FLAG, 0, 0, NULL },
{ "detach-on-destroy", SET_OPTION_FLAG, 0, 0, NULL },
{ "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-active-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "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 },
{ "message-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "mouse-select-pane", SET_OPTION_FLAG, 0, 0, NULL },
{ "pane-active-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-active-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "prefix", SET_OPTION_KEYS, 0, 0, NULL },
{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "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 },
{ "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 },
{ "visual-silence", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "alternate-screen", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "monitor-silence",SET_OPTION_NUMBER, 0, INT_MAX, NULL},
{ "other-pane-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "other-pane-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-alert-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-alert-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-alert-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
{ "word-separators", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_option_data *data = self->data;
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry;
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)
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
oo = &s->options;
table = set_option_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
}
if (*data->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 = 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 (cmd_check_flag(data->chflags, 'u')) {
if (cmd_check_flag(data->chflags, 'g')) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
return (-1);
}
if (data->value != NULL) {
if (data->arg2 != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
@@ -135,25 +261,26 @@ 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);
cmd_set_option_string(ctx, oo, entry,
data->arg2, cmd_check_flag(data->chflags, 'a'));
break;
case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->value);
cmd_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:
cmd_set_option_keys(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->value);
cmd_set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->value);
cmd_set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->value);
cmd_set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->value);
cmd_set_option_choice(ctx, oo, entry, data->arg2);
break;
}
}
@@ -165,5 +292,278 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_client(c);
}
/*
* Special-case: kill all persistent jobs if status-left, status-right
* or set-titles-string have changed. Persistent jobs are only used by
* the status line at the moment so this works XXX.
*/
if (strcmp(entry->name, "status-left") == 0 ||
strcmp(entry->name, "status-right") == 0 ||
strcmp(entry->name, "status") == 0 ||
strcmp(entry->name, "set-titles-string") == 0 ||
strcmp(entry->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
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);
}
const char *
cmd_set_option_print(
const struct set_option_entry *entry, struct options_entry *o)
{
static char out[BUFSIZ];
const char *s;
struct keylist *keylist;
u_int i;
*out = '\0';
switch (entry->type) {
case SET_OPTION_STRING:
xsnprintf(out, sizeof out, "\"%s\"", o->str);
break;
case SET_OPTION_NUMBER:
xsnprintf(out, sizeof out, "%lld", o->num);
break;
case SET_OPTION_KEYS:
keylist = o->data;
for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
strlcat(out, key_string_lookup_key(
ARRAY_ITEM(keylist, i)), sizeof out);
if (i != ARRAY_LENGTH(keylist) - 1)
strlcat(out, ",", sizeof out);
}
break;
case SET_OPTION_COLOUR:
s = colour_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_ATTRIBUTES:
s = attributes_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_FLAG:
if (o->num)
strlcpy(out, "on", sizeof out);
else
strlcpy(out, "off", sizeof out);
break;
case SET_OPTION_CHOICE:
s = entry->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
}
return (out);
}
void
cmd_set_option_string(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value, int append)
{
struct options_entry *o;
char *oldvalue, *newvalue;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if (append) {
oldvalue = options_get_string(oo, entry->name);
xasprintf(&newvalue, "%s%s", oldvalue, value);
} else
newvalue = value;
o = options_set_string(oo, entry->name, "%s", newvalue);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
if (newvalue != value)
xfree(newvalue);
}
void
cmd_set_option_number(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
long long number;
const char *errstr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
number = strtonum(value, entry->minimum, entry->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
return;
}
o = options_set_number(oo, entry->name, number);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
struct keylist *keylist;
char *copyvalue, *ptr, *str;
int key;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ptr = copyvalue = xstrdup(value);
while ((str = strsep(&ptr, ",")) != NULL) {
if ((key = key_string_lookup_string(str)) == KEYC_NONE) {
xfree(keylist);
ctx->error(ctx, "unknown key: %s", str);
xfree(copyvalue);
return;
}
ARRAY_ADD(keylist, key);
}
xfree(copyvalue);
o = options_set_data(oo, entry->name, keylist, xfree);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_colour(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int colour;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
return;
}
o = options_set_number(oo, entry->name, colour);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int attr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
return;
}
o = options_set_number(oo, entry->name, attr);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int flag;
if (value == NULL || *value == '\0')
flag = !options_get_number(oo, entry->name);
else {
if ((value[0] == '1' && value[1] == '\0') ||
strcasecmp(value, "on") == 0 ||
strcasecmp(value, "yes") == 0)
flag = 1;
else if ((value[0] == '0' && value[1] == '\0') ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
return;
}
}
o = options_set_number(oo, entry->name, flag);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_choice(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
const char **choicep;
int n, choice = -1;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
n = 0;
for (choicep = entry->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (choice != -1) {
ctx->error(ctx, "ambiguous option value: %s", value);
return;
}
choice = n - 1;
}
if (choice == -1) {
ctx->error(ctx, "unknown option value: %s", value);
return;
}
o = options_set_number(oo, entry->name, choice);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}

View File

@@ -1,169 +0,0 @@
/* $Id: cmd-set-password.c,v 1.3 2009-01-19 18:23:40 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.24 2009-01-30 00:24:49 nicm Exp $ */
/* $Id: cmd-set-window-option.c,v 1.43 2009-12-04 22:11:23 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,151 +18,30 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Set a window option.
* Set a window option. This is just an alias for set-option -w.
*/
int cmd_set_window_option_parse(struct cmd *, int, char **, char **);
int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_window_option_send(struct cmd *, struct buffer *);
void cmd_set_window_option_recv(struct cmd *, struct buffer *);
void cmd_set_window_option_free(struct cmd *);
size_t cmd_set_window_option_print(struct cmd *, char *, size_t);
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, "agu",
NULL,
cmd_option_parse,
cmd_target_parse,
cmd_set_window_option_exec,
cmd_option_send,
cmd_option_recv,
cmd_option_free,
cmd_option_print
};
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "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 },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "remain-on-exit", 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-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
cmd_target_free,
cmd_target_print
};
int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_option_data *data = self->data;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry;
u_int i;
struct cmd_target_data *data = self->data;
if (data->flags & CMD_GFLAG)
oo = &global_window_options;
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
if (*data->option == '\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)
continue;
if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->option);
return (-1);
}
entry = &set_window_option_table[i];
/* Bail now if an exact match. */
if (strcmp(entry->name, data->option) == 0)
break;
}
if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->option);
return (-1);
}
if (data->flags & CMD_UFLAG) {
if (data->flags & CMD_GFLAG) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
return (-1);
}
if (data->value != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
}
options_remove(oo, entry->name);
ctx->info(ctx, "unset option: %s", entry->name);
} else {
switch (entry->type) {
case SET_OPTION_STRING:
set_option_string(ctx, oo, entry, data->value);
break;
case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->value);
break;
case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->value);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->value);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->value);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->value);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->value);
break;
}
}
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
server_redraw_client(c);
}
return (0);
cmd_set_flag(&data->chflags, 'w');
return (cmd_set_option_entry.exec(self, ctx));
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-buffer.c,v 1.4 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-show-buffer.c,v 1.12 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -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, "",
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;
ptr = pb->data;
do {
buf[len++] = *ptr++;
buf = xmalloc(width + 1);
len = 0;
if (len == size) {
buf[len] = '\0';
ctx->print(ctx, buf);
ptr = in;
do {
buf[len++] = *ptr++;
len = 0;
}
} while (*ptr != '\0');
if (len == width || buf[len - 1] == '\n') {
if (buf[len - 1] == '\n')
len--;
buf[len] = '\0';
ctx->print(ctx, "%s", buf);
len = 0;
}
} while (*ptr != '\0');
if (len != 0) {
buf[len] = '\0';
ctx->print(ctx, 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.2 2009-11-14 17:56: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 <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, "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 (cmd_check_flag(data->chflags, '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);
}

65
cmd-show-messages.c Normal file
View File

@@ -0,0 +1,65 @@
/* $Id: cmd-show-messages.c,v 1.2 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include <time.h>
#include "tmux.h"
/*
* Show client message log.
*/
int cmd_show_messages_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
CMD_TARGET_CLIENT_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_show_messages_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_show_messages_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
struct message_entry *msg;
char *tim;
u_int i;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
msg = &ARRAY_ITEM(&c->message_log, i);
tim = ctime(&msg->msg_time);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%s %s", tim, msg->msg);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.11 2009-01-27 20:22:33 nicm Exp $ */
/* $Id: cmd-show-options.c,v 1.21 2009-12-10 16:59:02 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,13 +31,11 @@ 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,
"[-gsw] [-t target-session|target-window]",
0, "gsw",
cmd_target_init,
cmd_target_parse,
cmd_show_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -46,64 +44,44 @@ int
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
u_int i;
char *vs;
long long vn;
const char *optval;
if (data->flags & CMD_GFLAG)
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
oo = &s->options;
table = set_option_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
}
for (i = 0; i < NSETOPTION; i++) {
entry = &set_option_table[i];
if (options_find1(oo, entry->name) == NULL)
for (entry = 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 = cmd_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.15 2009-12-04 22:11:23 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,7 +24,7 @@
#include "tmux.h"
/*
* Show window options.
* Show window options. This is an alias for show-options -w.
*/
int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
@@ -32,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, "g",
cmd_target_init,
cmd_target_parse,
cmd_show_window_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
@@ -46,65 +44,7 @@ int
cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct options *oo;
const struct set_option_entry *entry;
u_int i;
char *vs;
long long vn;
if (data->flags & CMD_GFLAG)
oo = &global_window_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)
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;
}
}
return (0);
cmd_set_flag(&data->chflags, 'w');
return (cmd_show_options_entry.exec(self, ctx));
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-source-file.c,v 1.5 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-source-file.c,v 1.13 2010-02-08 18:29:32 tcunha Exp $ */
/*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -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,16 +37,15 @@ struct cmd_source_file_data {
const struct cmd_entry cmd_source_file_entry = {
"source-file", "source",
"path",
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
};
/* ARGSUSED */
void
cmd_source_file_init(struct cmd *self, unused int arg)
{
@@ -64,7 +61,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) {
@@ -92,36 +89,23 @@ int
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_source_file_data *data = self->data;
struct causelist causes;
char *cause;
u_int i;
if (load_cfg(data->path, &cause) != 0) {
ctx->error(ctx, "%s", cause);
xfree(cause);
return (-1);
ARRAY_INIT(&causes);
if (load_cfg(data->path, ctx, &causes) != 0) {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
xfree(cause);
}
ARRAY_FREE(&causes);
}
return (0);
}
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.12 2009-04-03 17:21:46 nicm Exp $ */
/* $Id: cmd-split-window.c,v 1.35 2010-07-02 02:49:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -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-pane] [command]",
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;
}
@@ -138,70 +148,83 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
const char **env;
struct window_pane *wp, *new_wp = NULL;
struct environ env;
char *cmd, *cwd, *cause;
u_int hlimit, lines;
const char *shell;
u_int hlimit;
int size;
enum layout_type type;
struct layout_cell *lc;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
return (-1);
w = wl->window;
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");
else
cwd = ctx->cmdclient->cwd;
lines = -1;
if (data->lines != -1)
lines = data->lines;
else if (data->percentage != -1)
lines = (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);
cwd = options_get_string(&s->options, "default-path");
if (*cwd == '\0') {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
cwd = ctx->cmdclient->cwd;
else
cwd = s->cwd;
}
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1) {
if (type == LAYOUT_TOPBOTTOM)
size = (wp->sy * data->percentage) / 100;
else
size = (wp->sx * data->percentage) / 100;
}
hlimit = options_get_number(&s->options, "history-limit");
shell = options_get_string(&s->options, "default-shell");
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
if ((lc = layout_split_pane(wp, type, size)) == NULL) {
cause = xstrdup("pane too small");
goto error;
}
new_wp = window_add_pane(w, hlimit);
if (window_pane_spawn(
new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
layout_assign_pane(lc, new_wp);
server_redraw_window(w);
if (!data->flag_detached) {
window_set_active_pane(w, wp);
window_set_active_pane(w, new_wp);
session_select(s, wl->idx);
server_redraw_session(s);
} else
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 (new_wp != NULL)
window_remove_pane(w, new_wp);
ctx->error(ctx, "create pane failed: %s", cause);
xfree(cause);
return (-1);
}
void
@@ -227,6 +250,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.10 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,16 +29,15 @@ 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, "",
NULL,
NULL,
cmd_start_server_exec,
NULL,
NULL,
NULL,
NULL
};
/* ARGSUSED */
int
cmd_start_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.13 2009-02-16 19:29:17 nicm Exp $ */
/* $Id: cmd-string.c,v 1.32 2010-12-13 22:53:56 nicm 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"
@@ -30,20 +32,23 @@
*/
int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(const char *, size_t *);
void cmd_string_ungetc(size_t *);
char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *);
char *cmd_string_expand_tilde(const char *, size_t *);
int
cmd_string_getc(const char *s, size_t *p)
{
if (s[*p] == '\0')
const u_char *ucs = s;
if (ucs[*p] == '\0')
return (EOF);
return (s[(*p)++]);
return (ucs[(*p)++]);
}
void
cmd_string_ungetc(unused const char *s, size_t *p)
cmd_string_ungetc(size_t *p)
{
(*p)--;
}
@@ -56,29 +61,17 @@ 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;
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(s) != 0) {
xasprintf(cause, "assignment failed: %s", s);
return (-1);
}
*cmdlist = NULL;
return (0);
}
argv = NULL;
argc = 0;
buf = NULL;
len = 0;
have_arg = 0;
*cause = NULL;
*cmdlist = NULL;
@@ -95,8 +88,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '"':
if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
@@ -105,8 +96,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '$':
if ((t = cmd_string_variable(s, &p)) == NULL)
@@ -114,8 +103,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);
have_arg = 1;
xfree(t);
break;
case '#':
/* Comment: discard rest of line. */
@@ -125,7 +113,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
case EOF:
case ' ':
case '\t':
if (have_arg) {
if (buf != NULL) {
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
@@ -134,12 +122,20 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = NULL;
len = 0;
have_arg = 0;
}
if (ch != EOF)
break;
while (argc != 0) {
equals = strchr(argv[0], '=');
whitespace = argv[0] + strcspn(argv[0], " \t");
if (equals == NULL || equals > whitespace)
break;
environ_put(&global_environ, argv[0]);
argc--;
memmove(argv, argv + 1, argc * (sizeof *argv));
}
if (argc == 0)
goto out;
@@ -147,20 +143,25 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
if (*cmdlist == NULL)
goto out;
do
xfree(argv[argc - 1]);
while (--argc > 0);
rval = 0;
goto out;
case '~':
if (buf == NULL) {
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;
buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch;
have_arg = 1;
break;
}
}
@@ -172,10 +173,11 @@ out:
if (buf != NULL)
xfree(buf);
while (--argc >= 0)
xfree(argv[argc]);
if (argv != NULL)
if (argv != NULL) {
for (i = 0; i < argc; i++)
xfree(argv[i]);
xfree(argv);
}
return (rval);
}
@@ -187,30 +189,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 +224,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';
@@ -241,9 +247,10 @@ error:
char *
cmd_string_variable(const char *s, size_t *p)
{
int ch, fch;
char *buf, *t;
size_t len;
int ch, fch;
char *buf, *t;
size_t len;
struct environ_entry *envent;
#define cmd_string_first(ch) ((ch) == '_' || \
((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z'))
@@ -251,7 +258,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;
@@ -274,7 +281,7 @@ cmd_string_variable(const char *s, size_t *p)
buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch;
for(;;) {
for (;;) {
ch = cmd_string_getc(s, p);
if (ch == EOF || !cmd_string_other(ch))
break;
@@ -290,20 +297,48 @@ cmd_string_variable(const char *s, size_t *p)
if (fch == '{' && ch != '}')
goto error;
if (ch != EOF && fch != '{')
cmd_string_ungetc(s, p); /* ch */
cmd_string_ungetc(p); /* ch */
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
if ((t = getenv(buf)) == NULL) {
xfree(buf);
return (xstrdup(""));
}
envent = environ_find(&global_environ, buf);
xfree(buf);
return (xstrdup(t));
if (envent == NULL)
return (xstrdup(""));
return (xstrdup(envent->value));
error:
if (buf != NULL)
xfree(buf);
return (NULL);
}
char *
cmd_string_expand_tilde(const char *s, size_t *p)
{
struct passwd *pw;
struct environ_entry *envent;
char *home, *path, *username;
home = NULL;
if (cmd_string_getc(s, p) == '/') {
envent = environ_find(&global_environ, "HOME");
if (envent != NULL && *envent->value != '\0')
home = envent->value;
else if ((pw = getpwuid(getuid())) != NULL)
home = pw->pw_dir;
} else {
cmd_string_ungetc(p);
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
return (NULL);
if ((pw = getpwnam(username)) != NULL)
home = pw->pw_dir;
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.5 2009-11-14 17:56:39 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, "",
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.4 2009-04-03 17:21:46 nicm Exp $ */
/* $Id: cmd-swap-pane.c,v 1.15 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,260 +26,119 @@
* 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, "dDU",
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 == '{')
cmd_set_flag(&data->chflags, 'U');
else if (key == '}')
cmd_set_flag(&data->chflags, '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;
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 (cmd_check_flag(data->chflags, 'D')) {
src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes);
} else if (cmd_check_flag(data->chflags, 'U')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
} 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);
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;
src_wp->xoff = dst_wp->xoff;
src_wp->yoff = dst_wp->yoff;
dst_wp->xoff = xx;
dst_wp->yoff = yy;
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;
xx = src_wp->sx;
yy = src_wp->sy;
src_wp->window = dst_w;
dst_wp->window = src_w;
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) {
window_set_active_pane(w, dst_wp);
layout_refresh(w, 0);
if (!cmd_check_flag(data->chflags, 'd')) {
if (src_w != dst_w) {
window_set_active_pane(src_w, dst_wp);
window_set_active_pane(dst_w, src_wp);
} 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);
}

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