224 Commits
0.8 ... 0.9

Author SHA1 Message Date
no_author
dc2b811476 This commit was manufactured by cvs2svn to create tag 'TMUX_0_9'. 2009-07-02 18:26:56 +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
126 changed files with 3842 additions and 3194 deletions

126
CHANGES
View File

@@ -1,3 +1,121 @@
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 +365,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 +450,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 +469,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 +1322,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.299 2009-07-01 22:15:16 nicm 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

16
FAQ
View File

@@ -87,9 +87,10 @@ for each tmux window or globally by setting the "utf8" flag:
setw -g utf8 on
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:
As of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by
checking the LC_ALL, LC_CTYPE and LANG environment variables. list-clients may
be used to check if this is detected correctly; if not, the -u command-line
flag may be specified when creating or attaching a client to a tmux session:
$ tmux -u new
@@ -186,4 +187,11 @@ 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 $
* How do I prevent tmux from resizing my PuTTY window?
This isn't tmux's fault, but happens because the initialisation strings for the
terminal in use (set through TERM) request it. PuTTY can be told to ignore such
requests: in the configuration window under Terminal -> Features, check the
"Disable remote-controlled terminal resizing" box.
$Id: FAQ,v 1.23 2009-07-01 19:49:56 nicm Exp $

View File

@@ -1,144 +1,57 @@
# $Id: GNUmakefile,v 1.82 2009-04-21 20:10:22 nicm Exp $
# $Id: GNUmakefile,v 1.107 2009-07-01 22:10:06 nicm Exp $
.PHONY: clean
PROG= tmux
VERSION= 0.8
DATE= $(shell date +%Y%m%d-%H%M)
VERSION= 0.9
#FDEBUG= 1
META?= \002
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
CC?= gcc
INCDIRS+= -I. -I-
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\"" -DMETA="'${META}'"
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+= -lncurses
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
ifeq ($(shell (LC_ALL=C $(CC) -v 2>&1|awk '/gcc version 4/') || true), )
CPPFLAGS:= -I. -I- $(CPPFLAGS)
else
CPPFLAGS:= -iquote. $(CPPFLAGS)
endif
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
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
SRCS= $(shell echo *.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 .depend *~ *.core *.log compat/*.o
clean-all: clean
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

154
Makefile
View File

@@ -1,158 +1,62 @@
# $Id: Makefile,v 1.121 2009-04-21 20:10:22 nicm Exp $
# $Id: Makefile,v 1.142 2009-07-01 22:10:06 nicm Exp $
.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= 0.9
#FDEBUG= 1
META?= \002 # C-b
CC?= cc
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+= -lncurses
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
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
CCV!= (LC_ALL=C ${CC} -v 2>&1|awk '/gcc version 4/') || true
.if empty(CCV)
CPPFLAGS:= -I. -I- -I/usr/local/include ${CPPFLAGS}
.else
CPPFLAGS:= -iquote. -I/usr/local/include ${CPPFLAGS}
.endif
.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
PREFIX?= /usr/local
INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555
INSTALLMAN= install -g bin -o root -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|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 .depend *~ *.core *.log compat/*.o
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-*
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
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/

25
NOTES
View File

@@ -4,9 +4,10 @@ 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 0.9 release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they hasn't been tested in a while). It is
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
@@ -42,7 +43,6 @@ The following is a summary of major features implemented in this version:
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.
@@ -55,8 +55,10 @@ 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.
tmux(1) and the FAQ file. As of 0.9, tmux attempts to autodetect a
UTF-8-capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment
variables. list-clients may be used to check if this is detected correctly; if
not, the -u command-line flag may be specified.
A Vim syntax file is available in the examples directory. To install it:
@@ -74,15 +76,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
@@ -94,4 +87,4 @@ welcome. Please send by email to:
-- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.45 2009-04-21 20:06:12 nicm Exp $
$Id: NOTES,v 1.48 2009-07-01 19:49:56 nicm Exp $

103
TODO
View File

@@ -1,32 +1,20 @@
- 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
- 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
- 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?
@@ -41,63 +29,64 @@
unwrapping
- input.c is too complicated. simplify?
- 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
- key handling sucks a bit and may need to be reworked
- some people find first window being 0 rather than 1 is awkward on the
keyboard. 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?
keyboard
- client sx/sy should be in tty, then can let the terminal wrap at edge
to allow xterm to pick up it should be one line for its c/p
- should be able to move to a hidden pane and it would be moved into view. pane
number in status line/top-right would be cool for this
- command to run something without a window at all - output to
window-more. what for? isnt this the same as doing it w/ splitw/neww now?
- 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
binary as "tmuxsh" or wrapper script?) problems with tty dev permissions
- support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically?
- set-option should be set-session-option and should be overall global options
for stuff like mode keys?
- a confirm-before command which asks "Are you sure? (y/n)" before executing
command, eg bind-key "&" confirm-before "kill-window"
also quiet, utf8 and maybe other flags?
-g is a bit unexpected in conf file
- clear window title on exit
- refer to windows by name etc (duplicates? fnmatch?)
- the output code (tty.c) could do with optimisation depending on term
capibilities
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- goto line and search history in copy/scroll modes
- a command to display the status line briefly when it is turned off
- clone session command
- make command sequences more usable: don't require space after ;, handle
errors better
- might be nice if attach-session behaved like switch-client inside an
existing client
- key to switch to copy mode from scroll mode
- attach should have a flag to create session if it doesn't exist
- 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!
** NEW layout design:
1. finish rewrite manual with tree of layout_cell
2. convert automatic layout modes to produce a tree and make
them one-off operations
3. move any size/position details from window_pane to layout_cell
3.5. fix -p/-l on split
4. a way to address panes by name ("top-left") and position ("0,0")
TO TEST: force-width/height OK, respawn-window, rotate-window OK, break-pane??
** rename split-window -> split-pane
- fix UTF-8 guesswork on sparc64, improve tty checks
- choice and more mode would be better per client than per window?
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
- close/redirect stderr when popen to child proc for #() in status line
- if-shell-command command to run a tmux command if a shell command returns true
- hooks to which commands may be attached, for example:
tmux add-hook "new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file $HOME/.tmux-session.conf
- get it passing all the vttest tests that don't require resizing the terminal
- does tmux require a exmple conf? where does it go?
- there are an awful lot of commands. maybe separate man page for conf
file/commands -similar to ssh/ssh_config?
- esc seq to set window title should be documented and should set automatic-rename
- *** get rid of PANE_HIDDEN -- initially just check for outside window
- way to set socket path from config file
- the "window with one pane" vs window distinction is weird, eg you can't kill-pane the last pane

6
arg.c
View File

@@ -1,4 +1,4 @@
/* $Id: arg.c,v 1.5 2008-08-28 17:45:25 nicm Exp $ */
/* $Id: arg.c,v 1.6 2009-06-25 15:25:45 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -76,7 +76,7 @@ arg_parse_client(const char *arg)
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (arg2[n - 1] == ':')
if (n && arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* Try and look up the client name. */
@@ -101,7 +101,7 @@ arg_parse_session(const char *arg)
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (arg2[n - 1] == ':')
if (n && arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* See if the argument matches a session. */

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.2 2009-06-25 15:25:45 nicm Exp $ */
/*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -45,7 +45,8 @@ attributes_tostring(u_char ch)
strlcat(buf, "hidden,", sizeof (buf));
if (ch & GRID_ATTR_ITALICS)
strlcat(buf, "italics,", sizeof (buf));
*(strrchr(buf, ',')) = '\0';
if (*buf)
*(strrchr(buf, ',')) = '\0';
return (buf);
}

View File

@@ -1,4 +1,4 @@
/* $Id: buffer-poll.c,v 1.10 2008-09-09 22:16:36 nicm Exp $ */
/* $Id: buffer-poll.c,v 1.14 2009-06-25 16:22:36 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,39 +23,19 @@
#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
#ifdef HAVE_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) {
@@ -66,9 +46,6 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
}
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);
@@ -77,23 +54,3 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
}
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;
}
}

View File

@@ -1,4 +1,4 @@
/* $Id: buffer.c,v 1.5 2008-08-07 20:20:52 nicm Exp $ */
/* $Id: buffer.c,v 1.7 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,14 +47,6 @@ buffer_destroy(struct buffer *b)
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)
@@ -91,18 +83,6 @@ buffer_add(struct buffer *b, size_t size)
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)
@@ -116,50 +96,6 @@ buffer_remove(struct buffer *b, size_t 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)
@@ -194,16 +130,6 @@ buffer_write8(struct buffer *b, uint8_t 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)
@@ -214,14 +140,3 @@ buffer_read8(struct buffer *b)
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);
}

14
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.18 2009-06-25 16:21:32 nicm 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,7 +30,6 @@
* 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 *, ...);
@@ -55,11 +55,21 @@ load_cfg(const char *path, char **cause)
{
FILE *f;
u_int n;
struct stat sb;
char *buf, *line, *ptr;
size_t len;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
if (stat(path, &sb) != 0) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (-1);
}
if (!S_ISREG(sb.st_mode)) {
xasprintf(cause, "%s: not a regular file", path);
return (-1);
}
if ((f = fopen(path, "rb")) == NULL) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (1);

View File

@@ -1,4 +1,4 @@
/* $Id: client-msg.c,v 1.18 2009-01-21 22:47:31 nicm Exp $ */
/* $Id: client-msg.c,v 1.19 2009-06-25 15:25:45 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -73,7 +73,7 @@ client_msg_dispatch(struct client_ctx *cctx, char **error)
int
client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
{
if (hdr->size > SIZE_MAX - 1)
if (hdr->size == SIZE_MAX)
fatalx("bad MSG_ERROR size");
*error = xmalloc(hdr->size + 1);

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.53 2009-07-01 23:06:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,6 +46,15 @@ client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
int mode;
struct buffer *b;
char *name;
#ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
#endif
#ifdef HAVE_SETPROCTITLE
if (realpath(path, rpathbuf) == NULL)
strlcpy(rpathbuf, path, sizeof rpathbuf);
setproctitle("client (%s)", rpathbuf);
#endif
if (lstat(path, &sb) != 0) {
if (start_server && errno == ENOENT) {
@@ -135,12 +144,8 @@ client_main(struct client_ctx *cctx)
siginit();
logfile("client");
#ifndef NO_SETPROCTITLE
setproctitle("client");
#endif
error = NULL;
xtimeout = INFTIM;
while (!sigterm) {
if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG);
@@ -150,7 +155,7 @@ client_main(struct client_ctx *cctx)
client_handle_winch(cctx);
if (sigcont) {
siginit();
client_write_server(cctx, MSG_WAKEUP, NULL, 0);
client_write_server(cctx, MSG_WAKEUP, NULL, 0);
sigcont = 0;
}

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.4 2009-05-04 17:58:25 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -125,7 +125,7 @@ clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
screen_write_puts(ctx, &gc, "%s", tim);
}
return;
}
}
x = (screen_size_x(s) / 2) - 3 * strlen(tim);
y = (screen_size_y(s) / 2) - 3;

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.26 2009-06-25 16:34:50 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -45,7 +45,7 @@ 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);
@@ -77,4 +77,3 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (1);
}

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.21 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -65,7 +65,7 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
case 'r':
data->can_repeat = 1;
break;
default:
default:
goto usage;
}
}

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.3 2009-05-18 21:01:38 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -50,7 +50,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_pane *wp;
struct window *w;
char *cause;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
if (data->pane == -1)
@@ -74,18 +74,18 @@ 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_refresh(wl->window, 0);
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);
wl = session_attach(s, w, -1, &cause); /* can't fail */
if (!(data->flags & CMD_DFLAG))
session_select(s, wl->idx);
layout_refresh(w, 0);
server_redraw_session(s);
return (0);

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.7 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -61,7 +61,7 @@ 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);

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.9 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,7 +63,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);
@@ -76,8 +76,8 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
idx++;
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 [%ux%u %s] (%u panes)", wm->idx, w->name,
w->sx, w->sy, layout_name(w), window_count_panes(w));
}
cdata = xmalloc(sizeof *cdata);

67
cmd-clear-history.c Normal file
View File

@@ -0,0 +1,67 @@
/* $Id: cmd-clear-history.c,v 1.3 2009-06-25 16:21:32 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 "tmux.h"
/*
* 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_PANE_WINDOW_USAGE,
0,
cmd_pane_init,
cmd_pane_parse,
cmd_clear_history_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
};
int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct grid *gd;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy);
gd->hsize = 0;
return (0);
}

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

@@ -0,0 +1,141 @@
/* $Id: cmd-confirm-before.c,v 1.4 2009-04-28 18:29:44 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 *);
struct cmd_confirm_before_data {
struct client *c;
char *cmd;
};
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_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
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(unused 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, 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 || tolower((u_char) s[0]) != 'y' || s[1] != '\0')
goto out;
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, cause);
xfree(cause);
}
goto out;
}
ctx.msgdata = NULL;
ctx.cursession = c->session;
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);
out:
if (cdata->cmd != NULL)
xfree(cdata->cmd);
xfree(cdata);
return (0);
}

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.19 2009-07-01 23:06:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,13 +44,15 @@ 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)
return (-1);
wp = wl->window->active;
window_pane_set_mode(wl->window->active, &window_copy_mode);
if (data->flags & CMD_UFLAG)
window_copy_pageup(wl->window->active);
window_pane_set_mode(wp, &window_copy_mode);
if (wp->mode == &window_copy_mode && data->flags & CMD_UFLAG)
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.5 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -56,6 +56,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-find-window.c,v 1.6 2009-03-29 11:18:28 nicm Exp $ */
/* $Id: cmd-find-window.c,v 1.10 2009-06-25 16:21:32 nicm 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,7 +30,6 @@
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 *);
const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw",
@@ -59,8 +59,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 +70,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 +127,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,
@@ -159,46 +163,3 @@ cmd_find_window_callback(void *data, int idx)
}
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.28 2009-05-21 19:47:57 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,8 +24,8 @@
#include "tmux.h"
#define CMD_FLAGS "adDgkuU"
#define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_UPPERDFLAG|CMD_GFLAG|CMD_KFLAG| \
CMD_UFLAG|CMD_UPPERUFLAG)
#define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_BIGDFLAG|CMD_GFLAG|CMD_KFLAG| \
CMD_UFLAG|CMD_BIGUFLAG)
int cmd_do_flags(int, int, int *);
size_t cmd_print_flags(char *, size_t, size_t, int);
@@ -34,7 +34,7 @@ int cmd_fill_argument(int, 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));
}
@@ -56,8 +56,8 @@ cmd_do_flags(int opt, int iflags, int *oflags)
}
return (-1);
case 'D':
if (iflags & CMD_UPPERDFLAG) {
(*oflags) |= CMD_UPPERDFLAG;
if (iflags & CMD_BIGDFLAG) {
(*oflags) |= CMD_BIGDFLAG;
return (0);
}
return (-1);
@@ -80,8 +80,8 @@ cmd_do_flags(int opt, int iflags, int *oflags)
}
return (-1);
case 'U':
if (iflags & CMD_UPPERUFLAG) {
(*oflags) |= CMD_UPPERUFLAG;
if (iflags & CMD_BIGUFLAG) {
(*oflags) |= CMD_BIGUFLAG;
return (0);
}
return (-1);
@@ -99,7 +99,7 @@ cmd_print_flags(char *buf, size_t len, size_t off, int flags)
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)
if (off < len && flags & CMD_BIGDFLAG)
off += xsnprintf(buf + off, len - off, "D");
if (off < len && flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, "d");
@@ -109,7 +109,7 @@ cmd_print_flags(char *buf, size_t len, size_t off, int flags)
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)
if (off < len && flags & CMD_BIGUFLAG)
off += xsnprintf(buf + off, len - off, "U");
return (off - boff);
}
@@ -618,7 +618,7 @@ cmd_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
goto error;
}
data->pane = n;
}
}
break;
case 't':
if (data->target == NULL)

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.7 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,7 +47,7 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_pane_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (data->pane == -1)

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.16 2009-06-25 16:34:50 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,14 +47,20 @@ 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-keys.c,v 1.13 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-list-keys.c,v 1.14 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -49,7 +49,7 @@ cmd_list_keys_exec(unused struct cmd *self, struct cmd_ctx *ctx)
SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
if ((key = key_string_lookup_key(bd->key)) == NULL)
continue;
*tmp = '\0';
cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
ctx->print(ctx, "%11s: %s", key, tmp);

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.35 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,7 +48,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct window_pane *wp;
struct grid *gd;
u_int i;
unsigned long long size;
@@ -64,7 +64,7 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
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;
@@ -76,10 +76,11 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
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);
name = "unknown";
ctx->print(ctx,
" %s [%ux%u %s] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, layout_name(w), gd->hsize,
gd->hlimit, size);
}
}

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.5 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,29 +28,44 @@ 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 **new_argv;
cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist);
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(argv[i]);
if (arglen == 0 || argv[i][arglen - 1] != ';')
continue;
argv[i][arglen - 1] = '\0';
if (arglen > 1 && argv[i][arglen - 2] == '\\') {
argv[i][arglen - 2] = ';';
continue;
}
new_argc = i - lastsplit;
new_argv = argv + lastsplit;
if (arglen != 1)
new_argc++;
cmd = cmd_parse(new_argc, new_argv, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
lastsplit = i + 1;
}
if (lastsplit != argc) {
cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
}
cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
return (cmdlist);
bad:
@@ -110,7 +125,7 @@ void
cmd_list_free(struct cmd_list *cmdlist)
{
struct cmd *cmd;
while (!TAILQ_EMPTY(cmdlist)) {
cmd = TAILQ_FIRST(cmdlist);
TAILQ_REMOVE(cmdlist, cmd, qentry);

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.4 2009-05-21 19:38:51 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -62,8 +62,12 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
if (!S_ISREG(statbuf.st_mode)) {
ctx->error(ctx, "%s: not a regular file", data->arg);
return (-1);
}
if ((f = fopen(data->arg, "r")) == NULL) {
if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}

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.4 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,8 +30,6 @@
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",
"",

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.41 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -118,7 +118,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if (ctx->curclient != NULL)
return (0);
if (!data->flag_detached) {
if (c == NULL) {
ctx->error(ctx, "no client to attach to");

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.2 2009-04-30 21:17:06 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -49,6 +49,7 @@ cmd_next_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
layout_next(wl->window);
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
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.17 2009-06-25 15:29:34 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ 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,
"[-a] " CMD_TARGET_SESSION_USAGE,
CMD_AFLAG,
cmd_next_window_init,
cmd_target_parse,

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.16 2009-07-02 16:23:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,7 +63,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (pb != NULL)
if (pb != NULL && *pb->data != '\0')
buffer_write(w->active->out, pb->data, strlen(pb->data));
/* Delete the buffer if -d. */

View File

@@ -1,4 +1,4 @@
/* $Id: util.c,v 1.1 2009-01-18 17:20:52 nicm Exp $ */
/* $Id: cmd-previous-layout.c,v 1.1 2009-04-30 21:17:06 nicm 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)
/*
* Switch window to previous layout.
*/
int cmd_previous_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl",
CMD_TARGET_WINDOW_USAGE,
0,
cmd_target_init,
cmd_target_parse,
cmd_previous_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
int
cmd_previous_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{
char *s;
size_t first, last;
struct cmd_target_data *data = self->data;
struct winlink *wl;
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 ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (last - first > 3 && first != 0)
first += 3;
if (last - first > 3 && last != len)
last -= 3;
layout_previous(wl->window);
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
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-previous-window.c,v 1.16 2009-03-28 14:08:09 nicm Exp $ */
/* $Id: cmd-previous-window.c,v 1.17 2009-06-25 15:29:34 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ 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,
"[-a] " CMD_TARGET_SESSION_USAGE,
CMD_AFLAG,
cmd_previous_window_init,
cmd_target_parse,

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.27 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -53,7 +53,7 @@ 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);

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,4 +1,4 @@
/* $Id: cmd-resize-pane-up.c,v 1.8 2009-04-02 21:11:52 nicm Exp $ */
/* $Id: cmd-resize-pane.c,v 1.7 2009-05-21 19:46:00 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,19 +23,19 @@
#include "tmux.h"
/*
* Increase pane size.
* Increase or decrease pane size.
*/
void cmd_resize_pane_up_init(struct cmd *, int);
int cmd_resize_pane_up_exec(struct cmd *, struct cmd_ctx *);
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_up_entry = {
"resize-pane-up", "resizep-up",
CMD_PANE_WINDOW_USAGE " [adjustment]",
CMD_ARG01,
cmd_resize_pane_up_init,
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
CMD_PANE_WINDOW_USAGE "[-DU] [adjustment]",
CMD_ARG01|CMD_BIGUFLAG|CMD_BIGDFLAG,
cmd_resize_pane_init,
cmd_pane_parse,
cmd_resize_pane_up_exec,
cmd_resize_pane_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
@@ -43,32 +43,35 @@ const struct cmd_entry cmd_resize_pane_up_entry = {
};
void
cmd_resize_pane_up_init(struct cmd *self, int key)
cmd_resize_pane_init(struct cmd *self, int key)
{
struct cmd_pane_data *data;
cmd_pane_init(self, key);
data = self->data;
if (key == KEYC_ADDCTL(KEYC_DOWN))
data->flags |= CMD_BIGDFLAG;
if (key == KEYC_ADDESC(KEYC_UP))
data->arg = xstrdup("5");
if (key == KEYC_ADDESC(KEYC_DOWN)) {
data->flags |= CMD_BIGDFLAG;
data->arg = xstrdup("5");
}
}
int
cmd_resize_pane_up_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_resize_pane_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;
struct window_pane *wp;
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 {
@@ -89,28 +92,13 @@ cmd_resize_pane_up_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
/*
* 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);
if (!(data->flags & CMD_BIGDFLAG))
adjust = -adjust;
if (layout_resize(wp, adjust) != 0) {
ctx->error(ctx, "layout %s "
"does not support resizing", layout_name(wp->window));
return (-1);
}
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);

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.4 2009-06-25 15:28:08 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew",
"[-DU] " CMD_TARGET_WINDOW_USAGE,
CMD_UPPERUFLAG|CMD_UPPERDFLAG,
CMD_BIGUFLAG|CMD_BIGDFLAG,
cmd_rotate_window_init,
cmd_target_parse,
cmd_rotate_window_exec,
@@ -49,7 +49,7 @@ cmd_rotate_window_init(struct cmd *self, int key)
data = self->data;
if (key == KEYC_ADDESC('o'))
data->flags |= CMD_UPPERDFLAG;
data->flags |= CMD_BIGDFLAG;
}
int
@@ -60,25 +60,31 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w;
struct window_pane *wp, *wp2;
u_int sx, sy, xoff, yoff;
int flags;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
w = wl->window;
if (data->flags & CMD_UPPERDFLAG) {
if (data->flags & CMD_BIGDFLAG) {
wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH(wp, &w->panes, entry) {
if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL)
break;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy);
}
wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
@@ -91,13 +97,18 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) {
if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL)
break;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy);
}
wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)

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.5 2009-05-18 16:22:30 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -69,9 +69,9 @@ 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");
f = fopen(data->arg, "ab");
else
f = fopen(data->arg, "w");
f = fopen(data->arg, "wb");
if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-scroll-mode.c,v 1.16 2009-01-27 23:35:44 nicm Exp $ */
/* $Id: cmd-scroll-mode.c,v 1.19 2009-07-01 23:06:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -60,13 +60,15 @@ cmd_scroll_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)
return (-1);
wp = wl->window->active;
window_pane_set_mode(wl->window->active, &window_scroll_mode);
if (data->flags & CMD_UFLAG)
window_scroll_pageup(wl->window->active);
window_pane_set_mode(wp, &window_scroll_mode);
if (wp->mode == &window_scroll_mode && data->flags & CMD_UFLAG)
window_scroll_pageup(wp);
return (0);
}

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

@@ -0,0 +1,86 @@
/* $Id: cmd-select-layout.c,v 1.3 2009-06-25 16:34:50 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 "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_ARG1,
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
cmd_target_send,
cmd_target_recv,
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 KEYC_ADDESC('0'):
data->arg = xstrdup("manual-vertical");
break;
case KEYC_ADDESC('1'):
data->arg = xstrdup("even-horizontal");
break;
case KEYC_ADDESC('2'):
data->arg = xstrdup("even-vertical");
break;
case KEYC_ADDESC('9'):
data->arg = xstrdup("active-only");
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 ((layout = layout_lookup(data->arg)) == -1) {
ctx->error(ctx, "unknown or ambiguous layout: %s", data->arg);
return (-1);
}
if (layout_select(wl->window, layout) == 0)
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
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.20 2009-06-25 20:27:31 nicm 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"
@@ -60,7 +59,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct utsname un;
struct grid *gd;
u_int i, j, k;
char out[BUFSIZ];
char out[80];
char *tim;
time_t t;
u_int lines, ulines;
@@ -68,7 +67,7 @@ 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" : "");
@@ -91,9 +90,9 @@ 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,
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x]", i, c->tty.path, c->fd, c->tty.fd,
c->session->name, c->tty.sx, c->tty.sy, c->tty.termname,
c->flags, c->tty.flags);
}
ctx->print(ctx, "");
@@ -109,14 +108,15 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
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),
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x]", i, s->name, winlink_count(&s->windows),
tim, s->sx, s->sy, s->flags);
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, layout=%u]", wl->idx, w->name,
w->sx, w->sy, w->flags, w->references,
w->layout);
j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0;
@@ -133,8 +133,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
sizeof (**gd->udata);
}
}
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);
@@ -157,10 +157,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;

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.62 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -73,6 +73,7 @@ const struct set_option_entry set_option_table[NSETOPTION] = {
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
};
int

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-password.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* $Id: cmd-set-password.c,v 1.5 2009-06-25 16:47:00 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>

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.28 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,12 +27,7 @@
* Set a window option.
*/
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",
@@ -61,11 +56,13 @@ const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-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 },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },

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.15 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -141,7 +141,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_pane *wp;
const char **env;
char *cmd, *cwd, *cause;
u_int hlimit, lines;
u_int hlimit;
int lines;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
@@ -171,7 +172,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
server_redraw_window(w);
if (!data->flag_detached) {
window_set_active_pane(w, wp);
session_select(s, wl->idx);

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.17 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,7 +63,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
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) {
if (putenv(xstrdup(s)) != 0) {
xasprintf(cause, "assignment failed: %s", s);
return (-1);
}
@@ -274,7 +274,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;

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.6 2009-06-25 15:28:08 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -111,7 +111,7 @@ cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
goto error;
}
data->src = n;
}
}
break;
case 'q':
if (data->dst == -1) {
@@ -124,7 +124,7 @@ cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
}
data->flag_up = 0;
data->flag_down = 0;
break;
break;
case 'U':
data->flag_up = 1;
data->flag_down = 0;
@@ -158,6 +158,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w;
struct window_pane *tmp_wp, *src_wp, *dst_wp;
u_int xx, yy;
int flags;
if (data == NULL)
return (0);
@@ -195,7 +196,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
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);
@@ -209,10 +210,15 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
xx = src_wp->xoff;
yy = src_wp->yoff;
flags = src_wp->flags;
src_wp->xoff = dst_wp->xoff;
src_wp->yoff = dst_wp->yoff;
src_wp->flags &= ~PANE_HIDDEN;
src_wp->flags |= dst_wp->flags & PANE_HIDDEN;
dst_wp->xoff = xx;
dst_wp->yoff = yy;
dst_wp->flags &= ~PANE_HIDDEN;
dst_wp->flags |= flags & PANE_HIDDEN;
xx = src_wp->sx;
yy = src_wp->sy;
@@ -220,7 +226,10 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
window_pane_resize(dst_wp, xx, yy);
if (!data->flag_detached) {
window_set_active_pane(w, dst_wp);
tmp_wp = dst_wp;
if (tmp_wp->flags & PANE_HIDDEN)
tmp_wp = src_wp;
window_set_active_pane(w, tmp_wp);
layout_refresh(w, 0);
}

15
cmd.c
View File

@@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.89 2009-04-03 17:21:46 nicm Exp $ */
/* $Id: cmd.c,v 1.97 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,8 +31,10 @@ const struct cmd_entry *cmd_table[] = {
&cmd_break_pane_entry,
&cmd_choose_session_entry,
&cmd_choose_window_entry,
&cmd_clear_history_entry,
&cmd_clock_mode_entry,
&cmd_command_prompt_entry,
&cmd_confirm_before_entry,
&cmd_copy_buffer_entry,
&cmd_copy_mode_entry,
&cmd_delete_buffer_entry,
@@ -60,16 +62,17 @@ const struct cmd_entry *cmd_table[] = {
&cmd_next_layout_entry,
&cmd_next_window_entry,
&cmd_paste_buffer_entry,
&cmd_previous_layout_entry,
&cmd_previous_window_entry,
&cmd_refresh_client_entry,
&cmd_rename_session_entry,
&cmd_rename_window_entry,
&cmd_resize_pane_down_entry,
&cmd_resize_pane_up_entry,
&cmd_respawn_window_entry,
&cmd_resize_pane_entry,
&cmd_respawn_window_entry,
&cmd_rotate_window_entry,
&cmd_save_buffer_entry,
&cmd_scroll_mode_entry,
&cmd_select_layout_entry,
&cmd_select_pane_entry,
&cmd_select_prompt_entry,
&cmd_select_window_entry,
@@ -105,8 +108,10 @@ cmd_parse(int argc, char **argv, char **cause)
int opt;
*cause = NULL;
if (argc == 0)
if (argc == 0) {
xasprintf(cause, "no command");
return (NULL);
}
entry = NULL;
for (entryp = cmd_table; *entryp != NULL; entryp++) {

View File

@@ -1,4 +1,4 @@
/* $Id: colour.c,v 1.5 2009-03-07 10:29:06 nicm Exp $ */
/* $Id: colour.c,v 1.6 2009-05-18 15:42:30 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,7 +48,6 @@ colour_tostring(u_char c)
return (NULL);
}
/* String to colour. */
int
colour_fromstring(const char *s)
{

228
compat.h Normal file
View File

@@ -0,0 +1,228 @@
/* $Id: compat.h,v 1.6 2009-07-02 07:30:59 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.
*/
#ifndef HAVE_PATHS_H
#define _PATH_BSHELL "/bin/sh"
#define _PATH_TMP "/tmp/"
#define _PATH_DEVNULL "/dev/null"
#define _PATH_TTY "/dev/tty"
#endif
#ifdef HAVE_QUEUE_H
#include <sys/queue.h>
#else
#include "compat/queue.h"
#endif
#ifdef HAVE_TREE_H
#include <sys/tree.h>
#else
#include "compat/tree.h"
#endif
#ifdef HAVE_BITSTRING_H
#include <bitstring.h>
#else
#include "compat/bitstring.h"
#endif
#ifdef HAVE_POLL
#include <poll.h>
#else
#include "compat/bsd-poll.h"
#endif
#ifdef HAVE_GETOPT
#include <getopt.h>
#endif
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_FORKPTY
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#endif
#ifdef HAVE_VIS
#include <vis.h>
#else
#include "compat/vis.h"
#endif
#ifndef INFTIM
#define INFTIM -1
#endif
#ifndef WAIT_ANY
#define WAIT_ANY -1
#endif
#ifndef SUN_LEN
#define SUN_LEN(sun) (sizeof (sun)->sun_path)
#endif
#ifndef __dead
#define __dead __attribute__ ((__noreturn__))
#endif
#ifndef __packed
#define __packed __attribute__ ((__packed__))
#endif
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#ifndef timeradd
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#endif
#ifndef TTY_NAME_MAX
#define TTY_NAME_MAX 32
#endif
#ifndef HAVE_STRCASESTR
/* strcasestr.c */
char *strcasestr(const char *, const char *);
#endif
#ifndef HAVE_STRTONUM
/* strtonum.c */
long long strtonum(const char *, long long, long long, const char **);
#endif
#ifndef HAVE_STRLCPY
/* strlcpy.c */
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
/* strlcat.c */
size_t strlcat(char *, const char *, size_t);
#endif
#ifndef HAVE_DAEMON
/* daemon.c */
int daemon(int, int);
#endif
#ifndef HAVE_FORKPTY
/* forkpty.c */
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
#ifndef HAVE_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_GETOPT
/* getopt.c */
extern int BSDopterr;
extern int BSDoptind;
extern int BSDoptopt;
extern int BSDoptreset;
extern char *BSDoptarg;
int BSDgetopt(int, char *const *, const char *);
#define getopt(ac, av, o) BSDgetopt(ac, av, o)
#define opterr BSDopterr
#define optind BSDoptind
#define optopt BSDoptopt
#define optreset BSDoptreset
#define optarg BSDoptarg
#endif
#ifndef HAVE_STRTONUM
/* strtonum.c */
long long strtonum(const char *, long long, long long, const char **);
#endif
#ifndef HAVE_STRLCPY
/* strlcpy.c */
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
/* strlcat.c */
size_t strlcat(char *, const char *, size_t);
#endif
#ifndef HAVE_DAEMON
/* daemon.c */
int daemon(int, int);
#endif
#ifndef HAVE_FORKPTY
/* forkpty.c */
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
#ifndef HAVE_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_GETOPT
/* getopt.c */
extern int BSDopterr;
extern int BSDoptind;
extern int BSDoptopt;
extern int BSDoptreset;
extern char *BSDoptarg;
int BSDgetopt(int, char *const *, const char *);
#define getopt(ac, av, o) BSDgetopt(ac, av, o)
#define opterr BSDopterr
#define optind BSDoptind
#define optopt BSDoptopt
#define optreset BSDoptreset
#define optarg BSDoptarg
#endif

129
compat/bitstring.h Normal file
View File

@@ -0,0 +1,129 @@
/* $Id: bitstring.h,v 1.1 2009-06-25 17:02:59 nicm Exp $ */
/* $OpenBSD: bitstring.h,v 1.5 2003/06/02 19:34:12 millert Exp $ */
/* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Paul Vixie.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bitstring.h 8.1 (Berkeley) 7/19/93
*/
#ifndef _BITSTRING_H_
#define _BITSTRING_H_
/* modified for SV/AT and bitstring bugfix by M.R.Murphy, 11oct91
* bitstr_size changed gratuitously, but shorter
* bit_alloc spelling error fixed
* the following were efficient, but didn't work, they've been made to
* work, but are no longer as efficient :-)
* bit_nclear, bit_nset, bit_ffc, bit_ffs
*/
typedef unsigned char bitstr_t;
/* internal macros */
/* byte of the bitstring bit is in */
#define _bit_byte(bit) \
((bit) >> 3)
/* mask for the bit within its byte */
#define _bit_mask(bit) \
(1 << ((bit)&0x7))
/* external macros */
/* bytes in a bitstring of nbits bits */
#define bitstr_size(nbits) \
(((nbits) + 7) >> 3)
/* allocate a bitstring */
#define bit_alloc(nbits) \
(bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
/* allocate a bitstring on the stack */
#define bit_decl(name, nbits) \
((name)[bitstr_size(nbits)])
/* is bit N of bitstring name set? */
#define bit_test(name, bit) \
((name)[_bit_byte(bit)] & _bit_mask(bit))
/* set bit N of bitstring name */
#define bit_set(name, bit) \
((name)[_bit_byte(bit)] |= _bit_mask(bit))
/* clear bit N of bitstring name */
#define bit_clear(name, bit) \
((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
/* clear bits start ... stop in bitstring */
#define bit_nclear(name, start, stop) do { \
register bitstr_t *_name = name; \
register int _start = start, _stop = stop; \
while (_start <= _stop) { \
bit_clear(_name, _start); \
_start++; \
} \
} while(0)
/* set bits start ... stop in bitstring */
#define bit_nset(name, start, stop) do { \
register bitstr_t *_name = name; \
register int _start = start, _stop = stop; \
while (_start <= _stop) { \
bit_set(_name, _start); \
_start++; \
} \
} while(0)
/* find first bit clear in name */
#define bit_ffc(name, nbits, value) do { \
register bitstr_t *_name = name; \
register int _bit, _nbits = nbits, _value = -1; \
for (_bit = 0; _bit < _nbits; ++_bit) \
if (!bit_test(_name, _bit)) { \
_value = _bit; \
break; \
} \
*(value) = _value; \
} while(0)
/* find first bit set in name */
#define bit_ffs(name, nbits, value) do { \
register bitstr_t *_name = name; \
register int _bit, _nbits = nbits, _value = -1; \
for (_bit = 0; _bit < _nbits; ++_bit) \
if (bit_test(_name, _bit)) { \
_value = _bit; \
break; \
} \
*(value) = _value; \
} while(0)
#endif /* !_BITSTRING_H_ */

View File

@@ -1,4 +1,4 @@
/* $Id: bsd-poll.c,v 1.1 2008-08-28 17:45:30 nicm Exp $ */
/* $Id: bsd-poll.c,v 1.2 2009-05-13 23:50:42 nicm Exp $ */
/*
* Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au).
@@ -29,7 +29,8 @@
#include <stdlib.h>
#include <errno.h>
#include "bsd-poll.h"
#include "compat/bsd-poll.h"
/*
* A minimal implementation of poll(2), built on top of select(2).

View File

@@ -27,7 +27,6 @@
/* OPENBSD ORIGINAL: sys/sys/poll.h */
#if !defined(HAVE_POLL) && !defined(HAVE_POLL_H)
#ifndef _COMPAT_POLL_H_
#define _COMPAT_POLL_H_
@@ -58,4 +57,3 @@ typedef unsigned int nfds_t;
int poll(struct pollfd *, nfds_t, int);
#endif /* !_COMPAT_POLL_H_ */
#endif /* !HAVE_POLL_H */

View File

@@ -32,7 +32,7 @@
#include <unistd.h>
#include <stdlib.h>
#ifndef NO_PATHS_H
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif

View File

@@ -1,3 +1,4 @@
/* $Id: fgetln.c,v 1.5 2009-04-29 22:45:32 nicm Exp $ */
/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
/*-

View File

@@ -1,83 +0,0 @@
/* $Id: forkpty-irix.c,v 1.2 2008-09-26 06:45:28 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 <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
pid_t
forkpty(int *master,
unused char *name, unused struct termios *tio, struct winsize *ws)
{
int slave, fd;
char *path;
pid_t pid;
void *old;
path = _getpty(master, O_RDWR, 0622, 0);
if (path == NULL)
goto out;
if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
goto out;
switch (pid = fork()) {
case -1:
goto out;
case 0:
close(*master);
setsid();
old = signal(SIGHUP, SIG_IGN);
vhangup();
signal(SIGHUP, old);
if ((fd = open(path, O_RDWR)) == -1)
fatal("open failed");
close(slave);
slave = fd;
if (ioctl(slave, TIOCSWINSZ, ws) == -1)
fatal("ioctl failed");
dup2(slave, 0);
dup2(slave, 1);
dup2(slave, 2);
if (slave > 2)
close(slave);
return (0);
}
close(slave);
return (pid);
out:
if (*master != -1)
close(*master);
if (slave != -1)
close(slave);
return (-1);
}

117
compat/getopt.c Normal file
View File

@@ -0,0 +1,117 @@
/* $Id: getopt.c,v 1.1 2009-05-13 22:20:48 nicm Exp $ */
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */
#include "tmux.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int BSDopterr = 1, /* if error message should be printed */
BSDoptind = 1, /* index into parent argv vector */
BSDoptopt, /* character checked for validity */
BSDoptreset; /* reset getopt */
char *BSDoptarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
BSDgetopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (ostr == NULL)
return (-1);
if (BSDoptreset || !*place) { /* update scanning pointer */
BSDoptreset = 0;
if (BSDoptind >= nargc || *(place = nargv[BSDoptind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++BSDoptind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((BSDoptopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, BSDoptopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (BSDoptopt == (int)'-')
return (-1);
if (!*place)
++BSDoptind;
if (BSDopterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname, BSDoptopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
BSDoptarg = NULL;
if (!*place)
++BSDoptind;
}
else { /* need an argument */
if (*place) /* no white space */
BSDoptarg = place;
else if (nargc <= ++BSDoptind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (BSDopterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__progname, BSDoptopt);
return (BADCH);
}
else /* white space */
BSDoptarg = nargv[BSDoptind];
place = EMSG;
++BSDoptind;
}
return (BSDoptopt); /* dump back option letter */
}

View File

@@ -1,76 +0,0 @@
/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GETOPT_H_
#define _GETOPT_H_
#include <sys/cdefs.h>
/*
* GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
*/
#define no_argument 0
#define required_argument 1
#define optional_argument 2
struct option {
/* name of long option */
const char *name;
/*
* one of no_argument, required_argument, and optional_argument:
* whether option takes an argument
*/
int has_arg;
/* if not NULL, set *flag to val when option found */
int *flag;
/* if flag not NULL, value to set *flag to; else return value */
int val;
};
int getopt_long(int, char * const *, const char *,
const struct option *, int *);
int getopt_long_only(int, char * const *, const char *,
const struct option *, int *);
#ifndef _GETOPT_DEFINED_
#define _GETOPT_DEFINED_
int getopt(int, char * const *, const char *);
int getsubopt(char **, char * const *, char **);
extern char *optarg; /* getopt(3) external variables */
extern int opterr;
extern int optind;
extern int optopt;
extern int optreset;
extern char *suboptarg; /* getsubopt(3) external variable */
#endif
#endif /* !_GETOPT_H_ */

View File

@@ -1,523 +0,0 @@
/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF 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.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* #include <err.h> */
#include <errno.h>
/* #include <getopt.h> */
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
int
warnx(const char *fmt, ...)
{
}
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
#ifdef REPLACE_GETOPT
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#endif
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#define EMSG ""
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too)
{
char *current_argv, *has_equal;
size_t current_argv_len;
int i, match;
current_argv = place;
match = -1;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* partial match */
match = i;
else {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig, (int)current_argv_len,
current_argv);
optopt = 0;
return (BADCH);
}
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
return (BADARG);
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return (-1);
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*/
if (posixly_correct == -1)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
else if (*options == '-')
flags |= FLAG_ALLARGS;
if (*options == '+' || *options == '-')
options++;
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*place == '-')
place++; /* --foo long option */
else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or ':').
*/
if (optchar == (int)'-' && *place == '\0')
return (-1);
if (!*place)
++optind;
if (PRINT_ERROR)
warnx(illoptchar, optchar);
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
optchar = parse_long_options(nargv, options, long_options,
idx, 0);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
#ifdef REPLACE_GETOPT
/*
* getopt --
* Parse argc/argv argument vector.
*
* [eventually this will replace the BSD getopt]
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#endif /* REPLACE_GETOPT */
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}

61
compat/strcasestr.c Normal file
View File

@@ -0,0 +1,61 @@
/* $Id: strcasestr.c,v 1.1 2009-07-02 07:31:02 nicm Exp $ */
/* $OpenBSD: strcasestr.c,v 1.3 2006/03/31 05:34:55 deraadt Exp $ */
/* $NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <ctype.h>
#include <string.h>
/*
* Find the first occurrence of find in s, ignore case.
*/
char *
strcasestr(const char *s, const char *find)
{
char c, sc;
size_t len;
if ((c = *find++) != 0) {
c = (char)tolower((unsigned char)c);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
} while ((char)tolower((unsigned char)sc) != c);
} while (strncasecmp(s, find, len) != 0);
s--;
}
return ((char *)s);
}

View File

@@ -1,4 +1,5 @@
/* $OpenBSD: tree.h,v 1.11 2008/05/11 22:19:09 millert Exp $ */
/* $Id: tree.h,v 1.4 2009-05-26 18:31:10 nicm Exp $ */
/* $OpenBSD: tree.h,v 1.12 2009/03/02 09:42:55 mikeb Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -329,7 +330,7 @@ struct { \
} while (0)
#ifndef RB_AUGMENT
#define RB_AUGMENT(x)
#define RB_AUGMENT(x) do {} while (0)
#endif
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \

View File

@@ -32,7 +32,8 @@
#include <limits.h>
#include <ctype.h>
#include <string.h>
#include <vis.h>
#include "tmux.h"
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define isvisible(c) \

View File

@@ -1,3 +1,4 @@
/* $Id: vis.h,v 1.5 2009-07-01 23:22:46 nicm Exp $ */
/* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */
/* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */
@@ -71,8 +72,6 @@
*/
#define UNVIS_END 1 /* no more characters */
#include <sys/cdefs.h>
char *vis(char *, int, int, int);
int strvis(char *, const char *, int);
int strnvis(char *, const char *, size_t, int);

216
configure vendored Executable file
View File

@@ -0,0 +1,216 @@
#!/bin/sh
# $Id: configure,v 1.17 2009-07-02 07:31:01 nicm Exp $
TMUX_PLATFORM=${TMUX_PLATFORM:-`uname -s`}
CONFIG_H=config.h
rm -f $CONFIG_H
echo "/* $TMUX_PLATFORM */" >$CONFIG_H
CONFIG_MK=config.mk
rm -f $CONFIG_MK
echo "# $TMUX_PLATFORM" >$CONFIG_MK
cat <<EOF >>$CONFIG_H
#undef HAVE_ASPRINTF
#undef HAVE_CRYPT_H
#undef HAVE_DAEMON
#undef HAVE_FGETLN
#undef HAVE_FORKPTY
#undef HAVE_GETOPT
#undef HAVE_LIBUTIL_H
#undef HAVE_PATHS_H
#undef HAVE_POLL
#undef HAVE_PROGNAME
#undef HAVE_PTY_H
#undef HAVE_QUEUE_H
#undef HAVE_SETPROCTITLE
#undef HAVE_STRCASESTR
#undef HAVE_STRLCAT
#undef HAVE_STRLCPY
#undef HAVE_STRTONUM
#undef HAVE_TREE_H
#undef HAVE_UTIL_H
#undef HAVE_VIS
EOF
case $TMUX_PLATFORM in
# ------------------------------------------------------------------------------
OpenBSD)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_BITSTRING_H
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_QUEUE_H
#define HAVE_SETPROCTITLE
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_STRTONUM
#define HAVE_TREE_H
#define HAVE_UTIL_H
#define HAVE_VIS
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-openbsd.c
LIBS+= -lutil
EOF
;;
# ------------------------------------------------------------------------------
Linux)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FORKPTY
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_PTY_H
#define HAVE_STRCASESTR
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-linux.c \
compat/fgetln.c \
compat/strlcat.c \
compat/strlcpy.c \
compat/strtonum.c \
compat/getopt.c \
compat/vis.c
CFLAGS+= -D_GNU_SOURCE -D_POSIX_SOURCE
LIBS+= -lcrypt -lutil
EOF
;;
# ------------------------------------------------------------------------------
AIX)
cat <<EOF >>$CONFIG_H
#define HAVE_DAEMON
EOF
cat <<EOF >>$CONFIG_MK
CPPFLAGS+= -I/usr/local/include/ncurses
SRCS+= osdep-unknown.c \
compat/asprintf.c \
compat/bsd-poll.c \
compat/daemon.c \
compat/forkpty-aix.c \
compat/strcasestr.c \
compat/strlcat.c \
compat/strlcpy.c \
compat/strtonum.c \
compat/fgetln.c \
compat/getopt.c \
compat/vis.c
EOF
;;
# ------------------------------------------------------------------------------
SunOS)
cat <<EOF >>$CONFIG_H
#define HAVE_CRYPT_H
#define HAVE_POLL
#define HAVE_STRLCAT
#define HAVE_STRLCPY
EOF
cat <<EOF >>$CONFIG_MK
CPPFLAGS+= -I/usr/local/include/ncurses \
-I/opt/csw/include -I/opt/csw/include/ncurses \
-I/opt/sfw/include -I/opt/sfw/include/ncurses
LDFLAGS+= -L/usr/gnu/lib \
-L/opt/csw/lib \
-L/opt/sfw/lib
LIBS+= -lsocket -lnsl
SRCS+= osdep-unknown.c \
compat/asprintf.c \
compat/daemon.c \
compat/fgetln.c \
compat/forkpty-sunos.c \
compat/getopt.c \
compat/strcasestr.c \
compat/strtonum.c \
compat/vis.c
EOF
;;
# ------------------------------------------------------------------------------
Darwin)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_PATHS_H
#define HAVE_PROGNAME
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_UTIL_H
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-darwin.c \
compat/bsd-poll.c \
compat/strtonum.c \
compat/vis.c
EOF
;;
# ------------------------------------------------------------------------------
FreeBSD|DragonFly)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_LIBUTIL_H
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_SETPROCTITLE
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_STRTONUM
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-freebsd.c \
compat/vis.c
LIBS+= -lcrypt -lutil
EOF
;;
# ------------------------------------------------------------------------------
NetBSD)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_SETPROCTITLE
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_UTIL_H
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-netbsd.c \
compat/strtonum.c \
compat/vis.c
LIBS+= -lcrypt -lutil
CPPFLAGS+= -I/usr/pkg/include
LDFLAGS+= -L/usr/pkg/lib
EOF
;;
# ------------------------------------------------------------------------------
*)
echo Unable to configure for $TMUX_PLATFORM
exit 1
esac
echo Configured for $TMUX_PLATFORM
exit 0

View File

@@ -1,7 +1,7 @@
" Vim syntax file
" Language: tmux(1) configuration file
" Maintainer: Tiago Cunha <me@tiagocunha.org>
" Last Change: $Date: 2009-02-08 01:54:23 $
" Last Change: $Date: 2009-07-02 13:50:27 $
if version < 600
syntax clear
@@ -16,12 +16,12 @@ syn keyword tmuxAction any current none
syn keyword tmuxBoolean off on
syn keyword tmuxCmds detach[-client] ls list-sessions neww new-window
syn keyword tmuxCmds bind[-key] unbind[-key] prev[ious-window] last
syn keyword tmuxCmds last[-window] lsk list-keys set[-option] renamew
syn keyword tmuxCmds rename-window selectw select-window lsw list-windows
syn keyword tmuxCmds attach[-session] send-prefix refresh[-client] killw
syn keyword tmuxCmds kill-window lsc list-clients linkw link-window unlinkw
syn keyword tmuxCmds unlink-window next[-window] send[-keys] swapw swap-window
syn keyword tmuxCmds bind[-key] unbind[-key] prev[ious-window] last[-window]
syn keyword tmuxCmds lsk list-keys set[-option] renamew rename-window selectw
syn keyword tmuxCmds select-window lsw list-windows attach[-session]
syn keyword tmuxCmds send-prefix refresh[-client] killw kill-window lsc
syn keyword tmuxCmds list-clients linkw link-window unlinkw unlink-window
syn keyword tmuxCmds next[-window] send[-keys] swapw swap-window
syn keyword tmuxCmds rename[-session] kill-session switchc switch-client
syn keyword tmuxCmds has[-session] scroll-mode copy-mode pasteb paste-buffer
syn keyword tmuxCmds new[-session] start[-server] kill-server setw
@@ -31,24 +31,27 @@ syn keyword tmuxCmds list-buffers deleteb delete-buffer lscm list-commands
syn keyword tmuxCmds movew move-window select-prompt respawnw respawn-window
syn keyword tmuxCmds source[-file] info server-info clock-mode lock[-server]
syn keyword tmuxCmds pass set-password saveb save-buffer downp down-pane killp
syn keyword tmuxCmds kill-pane resizep-down resize-pane-down resizep-up
syn keyword tmuxCmds resize-pane-up selectp select-pane splitw split-window
syn keyword tmuxCmds upp up-pane choose-session choose-window loadb load-buffer
syn keyword tmuxCmds copyb copy-buffer suspendc suspend-client findw
syn keyword tmuxCmds find-window
syn keyword tmuxCmds kill-pane resizep resize-pane selectp select-pane swapp
syn keyword tmuxCmds swap-pane splitw split-window upp up-pane choose-session
syn keyword tmuxCmds choose-window loadb load-buffer copyb copy-buffer suspendc
syn keyword tmuxCmds suspend-client findw find-window breakp break-pane nextl
syn keyword tmuxCmds next-layout rotatew rotate-window confirm[-before]
syn keyword tmuxCmds clearhist clear-history selectl select-layout
syn keyword tmuxOptsSet prefix status status-fg status-bg bell-action
syn keyword tmuxOptsSet default-command history-limit status-left status-right
syn keyword tmuxOptsSet status-interval set-titles display-time buffer-limit
syn keyword tmuxOptsSet status-left-length status-right-length message-fg
syn keyword tmuxOptsSet message-bg lock-after-time default-path repeat-time
syn keyword tmuxOptsSet message-attr status-attr
syn keyword tmuxOptsSet message-attr status-attr status-keys set-remain-on-exit
syn keyword tmuxOptsSet status-utf8
syn keyword tmuxOptsSetw monitor-activity aggressive-resize force-width
syn keyword tmuxOptsSetw force-height remain-on-exit uft8 mode-fg mode-bg
syn keyword tmuxOptsSetw mode-keys clock-mode-colour clock-mode-style
syn keyword tmuxOptsSetw xterm-keys mode-attr window-status-attr
syn keyword tmuxOptsSetw window-status-bg window-status-fg automatic-rename
syn keyword tmuxOptsSetw main-pane-width main-pane-height monitor-content
syn keyword tmuxTodo FIXME NOTE TODO XXX contained

View File

@@ -1,4 +1,4 @@
/* $Id: grid-view.c,v 1.11 2009-03-28 20:17:29 nicm Exp $ */
/* $Id: grid-view.c,v 1.15 2009-07-01 19:14:33 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -133,7 +133,7 @@ grid_view_insert_lines(struct grid *gd, u_int py, u_int ny)
/* Insert lines in region. */
void
grid_view_insert_lines_region(
struct grid *gd, u_int rupper, u_int rlower, u_int py, u_int ny)
struct grid *gd, unused u_int rupper, u_int rlower, u_int py, u_int ny)
{
GRID_DEBUG(
gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny);
@@ -158,12 +158,13 @@ grid_view_delete_lines(struct grid *gd, u_int py, u_int ny)
sy = grid_view_y(gd, gd->sy);
grid_move_lines(gd, py, py + ny, sy - py - ny);
grid_clear(gd, 0, sy - ny, gd->sx, py + ny - (sy - ny));
}
/* Delete lines inside scroll region. */
void
grid_view_delete_lines_region(
struct grid *gd, u_int rupper, u_int rlower, u_int py, u_int ny)
struct grid *gd, unused u_int rupper, u_int rlower, u_int py, u_int ny)
{
GRID_DEBUG(
gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny);
@@ -191,7 +192,7 @@ grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx)
if (px == sx - 1)
grid_clear(gd, px, py, 1, 1);
else
grid_move_cells(gd, px + nx, px, py, (sx - 1) - (px + nx));
grid_move_cells(gd, px + nx, px, py, sx - px - nx);
}
/* Delete characters. */
@@ -207,5 +208,18 @@ grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx)
sx = grid_view_x(gd, gd->sx);
grid_move_cells(gd, px, px + nx, py, (sx - 1) - (px + nx));
grid_move_cells(gd, px, px + nx, py, sx - px - nx);
grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1);
}
/* Convert cells into a string. */
char *
grid_view_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
px = grid_view_x(gd, px);
py = grid_view_y(gd, py);
return (grid_string_cells(gd, px, py, nx));
}

82
grid.c
View File

@@ -1,4 +1,4 @@
/* $Id: grid.c,v 1.15 2009-03-30 19:44:55 nicm Exp $ */
/* $Id: grid.c,v 1.21 2009-06-25 16:34:50 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -375,12 +375,12 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny)
for (yy = py; yy < py + ny; yy++) {
if (gd->data[yy] != NULL) {
xfree(gd->data[yy]);
gd->data[yy] = NULL;
gd->data[yy] = NULL;
gd->size[yy] = 0;
}
if (gd->udata[yy] != NULL) {
xfree(gd->udata[yy]);
gd->udata[yy] = NULL;
gd->udata[yy] = NULL;
gd->usize[yy] = 0;
}
}
@@ -413,10 +413,10 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
grid_clear_lines(gd, yy, 1);
}
memmove(&gd->data[dy], &gd->data[py], ny * (sizeof *gd->data));
memmove(&gd->data[dy], &gd->data[py], ny * (sizeof *gd->data));
memmove(&gd->size[dy], &gd->size[py], ny * (sizeof *gd->size));
memmove(&gd->udata[dy], &gd->udata[py], ny * (sizeof *gd->udata));
memmove(&gd->udata[dy], &gd->udata[py], ny * (sizeof *gd->udata));
memmove(&gd->usize[dy], &gd->usize[py], ny * (sizeof *gd->usize));
/* Wipe any lines that have been moved (without freeing them). */
@@ -430,31 +430,6 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
}
}
/* Clear a group of cells. */
void
grid_clear_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
u_int xx;
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
if (nx == 0)
return;
if (grid_check_x(gd, px) != 0)
return;
if (grid_check_x(gd, px + nx - 1) != 0)
return;
if (grid_check_y(gd, py) != 0)
return;
for (xx = px; xx < px + nx; xx++) {
if (xx >= gd->size[py])
break;
grid_put_cell(gd, xx, py, &grid_default_cell);
}
}
/* Move a group of cells. */
void
grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
@@ -494,4 +469,51 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
}
}
/* Convert cells into a string. */
char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
const struct grid_cell *gc;
const struct grid_utf8 *gu;
char *buf;
size_t len, off;
u_int xx, i;
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
len = 128;
buf = xmalloc(len);
off = 0;
for (xx = px; xx < px + nx; xx++) {
gc = grid_peek_cell(gd, xx, py);
if (gc->flags & GRID_FLAG_PADDING)
continue;
if (gc->flags & GRID_FLAG_UTF8) {
while (len < off + UTF8_SIZE + 1) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
gu = grid_peek_utf8(gd, xx, py);
for (i = 0; i < UTF8_SIZE; i++) {
if (gu->data[i] == 0xff)
break;
buf[off++] = gu->data[i];
}
} else {
while (len < off + 2) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
buf[off++] = gc->data;
}
}
while (off > 0 && buf[off - 1] == ' ')
off--;
buf[off] = '\0';
return (buf);
}

View File

@@ -1,4 +1,4 @@
/* $Id: input-keys.c,v 1.26 2009-03-02 18:05:40 nicm Exp $ */
/* $Id: input-keys.c,v 1.27 2009-05-04 17:58:26 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -70,7 +70,7 @@ struct input_key_ent input_keys[] = {
{ KEYC_ADDCTL(KEYC_DOWN), "\033Ob", 0 },
{ KEYC_ADDCTL(KEYC_RIGHT), "\033Oc", 0 },
{ KEYC_ADDCTL(KEYC_LEFT), "\033Od", 0 },
{ KEYC_ADDSFT(KEYC_UP), "\033[a", 0 },
{ KEYC_ADDSFT(KEYC_DOWN), "\033[b", 0 },
{ KEYC_ADDSFT(KEYC_RIGHT), "\033[c", 0 },
@@ -85,7 +85,7 @@ struct input_key_ent input_keys[] = {
{ KEYC_DOWN, "\033[B", 0 },
{ KEYC_RIGHT, "\033[C", 0 },
{ KEYC_LEFT, "\033[D", 0 },
/* Keypad keys. Keypad versions must come first. */
{ KEYC_KP0_1, "/", INPUTKEY_KEYPAD },
{ KEYC_KP0_2, "*", INPUTKEY_KEYPAD },

173
input.c
View File

@@ -1,4 +1,4 @@
/* $Id: input.c,v 1.76 2009-03-28 20:17:29 nicm Exp $ */
/* $Id: input.c,v 1.86 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -67,6 +67,7 @@ void input_handle_sequence_cud(struct input_ctx *);
void input_handle_sequence_cuf(struct input_ctx *);
void input_handle_sequence_cub(struct input_ctx *);
void input_handle_sequence_dch(struct input_ctx *);
void input_handle_sequence_cbt(struct input_ctx *);
void input_handle_sequence_dl(struct input_ctx *);
void input_handle_sequence_ich(struct input_ctx *);
void input_handle_sequence_il(struct input_ctx *);
@@ -74,6 +75,7 @@ void input_handle_sequence_vpa(struct input_ctx *);
void input_handle_sequence_hpa(struct input_ctx *);
void input_handle_sequence_cup(struct input_ctx *);
void input_handle_sequence_cup(struct input_ctx *);
void input_handle_sequence_tbc(struct input_ctx *);
void input_handle_sequence_ed(struct input_ctx *);
void input_handle_sequence_el(struct input_ctx *);
void input_handle_sequence_sm(struct input_ctx *);
@@ -101,8 +103,10 @@ const struct input_sequence_entry input_sequence_table[] = {
{ 'L', input_handle_sequence_il },
{ 'M', input_handle_sequence_dl },
{ 'P', input_handle_sequence_dch },
{ 'Z', input_handle_sequence_cbt },
{ 'd', input_handle_sequence_vpa },
{ 'f', input_handle_sequence_cup },
{ 'g', input_handle_sequence_tbc },
{ 'h', input_handle_sequence_sm },
{ 'l', input_handle_sequence_rm },
{ 'm', input_handle_sequence_sgr },
@@ -394,15 +398,34 @@ input_state_sequence_first(u_char ch, struct input_ctx *ictx)
ictx->private = '\0';
ARRAY_CLEAR(&ictx->args);
input_state(ictx, input_state_sequence_next);
if (INPUT_PARAMETER(ch)) {
input_new_argument(ictx);
if (ch >= 0x3c && ch <= 0x3f) {
/* Private control sequence. */
ictx->private = ch;
/* Most C0 control are accepted within CSI. */
if (INPUT_C0CONTROL(ch)) {
if (ch == 0x1b) { /* ESC */
/* Abort sequence and begin with new. */
input_state(ictx, input_state_escape);
return;
} else if (ch == 0x18 || ch == 0x1a) { /* CAN and SUB */
/* Abort sequence. */
input_state(ictx, input_state_first);
return;
}
/* Handle C0 immediately. */
input_handle_c0_control(ch, ictx);
/*
* Just come back to this state, in case the next character
* is the start of a private sequence.
*/
return;
}
input_state(ictx, input_state_sequence_next);
/* Private sequence: always the first character. */
if (ch >= 0x3c && ch <= 0x3f) {
ictx->private = ch;
return;
}
/* Pass character on directly. */
@@ -423,6 +446,9 @@ input_state_sequence_next(u_char ch, struct input_ctx *ictx)
}
if (INPUT_PARAMETER(ch)) {
if (ARRAY_EMPTY(&ictx->args))
input_new_argument(ictx);
if (ch == ';') {
if (input_add_argument(ictx, '\0') != 0)
input_state(ictx, input_state_first);
@@ -443,6 +469,24 @@ input_state_sequence_next(u_char ch, struct input_ctx *ictx)
return;
}
/* Most C0 control are accepted within CSI. */
if (INPUT_C0CONTROL(ch)) {
if (ch == 0x1b) { /* ESC */
/* Abort sequence and begin with new. */
input_state(ictx, input_state_escape);
return;
} else if (ch == 0x18 || ch == 0x1a) { /* CAN and SUB */
/* Abort sequence. */
input_state(ictx, input_state_first);
return;
}
/* Handle C0 immediately. */
input_handle_c0_control(ch, ictx);
return;
}
input_state(ictx, input_state_first);
}
@@ -475,7 +519,7 @@ input_state_string_next(u_char ch, struct input_ctx *ictx)
return;
}
if (ch >= 0x20 && ch != 0x7f) {
if (ch >= 0x20) {
if (input_add_string(ictx, ch) != 0)
input_state(ictx, input_state_first);
return;
@@ -544,7 +588,7 @@ void
input_handle_character(u_char ch, struct input_ctx *ictx)
{
struct window_pane *wp = ictx->wp;
if (ch > 0x7f && options_get_number(&wp->window->options, "utf8")) {
/*
* UTF-8 sequence.
@@ -605,12 +649,19 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
screen_write_cursorleft(&ictx->ctx, 1);
break;
case '\011': /* TAB */
s->cx = ((s->cx / 8) * 8) + 8;
if (s->cx > screen_size_x(s) - 1) {
s->cx = 0;
screen_write_cursordown(&ictx->ctx, 1);
}
screen_write_cursormove(&ictx->ctx, s->cx, s->cy);
/* Don't tab beyond the end of the line. */
if (s->cx >= screen_size_x(s) - 1)
break;
/* Find the next tab point, or use the last column if none. */
do {
s->cx++;
if (bit_test(s->tabs, s->cx))
break;
} while (s->cx < screen_size_x(s) - 1);
break;
case '\013': /* VT */
screen_write_linefeed(&ictx->ctx);
break;
case '\016': /* SO */
ictx->cell.attr |= GRID_ATTR_CHARSET;
@@ -627,9 +678,22 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
void
input_handle_c1_control(u_char ch, struct input_ctx *ictx)
{
struct screen *s = ictx->ctx.s;
log_debug2("-- c1 %zu: %hhu (%c)", ictx->off, ch, ch);
switch (ch) {
case 'D': /* IND */
screen_write_linefeed(&ictx->ctx);
break;
case 'E': /* NEL */
screen_write_carriagereturn(&ictx->ctx);
screen_write_linefeed(&ictx->ctx);
break;
case 'H': /* HTS */
if (s->cx < screen_size_x(s))
bit_set(s->tabs, s->cx);
break;
case 'M': /* RI */
screen_write_reverseindex(&ictx->ctx);
break;
@@ -648,7 +712,7 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
"-- p2 %zu: %hhu (%c) %hhu", ictx->off, ch, ch, ictx->intermediate);
switch (ch) {
case '0': /* Dscs (graphics) */
case '0': /* SCS */
/*
* Not really supported, but fake it up enough for those that
* use it to switch character sets (by redefining G0 to
@@ -661,22 +725,36 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
}
break;
case '=': /* DECKPAM */
if (ictx->intermediate != '\0')
break;
screen_write_kkeypadmode(&ictx->ctx, 1);
log_debug("kkeypad on (application mode)");
break;
case '>': /* DECKPNM */
if (ictx->intermediate != '\0')
break;
screen_write_kkeypadmode(&ictx->ctx, 0);
log_debug("kkeypad off (number mode)");
break;
case '7': /* DECSC */
if (ictx->intermediate != '\0')
break;
memcpy(&ictx->saved_cell, &ictx->cell, sizeof ictx->saved_cell);
ictx->saved_cx = s->cx;
ictx->saved_cy = s->cy;
break;
case '8': /* DECRC */
memcpy(&ictx->cell, &ictx->saved_cell, sizeof ictx->cell);
screen_write_cursormove(
&ictx->ctx, ictx->saved_cx, ictx->saved_cy);
case '8':
switch (ictx->intermediate) {
case '\0': /* DECRC */
memcpy(
&ictx->cell, &ictx->saved_cell, sizeof ictx->cell);
screen_write_cursormove(
&ictx->ctx, ictx->saved_cx, ictx->saved_cy);
break;
case '#': /* DECALN */
screen_write_alignmenttest(&ictx->ctx);
break;
}
break;
default:
log_debug("unknown p2: %hhu", ch);
@@ -691,7 +769,7 @@ input_handle_standard_two(u_char ch, struct input_ctx *ictx)
"-- s2 %zu: %hhu (%c) %hhu", ictx->off, ch, ch, ictx->intermediate);
switch (ch) {
case 'B': /* Dscs (ASCII) */
case 'B': /* SCS */
/*
* Not really supported, but fake it up enough for those that
* use it to switch character sets (by redefining G0 to
@@ -710,6 +788,8 @@ input_handle_standard_two(u_char ch, struct input_ctx *ictx)
ictx->saved_cx = 0;
ictx->saved_cy = 0;
screen_reset_tabs(ictx->ctx.s);
screen_write_scrollregion(
&ictx->ctx, 0, screen_size_y(ictx->ctx.s) - 1);
@@ -849,6 +929,30 @@ input_handle_sequence_dch(struct input_ctx *ictx)
screen_write_deletecharacter(&ictx->ctx, n);
}
void
input_handle_sequence_cbt(struct input_ctx *ictx)
{
struct screen *s = ictx->ctx.s;
uint16_t n;
if (ictx->private != '\0')
return;
if (ARRAY_LENGTH(&ictx->args) > 1)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
if (n == 0)
n = 1;
/* Find the previous tab point, n times. */
while (s->cx > 0 && n-- > 0) {
do
s->cx--;
while (s->cx > 0 && !bit_test(s->tabs, s->cx));
}
}
void
input_handle_sequence_dl(struct input_ctx *ictx)
{
@@ -963,6 +1067,31 @@ input_handle_sequence_cup(struct input_ctx *ictx)
screen_write_cursormove(&ictx->ctx, m - 1, n - 1);
}
void
input_handle_sequence_tbc(struct input_ctx *ictx)
{
struct screen *s = ictx->ctx.s;
uint16_t n;
if (ictx->private != '\0')
return;
if (ARRAY_LENGTH(&ictx->args) > 1)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
switch (n) {
case 0:
if (s->cx < screen_size_x(s))
bit_clear(s->tabs, s->cx);
break;
case 3:
bit_nclear(s->tabs, 0, screen_size_x(s) - 1);
break;
}
}
void
input_handle_sequence_ed(struct input_ctx *ictx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: key-bindings.c,v 1.66 2009-04-03 17:21:46 nicm Exp $ */
/* $Id: key-bindings.c,v 1.72 2009-05-16 11:48:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -74,7 +74,7 @@ key_bindings_remove(int key)
void
key_bindings_init(void)
{
struct {
static const struct {
int key;
int can_repeat;
const struct cmd_entry *entry;
@@ -83,7 +83,7 @@ key_bindings_init(void)
{ '!', 0, &cmd_break_pane_entry },
{ '"', 0, &cmd_split_window_entry },
{ '#', 0, &cmd_list_buffers_entry },
{ '&', 0, &cmd_kill_window_entry },
{ '&', 0, &cmd_confirm_before_entry },
{ ',', 0, &cmd_command_prompt_entry },
{ '-', 0, &cmd_delete_buffer_entry },
{ '.', 0, &cmd_command_prompt_entry },
@@ -115,19 +115,24 @@ key_bindings_init(void)
{ 's', 0, &cmd_choose_session_entry },
{ 't', 0, &cmd_clock_mode_entry },
{ 'w', 0, &cmd_choose_window_entry },
{ 'x', 0, &cmd_kill_pane_entry, },
{ 'x', 0, &cmd_confirm_before_entry },
{ '{', 0, &cmd_swap_pane_entry },
{ '}', 0, &cmd_swap_pane_entry },
{ META, 0, &cmd_send_prefix_entry },
{ '\002', 0, &cmd_send_prefix_entry },
{ KEYC_ADDESC('0'), 0, &cmd_select_layout_entry },
{ KEYC_ADDESC('1'), 0, &cmd_select_layout_entry },
{ KEYC_ADDESC('2'), 0, &cmd_select_layout_entry },
{ KEYC_ADDESC('9'), 0, &cmd_select_layout_entry },
{ KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_entry },
{ KEYC_PPAGE, 0, &cmd_scroll_mode_entry },
{ KEYC_ADDESC('n'), 0, &cmd_next_window_entry },
{ KEYC_ADDESC('p'), 0, &cmd_previous_window_entry },
{ KEYC_UP, 1, &cmd_up_pane_entry },
{ KEYC_DOWN, 1, &cmd_down_pane_entry },
{ KEYC_ADDESC(KEYC_UP), 1, &cmd_resize_pane_up_entry },
{ KEYC_ADDESC(KEYC_DOWN), 1, &cmd_resize_pane_down_entry },
{ KEYC_ADDCTL(KEYC_UP), 1, &cmd_resize_pane_up_entry },
{ KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_down_entry },
{ KEYC_ADDESC(KEYC_UP), 1, &cmd_resize_pane_entry },
{ KEYC_ADDESC(KEYC_DOWN), 1, &cmd_resize_pane_entry },
{ KEYC_ADDCTL(KEYC_UP), 1, &cmd_resize_pane_entry },
{ KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_entry },
{ KEYC_ADDESC('o'), 0, &cmd_rotate_window_entry },
{ '\017', 0, &cmd_rotate_window_entry },
};
@@ -183,7 +188,7 @@ key_bindings_error(struct cmd_ctx *ctx, const char *fmt, ...)
void printflike2
key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...)
{
struct winlink *wl = ctx->cursession->curw;
struct winlink *wl = ctx->cursession->curw;
va_list ap;
if (wl->window->active->mode != &window_more_mode)

183
layout-manual.c Normal file
View File

@@ -0,0 +1,183 @@
/* $Id: layout-manual.c,v 1.3 2009-05-18 21:29:11 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 "tmux.h"
void layout_manual_v_update_offsets(struct window *);
void
layout_manual_v_refresh(struct window *w, unused int active_only)
{
struct window_pane *wp;
u_int npanes, canfit, total;
int left;
if (active_only)
return;
if (TAILQ_EMPTY(&w->panes))
return;
/* Clear hidden flags. */
TAILQ_FOREACH(wp, &w->panes, entry)
wp->flags &= ~PANE_HIDDEN;
/* Check the new size. */
npanes = window_count_panes(w);
if (w->sy <= PANE_MINIMUM * npanes) {
/* How many can we fit? */
canfit = w->sy / PANE_MINIMUM;
if (canfit == 0) {
/* None. Just use this size for the first. */
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp == TAILQ_FIRST(&w->panes))
wp->sy = w->sy;
else
wp->flags |= PANE_HIDDEN;
}
} else {
/* >=1, set minimum for them all. */
TAILQ_FOREACH(wp, &w->panes, entry) {
if (canfit-- > 0)
wp->sy = PANE_MINIMUM - 1;
else
wp->flags |= PANE_HIDDEN;
}
/* And increase the first by the rest. */
TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM;
}
} else {
/* In theory they will all fit. Find the current total. */
total = 0;
TAILQ_FOREACH(wp, &w->panes, entry)
total += wp->sy;
total += npanes - 1;
/* Growing or shrinking? */
left = w->sy - total;
if (left > 0) {
/* Growing. Expand evenly. */
while (left > 0) {
TAILQ_FOREACH(wp, &w->panes, entry) {
wp->sy++;
if (--left == 0)
break;
}
}
} else {
/* Shrinking. Reduce evenly down to minimum. */
while (left < 0) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->sy <= PANE_MINIMUM - 1)
continue;
wp->sy--;
if (++left == 0)
break;
}
}
}
}
/* Now do the resize. */
TAILQ_FOREACH(wp, &w->panes, entry) {
wp->sy--;
window_pane_resize(wp, w->sx, wp->sy + 1);
}
/* Fill in the offsets. */
layout_manual_v_update_offsets(w);
/* Switch the active window if necessary. */
window_set_active_pane(w, w->active);
}
void
layout_manual_v_resize(struct window_pane *wp, int adjust)
{
struct window *w = wp->window;
struct window_pane *wq;
if (adjust > 0) {
/*
* If this is not the last pane, keep trying to increase size
* and remove it from the next panes. If it is the last, do
* so on the previous pane.
*/
if (TAILQ_NEXT(wp, entry) == NULL) {
if (wp == TAILQ_FIRST(&w->panes)) {
/* Only one pane. */
return;
}
wp = TAILQ_PREV(wp, window_panes, entry);
}
while (adjust-- > 0) {
wq = wp;
while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
if (wq->sy <= PANE_MINIMUM)
continue;
window_pane_resize(wq, wq->sx, wq->sy - 1);
break;
}
if (wq == NULL)
break;
window_pane_resize(wp, wp->sx, wp->sy + 1);
}
} else {
adjust = -adjust;
/*
* If this is not the last pane, keep trying to reduce size
* and add to the following pane. If it is the last, do so on
* the previous pane.
*/
wq = TAILQ_NEXT(wp, entry);
if (wq == NULL) {
if (wp == TAILQ_FIRST(&w->panes)) {
/* Only one pane. */
return;
}
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);
}
}
layout_manual_v_update_offsets(w);
}
void
layout_manual_v_update_offsets(struct window *w)
{
struct window_pane *wp;
u_int yoff;
yoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->flags & PANE_HIDDEN)
continue;
wp->xoff = 0;
wp->yoff = yoff;
yoff += wp->sy + 1;
}
}

217
layout.c
View File

@@ -1,4 +1,4 @@
/* $Id: layout.c,v 1.3 2009-04-01 21:10:08 nicm Exp $ */
/* $Id: layout.c,v 1.14 2009-05-18 22:17:24 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,62 +18,116 @@
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/*
* Layout functions: second argument (int) is 1 if definitely the /only/ change
* has been the active pane has changed. If 0 then panes, active pane or both
* may have changed.
* Each layout has two functions, _refresh to relayout the panes and _resize to
* resize a single pane.
*
* Second argument (int) to _refresh is 1 if the only change has been that the
* active pane has changed. If 0 then panes, active pane or both may have
* changed.
*/
void layout_manual(struct window *, int);
void layout_active_only(struct window *, int);
void layout_even_horizontal(struct window *, int);
void layout_even_vertical(struct window *, int);
void layout_left_vertical(struct window *, int);
void layout_active_only_refresh(struct window *, int);
void layout_even_h_refresh(struct window *, int);
void layout_even_v_refresh(struct window *, int);
void layout_main_h_refresh(struct window *, int);
void layout_main_v_refresh(struct window *, int);
const struct {
const char *name;
void (*fn)(struct window *, int);
const char *name;
void (*refresh)(struct window *, int);
void (*resize)(struct window_pane *, int);
} layouts[] = {
{ "manual", layout_manual },
{ "active-only", layout_active_only },
{ "even-horizontal", layout_even_horizontal },
{ "even-vertical", layout_even_vertical },
{ "left-vertical", layout_left_vertical },
};
{ "manual-vertical", layout_manual_v_refresh, layout_manual_v_resize },
{ "active-only", layout_active_only_refresh, NULL },
{ "even-horizontal", layout_even_h_refresh, NULL },
{ "even-vertical", layout_even_v_refresh, NULL },
{ "main-horizontal", layout_main_h_refresh, NULL },
{ "main-vertical", layout_main_v_refresh, NULL },
};
const char *
layout_name(struct window *w)
{
return (layouts[w->layout].name);
}
int
layout_lookup(const char *name)
{
u_int i;
int matched = -1;
for (i = 0; i < nitems(layouts); i++) {
if (strncmp(layouts[i].name, name, strlen(name)) == 0) {
if (matched != -1) /* ambiguous */
return (-1);
matched = i;
}
}
return (matched);
}
int
layout_select(struct window *w, u_int layout)
{
if (layout > nitems(layouts) - 1 || layout == w->layout)
return (-1);
w->layout = layout;
layout_refresh(w, 0);
return (0);
}
void
layout_next(struct window *w)
{
w->layout++;
if (w->layout > nitems(layouts) - 1) {
if (w->layout > nitems(layouts) - 1)
w->layout = 0;
/* XXX Special-case manual. */
window_fit_panes(w);
window_update_panes(w);
}
layout_refresh(w, 0);
}
void
layout_refresh(struct window *w, unused int active_changed)
layout_previous(struct window *w)
{
layouts[w->layout].fn(w, active_changed);
if (w->layout == 0)
w->layout = nitems(layouts) - 1;
else
w->layout--;
layout_refresh(w, 0);
}
void
layout_refresh(struct window *w, int active_only)
{
layouts[w->layout].refresh(w, active_only);
server_redraw_window(w);
}
void
layout_manual(unused struct window *w, unused int active_changed)
int
layout_resize(struct window_pane *wp, int adjust)
{
struct window *w = wp->window;
if (layouts[w->layout].resize == NULL)
return (-1);
layouts[w->layout].resize(wp, adjust);
return (0);
}
void
layout_active_only(struct window *w, unused int active_changed)
layout_active_only_refresh(struct window *w, unused int active_only)
{
struct window_pane *wp;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp == w->active) {
if (wp == w->active) {
wp->flags &= ~PANE_HIDDEN;
wp->xoff = wp->yoff = 0;
window_pane_resize(wp, w->sx, w->sy);
@@ -83,12 +137,12 @@ layout_active_only(struct window *w, unused int active_changed)
}
void
layout_even_horizontal(struct window *w, int active_changed)
layout_even_h_refresh(struct window *w, int active_only)
{
struct window_pane *wp;
u_int i, n, width, xoff;
if (active_changed)
if (active_only)
return;
/* Get number of panes. */
@@ -102,7 +156,7 @@ layout_even_horizontal(struct window *w, int active_changed)
n = w->sx / PANE_MINIMUM;
} else
width = w->sx / n;
/* Fit the panes. */
i = xoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
@@ -131,12 +185,12 @@ layout_even_horizontal(struct window *w, int active_changed)
}
void
layout_even_vertical(struct window *w, int active_changed)
layout_even_v_refresh(struct window *w, int active_only)
{
struct window_pane *wp;
u_int i, n, height, yoff;
if (active_changed)
if (active_only)
return;
/* Get number of panes. */
@@ -150,7 +204,7 @@ layout_even_vertical(struct window *w, int active_changed)
n = w->sy / PANE_MINIMUM;
} else
height = w->sy / n;
/* Fit the panes. */
i = yoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
@@ -179,12 +233,12 @@ layout_even_vertical(struct window *w, int active_changed)
}
void
layout_left_vertical(struct window *w, int active_changed)
layout_main_v_refresh(struct window *w, int active_only)
{
struct window_pane *wp;
u_int i, n, height, yoff;
u_int i, n, mainwidth, height, yoff;
if (active_changed)
if (active_only)
return;
/* Get number of panes. */
@@ -192,9 +246,12 @@ layout_left_vertical(struct window *w, int active_changed)
if (n == 0)
return;
/* Get the main pane width and add one for separator line. */
mainwidth = options_get_number(&w->options, "main-pane-width") + 1;
/* Need >1 pane and minimum columns; if fewer, display active only. */
if (n == 1 || w->sx < 82 + PANE_MINIMUM) {
layout_active_only(w, active_changed);
if (n == 1 || w->sx < mainwidth + PANE_MINIMUM) {
layout_active_only_refresh(w, active_only);
return;
}
n--;
@@ -205,14 +262,14 @@ layout_left_vertical(struct window *w, int active_changed)
n = w->sy / PANE_MINIMUM;
} else
height = w->sy / n;
/* Fit the panes. */
i = yoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp == TAILQ_FIRST(&w->panes)) {
wp->xoff = 0;
wp->yoff = 0;
window_pane_resize(wp, 81, w->sy);
window_pane_resize(wp, mainwidth - 1, w->sy);
wp->flags &= ~PANE_HIDDEN;
continue;
}
@@ -223,12 +280,12 @@ layout_left_vertical(struct window *w, int active_changed)
}
wp->flags &= ~PANE_HIDDEN;
wp->xoff = 82;
wp->xoff = mainwidth;
wp->yoff = yoff;
if (i != n - 1)
window_pane_resize(wp, w->sx - 82, height - 1);
window_pane_resize(wp, w->sx - mainwidth, height - 1);
else
window_pane_resize(wp, w->sx - 82, height);
window_pane_resize(wp, w->sx - mainwidth, height);
i++;
yoff += height;
@@ -244,3 +301,73 @@ layout_left_vertical(struct window *w, int active_changed)
window_pane_resize(wp, wp->sx, wp->sy + 1);
}
}
void
layout_main_h_refresh(struct window *w, int active_only)
{
struct window_pane *wp;
u_int i, n, mainheight, width, xoff;
if (active_only)
return;
/* Get number of panes. */
n = window_count_panes(w);
if (n == 0)
return;
/* Get the main pane height and add one for separator line. */
mainheight = options_get_number(&w->options, "main-pane-height") + 1;
/* Need >1 pane and minimum rows; if fewer, display active only. */
if (n == 1 || w->sy < mainheight + PANE_MINIMUM) {
layout_active_only_refresh(w, active_only);
return;
}
n--;
/* How many can we fit, not including first? */
if (w->sx / n < PANE_MINIMUM) {
width = PANE_MINIMUM;
n = w->sx / PANE_MINIMUM;
} else
width = w->sx / n;
/* Fit the panes. */
i = xoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp == TAILQ_FIRST(&w->panes)) {
wp->xoff = 0;
wp->yoff = 0;
window_pane_resize(wp, w->sx, mainheight - 1);
wp->flags &= ~PANE_HIDDEN;
continue;
}
if (i > n) {
wp->flags |= PANE_HIDDEN;
continue;
}
wp->flags &= ~PANE_HIDDEN;
wp->xoff = xoff;
wp->yoff = mainheight;
if (i != n - 1)
window_pane_resize(wp, width - 1, w->sy - mainheight);
else
window_pane_resize(wp, width - 1, w->sy - mainheight);
i++;
xoff += width;
}
/* Any space left? */
while (xoff++ < w->sx + 1) {
wp = TAILQ_LAST(&w->panes, window_panes);
while (wp != NULL && wp == TAILQ_FIRST(&w->panes))
wp = TAILQ_PREV(wp, window_panes, entry);
if (wp == NULL)
break;
window_pane_resize(wp, wp->sx + 1, wp->sy);
}
}

38
log.c
View File

@@ -1,4 +1,4 @@
/* $Id: log.c,v 1.11 2009-03-31 21:22:10 nicm Exp $ */
/* $Id: log.c,v 1.15 2009-06-25 16:23:35 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,9 +29,8 @@
/* Logging type. */
#define LOG_TYPE_OFF 0
#define LOG_TYPE_SYSLOG 1
#define LOG_TYPE_TTY 2
#define LOG_TYPE_FILE 3
#define LOG_TYPE_TTY 1
#define LOG_TYPE_FILE 2
int log_type = LOG_TYPE_OFF;
/* Log file, if needed. */
@@ -40,17 +39,8 @@ FILE *log_file;
/* Debug level. */
int log_level;
/* Open logging to syslog. */
void
log_open_syslog(int level)
{
log_type = LOG_TYPE_SYSLOG;
log_level = level;
openlog(__progname, LOG_PID|LOG_NDELAY, LOG_FACILITY);
tzset();
}
void log_vwrite(int, const char *, va_list);
__dead void log_vfatal(const char *, va_list);
/* Open logging to tty. */
void
@@ -91,17 +81,6 @@ log_close(void)
log_type = LOG_TYPE_OFF;
}
/* Write a log message. */
void
log_write(int pri, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
log_vwrite(pri, msg, ap);
va_end(ap);
}
/* Write a log message. */
void
log_vwrite(int pri, const char *msg, va_list ap)
@@ -110,13 +89,6 @@ log_vwrite(int pri, const char *msg, va_list ap)
FILE *f = log_file;
switch (log_type) {
case LOG_TYPE_SYSLOG:
#ifdef NO_VSYSLOG
/* XXX */
#else
vsyslog(pri, msg, ap);
#endif
break;
case LOG_TYPE_TTY:
if (pri == LOG_INFO)
f = stdout;

View File

@@ -1,4 +1,4 @@
/* $Id: mode-key.c,v 1.10 2009-02-21 17:46:13 nicm Exp $ */
/* $Id: mode-key.c,v 1.12 2009-05-14 19:36:56 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -54,6 +54,13 @@ mode_key_lookup(struct mode_key_data *mdata, int key)
enum mode_key_cmd
mode_key_lookup_vi(struct mode_key_data *mdata, int key)
{
if (KEYC_ISESC(key)) {
key = KEYC_REMOVEESC(key);
if (mdata->flags & MODEKEY_CANEDIT)
mdata->flags ^= MODEKEY_EDITMODE;
}
if (mdata->flags & MODEKEY_EDITMODE) {
switch (key) {
case '\003':
@@ -131,8 +138,10 @@ mode_key_lookup_vi(struct mode_key_data *mdata, int key)
case 'k':
case KEYC_UP:
return (MODEKEYCMD_UP);
case 'p':
return (MODEKEYCMD_PASTE);
}
return (MODEKEYCMD_NONE);
}
@@ -173,6 +182,8 @@ mode_key_lookup_emacs(struct mode_key_data *mdata, int key)
return (MODEKEYCMD_NEXTPAGE);
case KEYC_ADDESC('f'):
return (MODEKEYCMD_NEXTWORD);
case '\031':
return (MODEKEYCMD_PASTE);
case KEYC_ADDESC('v'):
case KEYC_PPAGE:
return (MODEKEYCMD_PREVIOUSPAGE);

31
names.c
View File

@@ -1,4 +1,4 @@
/* $Id: names.c,v 1.4 2009-02-13 00:43:04 nicm Exp $ */
/* $Id: names.c,v 1.11 2009-07-02 18:26:55 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <ctype.h>
#include <libgen.h>
#include <string.h>
#include <unistd.h>
@@ -33,7 +34,7 @@ set_window_names(void)
u_int i;
char *name, *wname;
struct timeval tv, tv2;
if (gettimeofday(&tv, NULL) != 0)
fatal("gettimeofday");
@@ -49,7 +50,7 @@ set_window_names(void)
memcpy(&w->name_timer, &tv, sizeof w->name_timer);
tv2.tv_sec = 0;
tv2.tv_usec = NAME_INTERVAL * 1000L;
timeradd(&w->name_timer, &tv2, &w->name_timer);
timeradd(&w->name_timer, &tv2, &w->name_timer);
if (w->active->screen != &w->active->base)
name = NULL;
@@ -58,7 +59,16 @@ set_window_names(void)
if (name == NULL)
wname = default_window_name(w);
else {
wname = parse_window_name(name);
/*
* If tmux is using the default command, it will be a
* login shell and argv[0] may have a - prefix. Remove
* this if it is present. Ick.
*/
if (w->active->cmd != NULL && *w->active->cmd == '\0' &&
name != NULL && name[0] == '-' && name[1] != '\0')
wname = parse_window_name(name + 1);
else
wname = parse_window_name(name);
xfree(name);
}
@@ -77,7 +87,9 @@ default_window_name(struct window *w)
{
if (w->active->screen != &w->active->base)
return (xstrdup("[tmux]"));
return (parse_window_name(w->active->cmd));
if (w->active->cmd != NULL && *w->active->cmd != '\0')
return (parse_window_name(w->active->cmd));
return (parse_window_name(window_default_command()));
}
char *
@@ -88,7 +100,7 @@ parse_window_name(const char *in)
name = copy = xstrdup(in);
if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0)
name = name + (sizeof "exec ") - 1;
while (*name == ' ')
name++;
if ((ptr = strchr(name, ' ')) != NULL)
@@ -96,14 +108,13 @@ parse_window_name(const char *in)
if (*name != '\0') {
ptr = name + strlen(name) - 1;
while (ptr > name && !isalnum(*ptr))
while (ptr > name && !isalnum((u_char)*ptr))
*ptr-- = '\0';
}
if (*name == '/')
name = xbasename(name);
name = basename(name);
name = xstrdup(name);
xfree(copy);
return (name);
}

View File

@@ -1,4 +1,4 @@
/* $Id: options.c,v 1.4 2009-01-07 19:53:17 nicm Exp $ */
/* $Id: options.c,v 1.5 2009-05-15 12:57:36 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,7 +63,7 @@ options_find1(struct options *oo, const char *name)
{
struct options_entry p;
p.name = name;
p.name = (char *) name;
return (SPLAY_FIND(options_tree, &oo->tree, &p));
}
@@ -72,7 +72,7 @@ options_find(struct options *oo, const char *name)
{
struct options_entry *o, p;
p.name = name;
p.name = (char *) name;
o = SPLAY_FIND(options_tree, &oo->tree, &p);
while (o == NULL) {
oo = oo->parent;

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-darwin.c,v 1.9 2009-02-13 00:43:04 nicm Exp $ */
/* $Id: osdep-darwin.c,v 1.11 2009-05-04 17:58:27 nicm Exp $ */
/*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -16,8 +16,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __APPLE__
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -35,7 +33,7 @@ osdep_get_name(int fd, unused char *tty)
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 };
size_t size;
struct kinfo_proc kp;
if ((mib[3] = tcgetpgrp(fd)) == -1)
return (NULL);
@@ -47,5 +45,3 @@ osdep_get_name(int fd, unused char *tty)
return (strdup(kp.kp_proc.p_comm));
}
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-freebsd.c,v 1.14 2009-02-13 00:43:04 nicm Exp $ */
/* $Id: osdep-freebsd.c,v 1.16 2009-06-26 15:31:15 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,8 +16,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __FreeBSD__
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/stat.h>
@@ -33,7 +31,9 @@
char *osdep_get_name(int, char *);
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define is_runnable(p) \
((p)->ki_stat == SRUN || (p)->ki_stat == SIDL)
@@ -121,5 +121,3 @@ retry:
free(buf);
return (name);
}
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-linux.c,v 1.5 2009-02-13 00:43:04 nicm Exp $ */
/* $Id: osdep-linux.c,v 1.6 2009-04-29 23:07:35 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,8 +16,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __linux__
#include <sys/types.h>
#include <sys/stat.h>
@@ -59,5 +57,3 @@ osdep_get_name(int fd, unused char *tty)
fclose(f);
return (buf);
}
#endif

View File

@@ -1,3 +1,5 @@
/* $Id: osdep-netbsd.c,v 1.4 2009-06-26 15:54:52 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
@@ -14,109 +16,37 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __NetBSD__
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#define is_runnable(p) \
((p)->p_stat == LSRUN || (p)->p_stat == SIDL)
#define is_stopped(p) \
((p)->p_stat == LSSTOP || (p)->p_stat == SZOMB)
#endif
char *osdep_get_name(int, char *);
char *
osdep_get_name(int fd, char *tty)
osdep_get_name(int fd, __unused char *tty)
{
int mib[4] = { CTL_KERN, KERN_PROC2, KERN_PROC_PGRP, 0 };
struct stat sb;
int mib[6];
size_t len;
struct kinfo_proc2 *buf, *newbuf, *p, *bestp;
u_int i;
char *name;
struct kinfo_proc2 p;
buf = NULL;
if (stat(tty, &sb) == -1)
return (NULL);
if ((mib[3] = tcgetpgrp(fd)) == -1)
return (NULL);
retry:
if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
len = sizeof(p);
mib[0] = CTL_KERN;
mib[1] = KERN_PROC2;
mib[2] = KERN_PROC_PID;
mib[4] = sizeof(p);
mib[5] = 1;
if (sysctl(mib, nitems(mib), &p, &len, NULL, 0) == -1)
return (NULL);
len = (len * 5) / 4;
if ((newbuf = realloc(buf, len)) == NULL) {
free(buf);
return (NULL);
}
buf = newbuf;
if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) {
if (errno == ENOMEM)
goto retry;
free(buf);
return (NULL);
}
bestp = NULL;
for (i = 0; i < len / sizeof (struct kinfo_proc); i++) {
if (buf[i].p_tdev != sb.st_rdev)
continue;
p = &buf[i];
if (bestp == NULL) {
bestp = p;
continue;
}
if (is_runnable(p) && !is_runnable(bestp))
bestp = p;
else if (!is_runnable(p) && is_runnable(bestp))
continue;
if (!is_stopped(p) && is_stopped(bestp))
bestp = p;
else if (is_stopped(p) && !is_stopped(bestp))
continue;
if (p->p_estcpu > bestp->p_estcpu)
bestp = p;
else if (p->p_estcpu < bestp->p_estcpu)
continue;
if (p->p_slptime < bestp->p_slptime)
bestp = p;
else if (p->p_slptime > bestp->p_slptime)
continue;
if (strcmp(p->p_comm, p->p_comm) < 0)
bestp = p;
else if (strcmp(p->p_comm, p->p_comm) > 0)
continue;
if (p->p_pid > bestp->p_pid)
bestp = p;
}
name = NULL;
if (bestp != NULL)
name = strdup(bestp->p_comm);
free(buf);
return (name);
return (strdup(p.p_comm));
}
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-openbsd.c,v 1.14 2009-02-17 18:54:14 nicm Exp $ */
/* $Id: osdep-openbsd.c,v 1.16 2009-06-26 15:31:15 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,8 +16,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __OpenBSD__
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
@@ -27,7 +25,9 @@
#include <string.h>
#include <unistd.h>
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define is_runnable(p) \
((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC)
@@ -130,5 +130,3 @@ retry:
free(buf);
return (name);
}
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-unknown.c,v 1.4 2009-03-31 21:22:10 nicm Exp $ */
/* $Id: osdep-unknown.c,v 1.5 2009-04-29 23:07:35 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,9 +16,6 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__linux__) && \
!defined(__APPLE__) && !defined(__NetBSD__)
#include <sys/types.h>
#include "tmux.h"
@@ -28,5 +25,3 @@ osdep_get_name(unused int fd, unused char *tty)
{
return (NULL);
}
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: paste.c,v 1.6 2009-01-25 18:51:28 tcunha Exp $ */
/* $Id: paste.c,v 1.7 2009-07-02 16:23:54 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -101,6 +101,9 @@ paste_add(struct paste_stack *ps, char *data, u_int limit)
{
struct paste_buffer *pb;
if (*data == '\0')
return;
while (ARRAY_LENGTH(ps) >= limit)
ARRAY_TRUNC(ps, 1);

View File

@@ -1,4 +1,4 @@
/* $Id: screen-redraw.c,v 1.34 2009-04-02 21:08:13 nicm Exp $ */
/* $Id: screen-redraw.c,v 1.38 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -67,23 +67,40 @@ screen_redraw_screen(struct client *c)
struct window *w = c->session->curw->window;
struct tty *tty = &c->tty;
struct window_pane *wp;
struct screen *s;
u_int i, j, sx, sy;
int status;
int status, has_acs;
u_char choriz, cvert, cbackg;
/* Get status line, er, status. */
status = options_get_number(&c->session->options, "status");
/* Work out ACS characters. */
if (tty_term_has(tty->term, TTYC_ACSC)) {
has_acs = 1;
choriz = tty_get_acs(tty, 'q');
cvert = tty_get_acs(tty, 'x');
cbackg = tty_get_acs(tty, '~');
} else {
has_acs = 0;
choriz = '-';
cvert = '|';
cbackg = '.';
}
/* Clear the screen. */
tty_reset(tty);
if (has_acs)
tty_putcode(tty, TTYC_SMACS);
for (j = 0; j < tty->sy - status; j++) {
for (i = 0; i < tty->sx; i++) {
if (!screen_redraw_check_cell(c, i, j)) {
tty_cursor(tty, i, j, 0, 0);
tty_putc(tty, '.');
tty_putc(tty, cbackg);
}
}
}
if (has_acs)
tty_putcode(tty, TTYC_RMACS);
/* Draw the panes. */
TAILQ_FOREACH(wp, &w->panes, entry) {
@@ -92,40 +109,43 @@ screen_redraw_screen(struct client *c)
tty_reset(tty);
s = wp->screen;
sx = wp->sx;
sy = wp->sy;
/* Draw left and right borders. */
if (has_acs)
tty_putcode(tty, TTYC_SMACS);
if (wp->xoff > 0) {
for (i = wp->yoff; i < wp->yoff + sy; i++) {
tty_cursor(tty, wp->xoff - 1, i, 0, 0);
tty_putc(tty, '|');
tty_putc(tty, cvert);
}
}
if (wp->xoff + sx < tty->sx) {
for (i = wp->yoff; i < wp->yoff + sy; i++) {
tty_cursor(tty, wp->xoff + sx, i, 0, 0);
tty_putc(&c->tty, '|');
tty_putc(&c->tty, cvert);
}
}
/* Draw top and bottom borders. */
if (wp->yoff > 0) {
tty_cursor(tty, wp->xoff, wp->yoff - 1, 0, 0);
for (i = 0; i < sx; i++)
tty_putc(tty, '-');
}
tty_putc(tty, choriz);
}
if (wp->yoff + sy < tty->sy - status) {
tty_cursor(tty, wp->xoff, wp->yoff + sy, 0, 0);
for (i = 0; i < sx; i++)
tty_putc(tty, '-');
tty_putc(tty, choriz);
}
if (has_acs)
tty_putcode(tty, TTYC_RMACS);
/* Draw the pane. */
screen_redraw_pane(c, wp);
}
/* Draw the status line. */
screen_redraw_status(c);
}
@@ -139,7 +159,7 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
for (i = 0; i < wp->sy; i++)
tty_draw_line(&c->tty, wp->screen, i, wp->xoff, wp->yoff);
}
/* Draw the status line. */
void

View File

@@ -1,4 +1,4 @@
/* $Id: screen-write.c,v 1.43 2009-03-30 20:14:50 nicm Exp $ */
/* $Id: screen-write.c,v 1.56 2009-07-01 19:14:33 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -52,20 +52,126 @@ screen_write_putc(
screen_write_cell(ctx, gc, NULL);
}
/* Write string. */
void printflike3
screen_write_puts(
struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...)
/* Calculate string length. */
size_t printflike2
screen_write_strlen(int utf8flag, const char *fmt, ...)
{
va_list ap;
char *msg, *ptr;
char *msg;
u_char *ptr, utf8buf[4];
size_t left, size = 0;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
for (ptr = msg; *ptr != '\0'; ptr++)
screen_write_putc(ctx, gc, (u_char) *ptr);
ptr = msg;
while (*ptr != '\0') {
if (utf8flag && *ptr > 0x7f) {
memset(utf8buf, 0xff, sizeof utf8buf);
left = strlen(ptr);
if (*ptr >= 0xc2 && *ptr <= 0xdf && left >= 2) {
memcpy(utf8buf, ptr, 2);
ptr += 2;
} else if (*ptr >= 0xe0 && *ptr <= 0xef && left >= 3) {
memcpy(utf8buf, ptr, 3);
ptr += 3;
} else if (*ptr >= 0xf0 && *ptr <= 0xf4 && left >= 4) {
memcpy(utf8buf, ptr, 4);
ptr += 4;
} else {
*utf8buf = *ptr;
ptr++;
}
size += utf8_width(utf8buf);
} else {
size++;
ptr++;
}
}
return (size);
}
/* Write simple string (no UTF-8 or maximum length). */
void printflike3
screen_write_puts(
struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
screen_write_vnputs(ctx, -1, gc, 0, fmt, ap);
va_end(ap);
}
/* Write string with length limit (-1 for unlimited). */
void printflike5
screen_write_nputs(struct screen_write_ctx *ctx,
ssize_t maxlen, struct grid_cell *gc, int utf8flag, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
screen_write_vnputs(ctx, maxlen, gc, utf8flag, fmt, ap);
va_end(ap);
}
void
screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
struct grid_cell *gc, int utf8flag, const char *fmt, va_list ap)
{
char *msg;
u_char *ptr, utf8buf[4];
size_t left, size = 0;
int width;
xvasprintf(&msg, fmt, ap);
ptr = msg;
while (*ptr != '\0') {
if (utf8flag && *ptr > 0x7f) {
memset(utf8buf, 0xff, sizeof utf8buf);
left = strlen(ptr);
if (*ptr >= 0xc2 && *ptr <= 0xdf && left >= 2) {
memcpy(utf8buf, ptr, 2);
ptr += 2;
} else if (*ptr >= 0xe0 && *ptr <= 0xef && left >= 3) {
memcpy(utf8buf, ptr, 3);
ptr += 3;
} else if (*ptr >= 0xf0 && *ptr <= 0xf4 && left >= 4) {
memcpy(utf8buf, ptr, 4);
ptr += 4;
} else {
*utf8buf = *ptr;
ptr++;
}
width = utf8_width(utf8buf);
if (maxlen > 0 && size + width > (size_t) maxlen) {
while (size < (size_t) maxlen) {
screen_write_putc(ctx, gc, ' ');
size++;
}
break;
}
size += width;
gc->flags |= GRID_FLAG_UTF8;
screen_write_cell(ctx, gc, utf8buf);
gc->flags &= ~GRID_FLAG_UTF8;
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
size++;
screen_write_putc(ctx, gc, *ptr);
ptr++;
}
}
xfree(msg);
}
@@ -185,6 +291,31 @@ screen_write_cursorleft(struct screen_write_ctx *ctx, u_int nx)
s->cx -= nx;
}
/* VT100 alignment test. */
void
screen_write_alignmenttest(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
struct grid_cell gc;
u_int xx, yy;
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.data = 'E';
for (yy = 0; yy < screen_size_y(s); yy++) {
for (xx = 0; xx < screen_size_x(s); xx++)
grid_view_set_cell(s->grid, xx, yy, &gc);
}
s->cx = 0;
s->cy = 0;
s->rupper = 0;
s->rlower = screen_size_y(s) - 1;
tty_write_cmd(ctx->wp, TTY_ALIGNMENTTEST);
}
/* Insert nx characters. */
void
screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
@@ -194,8 +325,8 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0)
nx = 1;
if (nx > screen_size_x(s) - 1 - s->cx)
nx = screen_size_x(s) - 1 - s->cx;
if (nx > screen_size_x(s) - s->cx)
nx = screen_size_x(s) - s->cx;
if (nx == 0)
return;
@@ -216,8 +347,8 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0)
nx = 1;
if (nx > screen_size_x(s) - 1 - s->cx)
nx = screen_size_x(s) - 1 - s->cx;
if (nx > screen_size_x(s) - s->cx)
nx = screen_size_x(s) - s->cx;
if (nx == 0)
return;
@@ -238,8 +369,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0)
ny = 1;
if (ny > screen_size_y(s) - 1 - s->cy)
ny = screen_size_y(s) - 1 - s->cy;
if (ny > screen_size_y(s) - s->cy)
ny = screen_size_y(s) - s->cy;
if (ny == 0)
return;
@@ -264,8 +395,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0)
ny = 1;
if (ny > screen_size_y(s) - 1 - s->cy)
ny = screen_size_y(s) - 1 - s->cy;
if (ny > screen_size_y(s) - s->cy)
ny = screen_size_y(s) - s->cy;
if (ny == 0)
return;
@@ -499,11 +630,11 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
sx = screen_size_x(s);
if (s->cy > 0)
grid_view_clear(s->grid, 0, 0, sx, s->cy - 1);
grid_view_clear(s->grid, 0, 0, sx, s->cy);
if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1);
else
grid_view_clear(s->grid, 0, s->cy, s->cx, 1);
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1);
tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN);
}
@@ -529,9 +660,10 @@ screen_write_cell(
struct screen *s = ctx->s;
struct grid *gd = s->grid;
struct grid_utf8 gu, *tmp_gu;
u_int width, uvalue, xx, i;
u_int width, xx, i;
struct grid_cell tmp_gc, *tmp_gc2;
size_t size;
int insert = 0;
/* Ignore padding. */
if (gc->flags & GRID_FLAG_PADDING)
@@ -539,8 +671,7 @@ screen_write_cell(
/* Find character width. */
if (gc->flags & GRID_FLAG_UTF8) {
uvalue = utf8_combine(udata);
width = utf8_width(uvalue);
width = utf8_width(udata);
gu.width = width;
memcpy(&gu.data, udata, sizeof gu.data);
@@ -584,6 +715,13 @@ screen_write_cell(
gc = &tmp_gc;
}
/* If in insert mode, make space for the cells. */
if (s->mode & MODE_INSERT && s->cx <= screen_size_x(s) - width) {
xx = screen_size_x(s) - s->cx - width;
grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx);
insert = 1;
}
/* Check this will fit on the current line; scroll if not. */
if (s->cx > screen_size_x(s) - width) {
screen_write_carriagereturn(ctx);
@@ -611,12 +749,14 @@ screen_write_cell(
grid_view_set_cell(gd, s->cx, s->cy, gc);
if (gc->flags & GRID_FLAG_UTF8)
grid_view_set_utf8(gd, s->cx, s->cy, &gu);
/* Move the cursor. */
screen_write_save(ctx);
s->cx += width;
/* Draw to the screen if necessary. */
if (insert)
tty_write_cmd(ctx->wp, TTY_INSERTCHARACTER, width);
if (screen_check_selection(s, s->cx - width, s->cy)) {
s->sel.cell.data = gc->data;
tty_write_cmd(ctx->wp, TTY_CELL, &s->sel.cell, &gu);

119
screen.c
View File

@@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.81 2009-03-28 20:17:29 nicm Exp $ */
/* $Id: screen.c,v 1.88 2009-06-25 20:27:31 nicm 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"
@@ -33,6 +34,8 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
s->title = xstrdup("");
s->tabs = NULL;
screen_reinit(s);
}
@@ -47,6 +50,8 @@ screen_reinit(struct screen *s)
s->rlower = screen_size_y(s) - 1;
s->mode = MODE_CURSOR;
screen_reset_tabs(s);
grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy - 1);
@@ -61,12 +66,31 @@ screen_free(struct screen *s)
grid_destroy(s->grid);
}
/* Reset tabs to default, eight spaces apart. */
void
screen_reset_tabs(struct screen *s)
{
u_int i;
if (s->tabs != NULL)
xfree(s->tabs);
if ((s->tabs = bit_alloc(screen_size_x(s))) == NULL)
fatal("bit_alloc failed");
for (i = 8; i < screen_size_x(s); i += 8)
bit_set(s->tabs, i);
}
/* Set screen title. */
void
screen_set_title(struct screen *s, const char *title)
{
char tmp[BUFSIZ];
strnvis(tmp, title, sizeof tmp, VIS_OCTAL|VIS_TAB|VIS_NL);
xfree(s->title);
s->title = xstrdup(title);
s->title = xstrdup(tmp);
}
/* Resize screen. */
@@ -78,8 +102,17 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
if (sy < 1)
sy = 1;
if (sx != screen_size_x(s))
if (sx != screen_size_x(s)) {
screen_resize_x(s, sx);
/*
* It is unclear what should happen to tabs on resize. xterm
* seems to try and maintain them, rxvt resets them. Resetting
* is simpler and more reliable so let's do that.
*/
screen_reset_tabs(s);
}
if (sy != screen_size_y(s))
screen_resize_y(s, sy);
}
@@ -135,38 +168,42 @@ void
screen_resize_y(struct screen *s, u_int sy)
{
struct grid *gd = s->grid;
u_int oy, yy, ny;
u_int needed, available, oldy, i;
if (sy == 0)
fatalx("zero size");
oldy = screen_size_y(s);
/*
* When resizing:
*
* If the height is decreasing, delete lines from the bottom until
* hitting the cursor, then push lines from the top into the history.
*
* When increasing, pull as many lines as possible from the history to
* the top, then fill the remaining with blanks at the bottom.
*/
/* Size decreasing. */
if (sy < screen_size_y(s)) {
oy = screen_size_y(s);
if (sy < oldy) {
needed = oldy - sy;
if (s->cy != 0) {
/*
* The cursor is not at the start. Try to remove as
* many lines as possible from the top. (Up to the
* cursor line.)
*/
ny = s->cy;
if (ny > oy - sy)
ny = oy - sy;
grid_view_delete_lines(gd, 0, ny);
s->cy -= ny;
oy -= ny;
/* Delete as many lines as possible from the bottom. */
available = oldy - 1 - s->cy;
if (available > 0) {
if (available > needed)
available = needed;
grid_view_delete_lines(gd, oldy - available, available);
}
needed -= available;
if (sy < oy) {
/* Remove any remaining lines from the bottom. */
grid_view_delete_lines(gd, sy, oy - sy);
if (s->cy >= sy)
s->cy = sy - 1;
}
}
/*
* Now just increase the history size to take over the lines
* which are left. XXX Should apply history limit?
*/
gd->hsize += needed;
s->cy -= needed;
}
/* Resize line arrays. */
gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size);
@@ -175,18 +212,30 @@ screen_resize_y(struct screen *s, u_int sy)
gd->udata = xrealloc(gd->udata, gd->hsize + sy, sizeof *gd->udata);
/* Size increasing. */
if (sy > screen_size_y(s)) {
oy = screen_size_y(s);
for (yy = gd->hsize + oy; yy < gd->hsize + sy; yy++) {
gd->size[yy] = 0;
gd->data[yy] = NULL;
gd->usize[yy] = 0;
gd->udata[yy] = NULL;
if (sy > oldy) {
needed = sy - oldy;
/* Try to pull as much as possible out of the history. */
available = gd->hsize;
if (available > 0) {
if (available > needed)
available = needed;
gd->hsize -= available;
s->cy += available;
}
needed -= available;
/* Then fill the rest in with blanks. */
for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++) {
gd->size[i] = 0;
gd->data[i] = NULL;
gd->usize[i] = 0;
gd->udata[i] = NULL;
}
}
/* Set the new size, and reset the scroll region. */
gd->sy = sy;
s->rupper = 0;
s->rlower = screen_size_y(s) - 1;
}

View File

@@ -1,4 +1,4 @@
/* $Id: server-fn.c,v 1.58 2009-04-02 20:30:20 nicm Exp $ */
/* $Id: server-fn.c,v 1.65 2009-07-01 19:15:12 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,6 +20,7 @@
#include <sys/time.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "tmux.h"
@@ -75,22 +76,6 @@ server_write_session(
}
}
void
server_write_window(
struct window *w, enum hdrtype type, const void *buf, size_t len)
{
struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c->session->curw->window == w)
server_write_client(c, type, buf, len);
}
}
void
server_redraw_client(struct client *c)
{
@@ -183,7 +168,8 @@ server_lock(void)
continue;
status_prompt_clear(c);
status_prompt_set(c, "Password: ", server_lock_callback, c, 1);
status_prompt_set(
c, "Password: ", server_lock_callback, c, PROMPT_HIDDEN);
server_redraw_client(c);
}
server_locked = 1;
@@ -204,13 +190,14 @@ server_unlock(const char *s)
if (!server_locked)
return (0);
server_activity = time(NULL);
if (server_password != NULL) {
if (s == NULL)
return (-1);
out = crypt(s, server_password);
if (strcmp(out, server_password) != 0)
return (-1);
goto wrong;
}
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -221,7 +208,20 @@ server_unlock(const char *s)
status_prompt_clear(c);
server_redraw_client(c);
}
server_locked = 0;
server_locked = 0;
return (0);
wrong:
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->prompt_buffer == NULL)
continue;
*c->prompt_buffer = '\0';
c->prompt_index = 0;
server_status_client(c);
}
return (-1);
}

View File

@@ -1,4 +1,4 @@
/* $Id: server-msg.c,v 1.65 2009-03-07 10:29:06 nicm Exp $ */
/* $Id: server-msg.c,v 1.69 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -155,7 +155,7 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
if (data.pid != -1) {
TAILQ_FOREACH(cmd, cmdlist, qentry) {
if (cmd->entry->flags & CMD_CANTNEST) {
server_msg_fn_command_error(&ctx,
server_msg_fn_command_error(&ctx,
"sessions should be nested with care. "
"unset $TMUX to force");
cmd_list_free(cmdlist);
@@ -196,6 +196,7 @@ server_msg_fn_identify(struct hdr *hdr, struct client *c)
c->tty.sy = data.sy;
c->cwd = NULL;
data.cwd[(sizeof data.cwd) - 1] = '\0';
if (*data.cwd != '\0')
c->cwd = xstrdup(data.cwd);
@@ -233,12 +234,12 @@ server_msg_fn_resize(struct hdr *hdr, struct client *c)
c->tty.sy = data.sy;
if (c->tty.sy == 0)
c->tty.sy = 25;
c->tty.cx = UINT_MAX;
c->tty.cy = UINT_MAX;
c->tty.rupper = UINT_MAX;
c->tty.rlower = UINT_MAX;
recalculate_sizes();
/* Always redraw this client. */
@@ -278,13 +279,14 @@ server_msg_fn_unlock(struct hdr *hdr, struct client *c)
if (server_unlock(pass) != 0) {
#define MSG "bad password"
server_write_client(c, MSG_ERROR, MSG, (sizeof MSG) - 1);
server_write_client(c, MSG_EXIT, NULL, 0);
return (0);
#undef MSG
}
server_write_client(c, MSG_EXIT, NULL, 0);
memset(pass, 0, strlen(pass));
xfree(pass);
return (0);
}

239
server.c
View File

@@ -1,4 +1,4 @@
/* $Id: server.c,v 1.137 2009-04-16 10:59:59 nicm Exp $ */
/* $Id: server.c,v 1.153 2009-07-01 23:06:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -43,6 +43,7 @@
/* Client list. */
struct clients clients;
int server_create_socket(void);
int server_main(int);
void server_shutdown(void);
void server_child_signal(void);
@@ -52,7 +53,13 @@ void server_fill_clients(struct pollfd **);
void server_handle_clients(struct pollfd **);
struct client *server_accept_client(int);
void server_handle_client(struct client *);
void server_handle_window(struct window *, struct window_pane *wp);
void server_handle_window(struct window *, struct window_pane *);
int server_check_window_bell(struct session *, struct window *,
struct window_pane *);
int server_check_window_activity(struct session *,
struct window *);
int server_check_window_content(struct session *, struct window *,
struct window_pane *);
void server_lost_client(struct client *);
void server_check_window(struct window *);
void server_check_redraw(struct client *);
@@ -124,13 +131,10 @@ server_client_index(struct client *c)
int
server_start(char *path)
{
struct sockaddr_un sa;
size_t size;
mode_t mask;
int n, fd, pair[2], mode;
char *cause;
#ifndef NO_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
int pair[2], srv_fd, null_fd;
char *cause;
#ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
#endif
/* The first client is special and gets a socketpair; create it. */
@@ -148,10 +152,6 @@ server_start(char *path)
}
close(pair[0]);
#ifdef DEBUG
xmalloc_clear();
#endif
/*
* Must daemonise before loading configuration as the PID changes so
* $TMUX would be wrong for sessions created in the config file.
@@ -163,6 +163,7 @@ server_start(char *path)
ARRAY_INIT(&clients);
ARRAY_INIT(&sessions);
key_bindings_init();
utf8_build();
server_locked = 0;
server_password = NULL;
@@ -177,15 +178,42 @@ server_start(char *path)
}
logfile("server");
/*
* Close stdin/stdout/stderr. Can't let daemon() do this as they are
* needed until now to print configuration file errors.
*/
if ((null_fd = open(_PATH_DEVNULL, O_RDWR)) != -1) {
dup2(null_fd, STDIN_FILENO);
dup2(null_fd, STDOUT_FILENO);
dup2(null_fd, STDERR_FILENO);
if (null_fd > 2)
close(null_fd);
}
log_debug("server started, pid %ld", (long) getpid());
log_debug("socket path %s", socket_path);
#ifndef NO_SETPROCTITLE
#ifdef HAVE_SETPROCTITLE
if (realpath(socket_path, rpathbuf) == NULL)
strlcpy(rpathbuf, socket_path, sizeof rpathbuf);
setproctitle("server (%s)", rpathbuf);
#endif
srv_fd = server_create_socket();
server_create_client(pair[1]);
exit(server_main(srv_fd));
}
/* Create server socket. */
int
server_create_socket(void)
{
struct sockaddr_un sa;
size_t size;
mode_t mask;
int fd, mode;
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
@@ -213,13 +241,7 @@ server_start(char *path)
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
server_create_client(pair[1]);
n = server_main(fd);
#ifdef DEBUG
xmalloc_report(getpid(), "server");
#endif
exit(n);
return (fd);
}
/* Main server loop. */
@@ -248,6 +270,13 @@ server_main(int srv_fd)
sigchld = 0;
}
/* Recreate socket on SIGUSR1. */
if (sigusr1) {
close(srv_fd);
srv_fd = server_create_socket();
sigusr1 = 0;
}
/* Initialise pollfd array. */
nfds = 1;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
@@ -272,10 +301,10 @@ server_main(int srv_fd)
/* Update socket permissions. */
xtimeout = INFTIM;
if (sigterm || server_update_socket() != 0)
xtimeout = 100;
xtimeout = POLL_TIMEOUT;
/* Do the poll. */
if ((nfds = poll(pfds, nfds, xtimeout)) == -1) {
if (poll(pfds, nfds, xtimeout) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
@@ -283,7 +312,7 @@ server_main(int srv_fd)
pfd = pfds;
/* Handle server socket. */
#ifndef BROKEN_POLL
#ifdef HAVE_POLL
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
fatalx("lost server socket");
#endif
@@ -422,7 +451,7 @@ server_child_signal(void)
}
}
}
/* Fill window pollfds. */
void
server_fill_windows(struct pollfd **pfd)
@@ -553,7 +582,7 @@ server_redraw_locked(struct client *c)
&global_window_options, "clock-mode-colour");
style = options_get_number(
&global_window_options, "clock-mode-style");
screen_init(&screen, xx, yy, 0);
screen_write_start(&ctx, NULL, &screen);
@@ -595,12 +624,12 @@ server_check_timers(struct client *c)
if (!options_get_number(&s->options, "status"))
return;
/* Check timer; resolution is only a second so don't be too clever. */
interval = options_get_number(&s->options, "status-interval");
if (interval == 0)
return;
tv.tv_sec -= interval;
if (timercmp(&c->status_timer, &tv, <))
if (tv.tv_sec < c->status_timer.tv_sec ||
((u_int) tv.tv_sec) - c->status_timer.tv_sec >= interval)
c->flags |= CLIENT_STATUS;
}
@@ -640,7 +669,7 @@ server_fill_clients(struct pollfd **pfd)
}
(*pfd)++;
}
/*
* Clear any window redraw flags (will have been redrawn as part of
* client).
@@ -649,7 +678,7 @@ server_fill_clients(struct pollfd **pfd)
w = ARRAY_ITEM(&windows, i);
if (w == NULL)
continue;
w->flags &= ~WINDOW_REDRAW;
TAILQ_FOREACH(wp, &w->panes, entry)
wp->flags &= ~PANE_REDRAW;
@@ -744,7 +773,7 @@ server_handle_client(struct client *c)
}
if (server_locked)
continue;
/* Check for mouse keys. */
if (key == KEYC_MOUSE) {
window_pane_mouse(wp, c, mouse[0], mouse[1], mouse[2]);
@@ -783,7 +812,7 @@ server_handle_client(struct client *c)
window_pane_key(wp, c, key);
continue;
}
/* If this key can repeat, reset the repeat flags and timer. */
if (xtimeout != 0 && bd->can_repeat) {
c->flags |= CLIENT_PREFIX|CLIENT_REPEAT;
@@ -802,7 +831,7 @@ server_handle_client(struct client *c)
return;
wp = c->session->curw->window->active; /* could die - do each loop */
s = wp->screen;
/* Ensure cursor position and mode settings. */
status = options_get_number(&c->session->options, "status");
if (wp->yoff + s->cy < c->tty.sy - status)
@@ -859,13 +888,12 @@ void
server_handle_window(struct window *w, struct window_pane *wp)
{
struct session *s;
struct client *c;
u_int i, j;
int action, update;
u_int i;
int update;
window_pane_parse(wp);
if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY))
if ((w->flags & (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT)) == 0)
return;
update = 0;
@@ -874,48 +902,89 @@ server_handle_window(struct window *w, struct window_pane *wp)
if (s == NULL || !session_has(s, w))
continue;
if (w->flags & WINDOW_BELL &&
!session_alert_has_window(s, w, WINDOW_BELL)) {
session_alert_add(s, w, WINDOW_BELL);
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
if (s->flags & SESSION_UNATTACHED)
break;
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
case BELL_CURRENT:
if (w->active != wp)
break;
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
}
update = 1;
}
if (options_get_number(&w->options, "monitor-activity") &&
(w->flags & WINDOW_ACTIVITY) &&
!session_alert_has_window(s, w, WINDOW_ACTIVITY)) {
session_alert_add(s, w, WINDOW_ACTIVITY);
update = 1;
}
update += server_check_window_bell(s, w, wp);
update += server_check_window_activity(s, w);
update += server_check_window_content(s, w, wp);
}
if (update)
server_status_window(w);
w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY);
w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT);
}
/* Check if window still exists.. */
int
server_check_window_bell(
struct session *s, struct window *w, struct window_pane *wp)
{
struct client *c;
u_int i;
int action;
if (!(w->flags & WINDOW_BELL))
return (0);
if (session_alert_has_window(s, w, WINDOW_BELL))
return (0);
session_alert_add(s, w, WINDOW_BELL);
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
if (s->flags & SESSION_UNATTACHED)
break;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
case BELL_CURRENT:
if (w->active != wp)
break;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
}
return (1);
}
int
server_check_window_activity(struct session *s, struct window *w)
{
if (!(w->flags & WINDOW_ACTIVITY))
return (0);
if (!options_get_number(&w->options, "monitor-activity"))
return (0);
if (session_alert_has_window(s, w, WINDOW_ACTIVITY))
return (0);
session_alert_add(s, w, WINDOW_ACTIVITY);
return (1);
}
int
server_check_window_content(
struct session *s, struct window *w, struct window_pane *wp)
{
char *found, *ptr;
if (!(w->flags & WINDOW_CONTENT))
return (0);
if ((ptr = options_get_string(&w->options, "monitor-content")) == NULL)
return (0);
if (*ptr == '\0')
return (0);
if (session_alert_has_window(s, w, WINDOW_CONTENT))
return (0);
if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
return (0);
session_alert_add(s, w, WINDOW_CONTENT);
xfree(found);
return (1);
}
/* Check if window still exists. */
void
server_check_window(struct window *w)
{
@@ -933,15 +1002,20 @@ server_check_window(struct window *w)
wp = TAILQ_FIRST(&w->panes);
while (wp != NULL) {
wq = TAILQ_NEXT(wp, entry);
if (wp->fd != -1)
destroyed = 0;
else if (!flag) {
/*
* If the pane has died and the remain-on-exit flag is not set,
* remove the pane; otherwise, if the flag is set, don't allow
* the window to be destroyed (or it'll close when the last
* pane dies).
*/
if (wp->fd == -1 && !flag) {
window_remove_pane(w, wp);
server_redraw_window(w);
layout_refresh(w, 0);
}
} else
destroyed = 0;
wp = wq;
}
}
if (!destroyed)
return;
@@ -1008,6 +1082,7 @@ server_second_timers(void)
}
}
/* Check for a minute having passed. */
gmtime_r(&t, &now);
gmtime_r(&last_t, &then);
if (now.tm_min == then.tm_min)
@@ -1020,12 +1095,12 @@ server_second_timers(void)
if (ARRAY_ITEM(&clients, i) != NULL)
server_redraw_client(ARRAY_ITEM(&clients, i));
}
}
}
}
/* Update socket execute permissions based on whether sessions are attached. */
int
server_update_socket()
server_update_socket(void)
{
struct session *s;
u_int i;

View File

@@ -1,4 +1,4 @@
/* $Id: session.c,v 1.55 2009-03-21 12:44:06 nicm Exp $ */
/* $Id: session.c,v 1.57 2009-05-19 13:32:55 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -212,7 +212,7 @@ session_new(struct session *s,
if (options_get_number(&s->options, "set-remain-on-exit"))
options_set_number(&w->options, "remain-on-exit", 1);
return (session_attach(s, w, idx, cause));
}
@@ -266,6 +266,8 @@ session_next_activity(struct session *s, struct winlink *wl)
break;
if (session_alert_has(s, wl, WINDOW_ACTIVITY))
break;
if (session_alert_has(s, wl, WINDOW_CONTENT))
break;
wl = winlink_next(&s->windows, wl);
}
return (wl);
@@ -305,6 +307,8 @@ session_previous_activity(struct session *s, struct winlink *wl)
break;
if (session_alert_has(s, wl, WINDOW_ACTIVITY))
break;
if (session_alert_has(s, wl, WINDOW_CONTENT))
break;
wl = winlink_previous(&s->windows, wl);
}
return (wl);

117
status.c
View File

@@ -1,4 +1,4 @@
/* $Id: status.c,v 1.75 2009-02-13 21:39:45 nicm Exp $ */
/* $Id: status.c,v 1.90 2009-07-01 23:06:32 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,10 +47,10 @@ status_redraw(struct client *c)
struct window_pane *wp;
struct screen *sc = NULL, old_status;
char *left, *right, *text, *ptr;
size_t llen, rlen, offset, xx, yy, sy;
size_t size, start, width;
size_t llen, llen2, rlen, rlen2, offset;
size_t xx, yy, sy, size, start, width;
struct grid_cell stdgc, gc;
int larrow, rarrow;
int larrow, rarrow, utf8flag;
left = right = NULL;
@@ -74,20 +74,23 @@ status_redraw(struct client *c)
if (yy == 0)
goto blank;
/* Caring about UTF-8 in status line? */
utf8flag = options_get_number(&s->options, "status-utf8");
/* Work out the left and right strings. */
left = status_replace(s, options_get_string(
&s->options, "status-left"), c->status_timer.tv_sec);
llen = options_get_number(&s->options, "status-left-length");
if (strlen(left) < llen)
llen = strlen(left);
left[llen] = '\0';
llen2 = screen_write_strlen(utf8flag, "%s", left);
if (llen2 < llen)
llen = llen2;
right = status_replace(s, options_get_string(
&s->options, "status-right"), c->status_timer.tv_sec);
rlen = options_get_number(&s->options, "status-right-length");
if (strlen(right) < rlen)
rlen = strlen(right);
right[rlen] = '\0';
rlen2 = screen_write_strlen(utf8flag, "%s", right);
if (rlen2 < rlen)
rlen = rlen2;
/*
* Figure out how much space we have for the window list. If there isn't
@@ -163,7 +166,8 @@ draw:
screen_write_start(&ctx, NULL, &c->status);
if (llen != 0) {
screen_write_cursormove(&ctx, 0, yy);
screen_write_puts(&ctx, &stdgc, "%s ", left);
screen_write_nputs(&ctx, llen, &stdgc, utf8flag, "%s", left);
screen_write_putc(&ctx, &stdgc, ' ');
if (larrow)
screen_write_putc(&ctx, &stdgc, ' ');
} else {
@@ -182,7 +186,9 @@ draw:
if (larrow == 1 && offset < start) {
if (session_alert_has(s, wl, WINDOW_ACTIVITY))
larrow = -1;
if (session_alert_has(s, wl, WINDOW_BELL))
else if (session_alert_has(s, wl, WINDOW_BELL))
larrow = -1;
else if (session_alert_has(s, wl, WINDOW_CONTENT))
larrow = -1;
}
@@ -195,7 +201,9 @@ draw:
if (rarrow == 1 && offset > start + width) {
if (session_alert_has(s, wl, WINDOW_ACTIVITY))
rarrow = -1;
if (session_alert_has(s, wl, WINDOW_BELL))
else if (session_alert_has(s, wl, WINDOW_BELL))
rarrow = -1;
else if (session_alert_has(s, wl, WINDOW_CONTENT))
rarrow = -1;
}
@@ -216,7 +224,8 @@ draw:
/* Draw the last item. */
if (rlen != 0) {
screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, yy);
screen_write_puts(&ctx, &stdgc, " %s", right);
screen_write_putc(&ctx, &stdgc, ' ');
screen_write_nputs(&ctx, rlen, &stdgc, utf8flag, "%s", right);
}
/* Draw the arrows. */
@@ -439,18 +448,7 @@ out:
size_t
status_width(struct winlink *wl)
{
#ifndef BROKEN_VSNPRINTF
return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name));
#else
char *s;
size_t n;
xasprintf(&s, "%d:%s ", wl->idx, wl->window->name);
n = strlen(s);
xfree(s);
return (n);
#endif
}
char *
@@ -478,10 +476,12 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
if (session_alert_has(s, wl, WINDOW_ACTIVITY)) {
flag = '#';
gc->attr ^= GRID_ATTR_REVERSE;
}
if (session_alert_has(s, wl, WINDOW_BELL)) {
} else if (session_alert_has(s, wl, WINDOW_BELL)) {
flag = '!';
gc->attr ^= GRID_ATTR_REVERSE;
} else if (session_alert_has(s, wl, WINDOW_CONTENT)) {
flag = '+';
gc->attr ^= GRID_ATTR_REVERSE;
}
xasprintf(&text, "%d:%s%c", wl->idx, wl->window->name, flag);
@@ -563,7 +563,7 @@ status_message_redraw(struct client *c)
void
status_prompt_set(struct client *c,
const char *msg, int (*fn)(void *, const char *), void *data, int hide)
const char *msg, int (*fn)(void *, const char *), void *data, int flags)
{
c->prompt_string = xstrdup(msg);
@@ -575,7 +575,7 @@ status_prompt_set(struct client *c,
c->prompt_hindex = 0;
c->prompt_hidden = hide;
c->prompt_flags = flags;
mode_key_init(&c->prompt_mdata,
options_get_number(&c->session->options, "status-keys"),
@@ -596,6 +596,8 @@ status_prompt_clear(struct client *c)
xfree(c->prompt_string);
c->prompt_string = NULL;
if (c->prompt_flags & PROMPT_HIDDEN)
memset(c->prompt_buffer, 0, strlen(c->prompt_buffer));
xfree(c->prompt_buffer);
c->prompt_buffer = NULL;
@@ -644,7 +646,7 @@ status_prompt_redraw(struct client *c)
left--;
size = left;
}
if (c->prompt_hidden) {
if (c->prompt_flags & PROMPT_HIDDEN) {
n = strlen(c->prompt_buffer);
if (n > left)
n = left;
@@ -663,8 +665,12 @@ status_prompt_redraw(struct client *c)
screen_write_cursormove(&ctx, len + c->prompt_index - offset, 0);
if (c->prompt_index == strlen(c->prompt_buffer))
ch = ' ';
else
ch = c->prompt_buffer[c->prompt_index];
else {
if (c->prompt_flags & PROMPT_HIDDEN)
ch = '*';
else
ch = c->prompt_buffer[c->prompt_index];
}
if (ch == '\0')
ch = ' ';
gc.attr ^= GRID_ATTR_REVERSE;
@@ -684,9 +690,9 @@ status_prompt_redraw(struct client *c)
void
status_prompt_key(struct client *c, int key)
{
char *s, *first, *last;
size_t size, n, off, idx;
char word[64];
struct paste_buffer *pb;
char *s, *first, *last, word[64];
size_t size, n, off, idx;
size = strlen(c->prompt_buffer);
switch (mode_key_lookup(&c->prompt_mdata, key)) {
@@ -784,8 +790,13 @@ status_prompt_key(struct client *c, int key)
}
break;
case MODEKEYCMD_UP:
if (server_locked)
break;
if (ARRAY_LENGTH(&c->prompt_hdata) == 0)
break;
if (c->prompt_flags & PROMPT_HIDDEN)
memset(c->prompt_buffer, 0, strlen(c->prompt_buffer));
xfree(c->prompt_buffer);
c->prompt_buffer = xstrdup(ARRAY_ITEM(&c->prompt_hdata,
@@ -797,6 +808,11 @@ status_prompt_key(struct client *c, int key)
c->flags |= CLIENT_STATUS;
break;
case MODEKEYCMD_DOWN:
if (server_locked)
break;
if (c->prompt_flags & PROMPT_HIDDEN)
memset(c->prompt_buffer, 0, strlen(c->prompt_buffer));
xfree(c->prompt_buffer);
if (c->prompt_hindex != 0) {
@@ -808,6 +824,28 @@ status_prompt_key(struct client *c, int key)
c->prompt_buffer = xstrdup("");
c->prompt_index = strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
case MODEKEYCMD_PASTE:
if ((pb = paste_get_top(&c->session->buffers)) == NULL)
break;
if ((last = strchr(pb->data, '\n')) == NULL)
last = strchr(pb->data, '\0');
n = last - pb->data;
c->prompt_buffer = xrealloc(c->prompt_buffer, 1, size + n + 1);
if (c->prompt_index == size) {
memcpy(c->prompt_buffer + c->prompt_index, pb->data, n);
c->prompt_index += n;
c->prompt_buffer[c->prompt_index] = '\0';
} else {
memmove(c->prompt_buffer + c->prompt_index + n,
c->prompt_buffer + c->prompt_index,
size + 1 - c->prompt_index);
memcpy(c->prompt_buffer + c->prompt_index, pb->data, n);
c->prompt_index += n;
}
c->flags |= CLIENT_STATUS;
break;
case MODEKEYCMD_CHOOSE:
@@ -838,6 +876,12 @@ status_prompt_key(struct client *c, int key)
c->prompt_buffer[c->prompt_index++] = key;
}
if (c->prompt_flags & PROMPT_SINGLE) {
if (c->prompt_callback(
c->prompt_data, c->prompt_buffer) == 0)
status_prompt_clear(c);
}
c->flags |= CLIENT_STATUS;
break;
default:
@@ -849,6 +893,9 @@ status_prompt_key(struct client *c, int key)
void
status_prompt_add_history(struct client *c)
{
if (server_locked)
return;
if (ARRAY_LENGTH(&c->prompt_hdata) > 0 &&
strcmp(ARRAY_LAST(&c->prompt_hdata), c->prompt_buffer) == 0)
return;

374
tmux.1
View File

@@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.89 2009-04-21 20:06:46 nicm Exp $
.\" $Id: tmux.1,v 1.104 2009-07-01 23:06:32 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\"
@@ -14,16 +14,16 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd April 20, 2009
.Dd $Mdocdate: June 26 2009 $
.Dt TMUX 1
.Os
.Sh NAME
.Nm tmux
.Nd "terminal multiplexer"
.Nd terminal multiplexer
.Sh SYNOPSIS
.Nm tmux
.Bk -words
.Op Fl 28dqUuVv
.Op Fl 28dqUuv
.Op Fl f Ar file
.Op Fl L Ar socket-name
.Op Fl S Ar socket-path
@@ -31,7 +31,7 @@
.Ek
.Sh DESCRIPTION
.Nm
is a terminal multiplexer; it enables a number of terminals to be accessed and
is a terminal multiplexer: it enables a number of terminals to be accessed and
controlled from a single terminal.
.Pp
.Nm
@@ -61,7 +61,7 @@ to assume the terminal supports 256 colours.
.It Fl 8
Like
.Fl 2 ,
indicates the terminal supports 88 colours.
but indicates that the terminal supports 88 colours.
.It Fl d
Force
.Nm
@@ -75,9 +75,6 @@ will look for a config file at
The configuration file is a set of
.Nm
commands which are executed in sequence when the server is first started.
.It Fl q
Prevent the server sending various information messages, for example when
window flags are altered.
.It Fl L Ar socket-name
.Nm
stores the server socket in a directory under
@@ -92,9 +89,18 @@ Unlike
.Fl S
a full path is not necessary: the sockets are all created in the same
directory.
.Pp
If the socket is accidentally removed, the
.Dv SIGUSR1
signal may be sent to the
.Nm
server process to recreate it.
.It Fl q
Prevent the server sending various informational messages, for example when
window flags are altered.
.It Fl S Ar socket-path
Specify a full alternative path to the server socket.
If
If
.Fl S
is specified, the default socket directory is not used and any
.Fl L
@@ -102,11 +108,19 @@ flag is ignored.
.It Fl U
Unlock the server.
.It Fl u
Instruct
.Nm
that the terminal support UTF-8.
.It Fl V
Print program version.
attempts to guess if the terminal is likely to support UTF-8 by checking the
first of the
.Ev LC_ALL ,
.Ev LC_CTYPE
and
.Ev LANG
environment variables to be set for the string "UTF-8".
This is not always correct: the
.Fl u
flag explicitly informs
.Nm
that UTF-8 is supported.
.It Fl v
Request verbose logging.
This option may be specified multiple times for increasing verbosity.
@@ -116,18 +130,19 @@ and
.Pa tmux-server-PID.log
files in the current directory, where
.Em PID
is the pid of the server or client process.
is the PID of the server or client process.
.It Ar command Op Ar flags
This specifies one of a set of commands used to control
.Nm ,
and described in the following sections.
If no command and flags is specified, the
as described in the following sections.
If no command and flags are specified, the
.Ic new-session
command is assumed.
.Pp
.El
.Sh QUICK START
To create a new tmux session running
To create a new
.Nm
session running
.Xr vi 1 :
.Pp
.Dl $ tmux new-session vi
@@ -143,15 +158,17 @@ If there are several options, they are listed:
.Bd -literal -offset indent
$ tmux n
ambiguous command: n, could be: new-session, new-window, next-window
$
.Ed
.Pp
Within an active session, a new window may be created by typing
.Ql C-b
(ctrl-b, known as the prefix key)
.Ql C-b c
(Ctrl
followed by the
.Ql b
key
followed by the
.Ql c
key.
key).
.Pp
Windows may be navigated with:
.Ql C-b 0
@@ -173,31 +190,64 @@ Typing
.Ql C-b \&?
lists the current key bindings in the current window; up and down may be used
to navigate the list or
.Ql Q
.Ql q
to exit from it.
.Pp
Commands to be run when the
.Nm
server is started may be placed in the
.Pa ~/.tmux.conf
configuration file.
Common examples include:
.Pp
Changing the default prefix key:
.Bd -literal -offset indent
set-option -g prefix C-a
unbind-key C-b
bind-key C-a send-prefix
.Ed
.Pp
Turning the status line off, or changing its colour:
.Bd -literal -offset indent
set-option -g status off
set-option -g status-bg blue
.Ed
.Pp
Setting other options, such as the default command,
or locking after 30 minutes of inactivity:
.Bd -literal -offset indent
set-option -g default-command "exec /bin/ksh"
set-option -g lock-after-time 1800
.Ed
.Pp
Creating new key bindings:
.Bd -literal -offset indent
bind-key b set-option status
bind-key / command-prompt "split-window 'exec man %%'"
.Ed
.Sh KEY BINDINGS
.Nm
may be controlled from an attached client by using a key combination of a
prefix key,
.Ql C-b
(ctrl-b) by default, followed by a command key.
(Ctrl-b) by default, followed by a command key.
.Pp
Some of the default key bindings include:
.Pp
.Bl -tag -width Ds -compact
.It Ql d
Detach current client.
.It Ql c
.Bl -tag -width Ds -offset 3n -compact
.It c
Create new window.
.It Ql n
Change to next window in the current session.
.It Ql p
Change to previous window in the current session.
.It Ql l
.It d
Detach current client.
.It l
Move to last (previously selected) window in the current session.
.It Ql t
.It n
Change to next window in the current session.
.It p
Change to previous window in the current session.
.It t
Display a large clock.
.It Ql \&?
.It \&?
List current key bindings.
.El
.Pp
@@ -214,7 +264,7 @@ commands.
.Sh HISTORY
.Nm
maintains a configurable history buffer for each window.
By default, up to 2000 lines are kept, this can be altered with the
By default, up to 2000 lines are kept; this can be altered with the
.Ic history-limit
option (see the
.Ic set-option
@@ -247,11 +297,8 @@ command, bound to
by default.
.El
.Pp
The keys available depend on whether
.Xr emacs 1
or
.Xr vi 1
mode is selected (see the
The keys available depend on whether emacs or vi mode is selected
(see the
.Ic mode-keys
option).
The following keys are supported as appropriate for the mode:
@@ -271,8 +318,11 @@ The following keys are supported as appropriate for the mode:
.It Li "Cursor right" Ta "l" Ta "Right"
.It Li "Start selection" Ta "Space" Ta "C-Space"
.It Li "Cursor up" Ta "k" Ta "Up"
.It Li "Paste buffer" Ta "p" Ta "C-y"
.El
.Pp
The paste buffer key pastes the first line from the top paste buffer on the
stack.
.Sh BUFFERS
.Nm
maintains a stack of
@@ -319,23 +369,88 @@ commands may be used to swap panes without changing the window layout.
.Pp
The following layouts are supported:
.Bl -tag -width Ds
.It Ic manual
Manual layout splits windows vertically (running across); only with this layout
may panes be resized using the
.Ic resize-pane-up
and
.Ic resize-pane-down
commands.
.It Ic active-only
Only the active pane is shown - all other panes are hidden.
Only the active pane is shown \(en all other panes are hidden.
.It Ic even-horizontal
Panes are spread out evenly from left to right across the window.
.It Ic even-vertical
Panes are spread evenly from top to bottom.
.It Ic left-vertical
A large (81 column) pane is shown on the left of the window and the remaining
panes are spread from top to bottom in the leftover space to the right.
.It Ic main-horizontal
A large (main) pane is shown at the top of the window and the remaining panes are
spread from left to right in the leftover space at the bottom.
Use the
.Em main-pane-height
window option to specify the height of the top pane.
.It Ic main-vertical
Similar to
.Ic main-horizontal
but the large pane is placed on the left and the others spread from top to
bottom along the right.
See the
.Em main-pane-width
window option.
.It Ic manual
Manual layout splits windows vertically (running across); only with this layout
may panes be resized using the
.Ic resize-pane
command.
.El
.Sh STATUS LINE
.Nm
includes an optional status line which is displayed in the bottom line of each
terminal.
By default, the status line is enabled (it may be disabled with the
.Ic status
session option) and contains, from left-to-right: the name of the current
session in square brackets; the window list; the current window title in double
quotes; and the time and date.
.Pp
The status line is made of three parts: configurable left and right sections
(which may contain dynamic content such as the time or output from a shell
command, see the
.Ic status-left ,
.Ic status-left-length ,
.Ic status-right ,
and
.Ic status-right-length
options below), and a central window list.
The window list shows the index, name and (if any) flag of the windows
present in the current session in ascending numerical order.
The flag is one of the following symbols appended to the window name:
.Bl -column "Symbol" "Meaning" -offset indent
.It Sy "Symbol" Ta Sy "Meaning"
.It Li "*" Ta "Denotes the current window."
.It Li "-" Ta "Marks the last window (previously selected)."
.It Li "#" Ta "Window is monitored and activity has been detected."
.It Li "!" Ta "A bell has occurred in the window."
.It Li "+" Ta "Window is monitored for content and it has appeared."
.El
.Pp
The # symbol relates to the
.Ic monitor-activity
and + to the
.Ic monitor-content
window options.
The window name is printed in inverted colours if an alert (bell, activity or
content) is present.
.Pp
The colour and attributes of the status line may be configured, the entire status line using
the
.Ic status-attr ,
.Ic status-fg
and
.Ic status-bg
session options and individual windows using the
.Ic window-status-attr ,
.Ic window-status-fg
and
.Ic window-status-bg
window options.
.Pp
The status line is automatically refreshed at interval if it has changed, the interval may be
controlled with the
.Ic status-interval
session option.
.Sh COMMANDS
This section contains a list of the commands supported by
.Nm .
@@ -359,9 +474,9 @@ command.
.Ar target-session
is either the name of a session (as listed by the
.Ic list-sessions
command); or the name of a client as for
command) or the name of a client,
.Ar target-client ,
in this case, the session attached to the client is used.
in which case the session attached to the client is used.
An
.Xr fnmatch 3
pattern may be used to match the session name.
@@ -388,22 +503,20 @@ is omitted, the same rules as for
are followed; if
.Em index
is not present, the current window for the given session is used.
When the argument does not contain a colon (:),
When the argument does not contain a colon,
.Nm
first attempts to parse it as window index; if that fails, an attempt is made
to match a session or client name.
.Pp
Multiple commands may be specified together as part of a
Multiple commands may be specified together as part of a
.Em command sequence .
Each command should be separated by spaces and a semicolon
.Eo ( Ql \& \&; \& Ec ) ;
Each command should be separated by spaces and a semicolon;
commands are executed sequentially from left to right.
A literal semicolon may be included by escaping it with a backslash (for
example, when specifying a command sequence to
.Ic bind-key ) .
.Pp
Examples include:
.Pp
.Bd -literal -offset indent
refresh-client -t/dev/ttyp2
@@ -445,9 +558,9 @@ Keys may be specified prefixed with
.Ql C-
or
.Ql ^
for ctrl keys, or
for Ctrl keys, or
.Ql M-
for alt (meta) keys.
for Alt (meta) keys.
The
.Fl r
flag indicates this key may repeat, see the
@@ -458,6 +571,7 @@ option.
.Op Fl p Ar pane-index
.Op Fl t Ar target-window
.Xc
.D1 (alias: Ic breakp )
Break the current pane off from its containing window to make it the only pane
in a new window.
If
@@ -477,6 +591,12 @@ Put a window into window choice mode, where the window for the session
attached to the current client may be selected interactively from a list.
This command works only from inside
.Nm .
.It Xo Ic clear-history
.Op Fl p Ar pane-index
.Op Fl t Ar target-window
.Xc
.D1 (alias: Ic clearhist )
Remove and free the history for the specified pane.
.It Xo Ic clock-mode
.Op Fl t Ar target-window
.Xc
@@ -493,13 +613,22 @@ If
.Ar template
is specified, it is used as the command; any %% in the template will be
replaced by what is entered at the prompt.
.It Xo Ic confirm-before
.Op Fl t Ar target-client
.Ar command
.Xc
.D1 (alias: Ic confirm )
Ask for confirmation before executing
.Ar command .
This command works only from inside
.Nm .
.It Xo Ic copy-buffer
.Op Fl a Ar src-index
.Op Fl b Ar dst-index
.Op Fl s Ar src-session
.Op Fl t Ar dst-session
.Xc
.D1 (alias: Ic copyb)
.D1 (alias: Ic copyb )
Copy a session paste buffer to another session.
If no sessions are specified, the current one is used instead.
.It Xo Ic copy-mode
@@ -535,7 +664,9 @@ Move down a pane.
.Ar match-string
.Xc
.D1 (alias: Ic findw )
Search for
Search for the
.Xr fnmatch 3
pattern
.Ar match-string
in window names, titles, and visible content (but not history).
If only one window is matched, it'll be automatically selected, otherwise a
@@ -706,10 +837,14 @@ start-up files.
.D1 (alias: Ic nextl )
Move a window to the next layout and rearrange the panes to fit.
.It Xo Ic next-window
.Op Fl a
.Op Fl t Ar target-session
.Xc
.D1 (alias: Ic next )
Move to the next window in the session.
If
.Fl a
is used, move to the next window with a bell, activity or content alert.
.It Xo Ic paste-buffer
.Op Fl d
.Op Fl b Ar buffer-index
@@ -718,10 +853,14 @@ Move to the next window in the session.
.D1 (alias: Ic pasteb )
Insert the contents of a paste buffer into the current window.
.It Xo Ic previous-window
.Op Fl a
.Op Fl t Ar target-session
.Xc
.D1 (alias: Ic prev )
Move to the previous window in the session.
With
.Fl a ,
move to the previous window with a bell, activity or content alert.
.It Xo Ic refresh-client
.Op Fl t Ar target-client
.Xc
@@ -745,26 +884,24 @@ Rename the current window, or the window at
.Ar target-window
if specified, to
.Ar new-name .
.It Xo Ic resize-pane-down
.It Xo Ic resize-pane
.Op Fl DU
.Op Fl p Ar pane-index
.Op Fl t Ar target-window
.Op Ar adjustment
.Xc
.D1 (alias: Ic resizep-down )
.It Xo Ic resize-pane-up
.Op Fl p Ar pane-index
.Op Fl t Ar target-window
.Op Ar adjustment
.Xc
.D1 (alias: Ic resizep-up)
Resize a pane.
.D1 (alias: Ic resizep )
Resize a pane, upward with
.Fl U
(the default) or downward with
.Fl D .
The
.Ar adjustment
is given in lines (the default is 1).
.It Xo Ic respawn-window
.Op Fl k
.Op Fl t Ar target-window
.Op command
.Op Ar command
.Xc
.D1 (alias: Ic respawnw )
Reactive a window in which the command has exited (see the
@@ -807,6 +944,12 @@ The
has the same meaning as in the
.Ic copy-mode
command.
.It Xo Ic select-layout
.Op Fl t Ar target-window
.Ar layout-name
.Xc
.D1 (alias: selectl )
Choose a specific layout for a window.
.It Xo Ic select-pane
.Op Fl p Ar pane-index
.Op Fl t Ar target-window
@@ -901,8 +1044,12 @@ maintain this maximum length.
Set the command used for new windows (if not specified when the window is
created) to
.Ar command .
The default is
.Dq exec $SHELL .
The default is an empty string, which instructs
.Nm
to create a login shell using the
.Ev SHELL
environment variable or, if it is unset, the user's shell returned by
.Xr getpwuid 3 .
.It Ic default-path Ar path
Set the default working directory for processes created from keys, or
interactively from the prompt.
@@ -961,7 +1108,7 @@ Whether a key repeats may be set when it is bound using the
.Fl r
flag to
.Ic bind-key .
Repeat is enabled for the default keys of the
Repeat is enabled for the default keys of the
.Ic up-pane ,
.Ic down-pane ,
.Ic resize-pane-up ,
@@ -979,9 +1126,8 @@ window option for any windows first created in this session.
.Xc
Attempt to set the window title using the \ee]2;...\e007 xterm code and
the terminal appears to be an xterm.
This option is enabled by default.
Note that
.Xr elinks 1
This option is off by default.
Note that elinks
will only attempt to set the window title if the STY environment
variable is set.
.It Xo Ic status
@@ -1003,10 +1149,7 @@ A setting of zero disables redrawing at interval.
.It Xo Ic status-keys
.Op Ic vi | Ic emacs
.Xc
Use
.Xr vi 1 -
or
.Xr emacs 1 -style
Use vi or emacs-style
key bindings in the status line, for example at the command prompt.
Defaults to emacs.
.It Ic status-left Ar string
@@ -1017,7 +1160,7 @@ to the left of the status bar.
will be passed through
.Xr strftime 3
before being used.
By default, the session name is shown.
By default, the session name is shown.
.Ar string
may contain any of the following special character pairs:
.Bl -column "Character pair" "Replaced with" -offset indent
@@ -1032,6 +1175,12 @@ may contain any of the following special character pairs:
Where appropriate, these may be prefixed with a number to specify the maximum
length, for example
.Ql #24T .
.Pp
By default, UTF-8 in
.Ar string
is not interpreted, to enable UTF-8, use the
.Ic status-utf8
option.
.It Ic status-left-length Ar length
Set the maximum
.Ar length
@@ -1046,13 +1195,27 @@ As with
.Ic status-left ,
.Ar string
will be passed to
.Xr strftime 3
and character pairs are replaced.
.Xr strftime 3 ,
character pairs are replaced, and UTF-8 is dependent on the
.Ic status-utf8
option.
.It Ic status-right-length Ar length
Set the maximum
.Ar length
of the right component of the status bar.
The default is 40.
.Pp
.It Xo Ic status-utf8
.Op Ic on | Ic off
.Xc
Instruct
.Nm
to treat top-bit-set characters in the
.Ic status-left
and
.Ic status-right
strings as UTF-8; notably, this is important for wide characters.
This option defaults to off.
.El
.It Xo Ic set-password
.Op Fl c
@@ -1095,8 +1258,9 @@ This means that
will resize the window to the size of the smallest session for which it is the
current window, rather than the smallest session to which it is attached.
The window may resize when the current window is changed on another sessions;
this option is good for full-screen programs which support SIGWINCH and poor for
interactive programs such as shells.
this option is good for full-screen programs which support
.Dv SIGWINCH
and poor for interactive programs such as shells.
.It Xo Ic automatic-rename
.Op Ic on | Ic off
.Xc
@@ -1130,6 +1294,13 @@ from resizing a window to greater than
or
.Ar height .
A value of zero restores the default unlimited setting.
.It Ic main-pane-width Ar width
.It Ic main-pane-height Ar height
Set the width or height of the main (left or top) pane in the
.Ic main-horizontal
or
.Ic main-vertical
layouts.
.It Ic mode-attr Ar attributes
Set window modes attributes.
.It Ic mode-bg Ar colour
@@ -1139,10 +1310,7 @@ Set window modes foreground colour.
.It Xo Ic mode-keys
.Op Ic vi | Ic emacs
.Xc
Use
.Xr vi 1 -
or
.Xr emacs 1 -style
Use vi or emacs-style
key bindings in scroll and copy modes.
Key bindings default to emacs.
.It Xo Ic monitor-activity
@@ -1150,6 +1318,14 @@ Key bindings default to emacs.
.Xc
Monitor for activity in the window.
Windows with activity are highlighted in the status line.
.It Xo Ic monitor-content Ar match-string
.Xc
Monitor content in the window.
When
.Xr fnmatch 3
pattern
.Ar match-string
appears in the window, it is highlighted in the status line.
.It Xo Ic remain-on-exit
.Op Ic on | Ic off
.Xc
@@ -1178,7 +1354,7 @@ If this option is set,
will generate
.Xr xterm 1 -style
function key sequences; these have a number included to indicate modifiers such
as shift, meta or ctrl.
as Shift, Alt or Ctrl.
.El
.It Xo Ic show-buffer
.Op Fl b Ar buffer-index
@@ -1251,7 +1427,9 @@ server, if not already running, without creating any sessions.
.Op Fl c target-client
.Xc
.D1 (alias: Ic suspendc )
Suspend a client by sending SIGTSTP (tty stop).
Suspend a client by sending
.Dv SIGTSTP
(tty stop).
.It Xo Ic swap-pane
.Op Fl dDU
.Op Fl p Ar src-index
@@ -1308,11 +1486,11 @@ not be linked to no sessions.
Move up a pane.
.El
.Sh FILES
.Bl -tag -width Ds -compact
.Bl -tag -width "~/.tmux.confXXX" -compact
.It Pa ~/.tmux.conf
default
Default
.Nm
configuration file
configuration file.
.El
.Sh SEE ALSO
.Xr pty 4

120
tmux.c
View File

@@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.113 2009-04-20 19:25:58 nicm Exp $ */
/* $Id: tmux.c,v 1.138 2009-07-01 19:42:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,10 +27,6 @@
#include <syslog.h>
#include <unistd.h>
#ifndef NO_PATHS_H
#include <paths.h>
#endif
#include "tmux.h"
#ifdef DEBUG
@@ -47,6 +43,8 @@ volatile sig_atomic_t sigwinch;
volatile sig_atomic_t sigterm;
volatile sig_atomic_t sigcont;
volatile sig_atomic_t sigchld;
volatile sig_atomic_t sigusr1;
volatile sig_atomic_t sigusr2;
char *cfg_file;
struct options global_options;
@@ -64,15 +62,16 @@ char *socket_path;
__dead void usage(void);
char *makesockpath(const char *);
#ifdef NO_PROGNAME
#ifndef HAVE_PROGNAME
const char *__progname = "tmux";
#endif
__dead void
usage(void)
{
fprintf(stderr, "usage: %s [-28dqUuVv] [-f file] "
"[-L socket-name] [-S socket-path] [command [flags]]\n",
fprintf(stderr,
"usage: %s [-28dqUuv] [-f file] [-L socket-name] [-S socket-path]\n"
" [command [flags]]\n",
__progname);
exit(1);
}
@@ -110,6 +109,12 @@ sighandler(int sig)
case SIGCONT:
sigcont = 1;
break;
case SIGUSR1:
sigusr1 = 1;
break;
case SIGUSR2:
sigusr2 = 1;
break;
}
errno = saved_errno;
}
@@ -126,10 +131,6 @@ siginit(void)
act.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &act, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR1, &act, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR2, &act, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGINT, &act, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGTSTP, &act, NULL) != 0)
@@ -144,6 +145,10 @@ siginit(void)
fatal("sigaction failed");
if (sigaction(SIGCHLD, &act, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR1, &act, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR2, &act, NULL) != 0)
fatal("sigaction failed");
}
void
@@ -213,15 +218,14 @@ main(int argc, char **argv)
struct cmd *cmd;
struct pollfd pfd;
struct hdr hdr;
const char *shell;
struct passwd *pw;
char *path, *label, *cause, *home, *pass = NULL;
char *s, *path, *label, *cause, *home, *pass = NULL;
char cwd[MAXPATHLEN];
int retcode, opt, flags, unlock, start_server;
unlock = flags = 0;
label = path = NULL;
while ((opt = getopt(argc, argv, "28df:L:qS:uUVv")) != -1) {
while ((opt = getopt(argc, argv, "28df:L:qS:uUv")) != -1) {
switch (opt) {
case '2':
flags |= IDENTIFY_256COLOURS;
@@ -232,22 +236,16 @@ main(int argc, char **argv)
flags &= ~IDENTIFY_256COLOURS;
break;
case 'f':
if (cfg_file)
xfree(cfg_file);
cfg_file = xstrdup(optarg);
break;
case 'L':
if (path != NULL) {
log_warnx("-L and -S cannot be used together");
exit(1);
}
if (label != NULL)
xfree(label);
label = xstrdup(optarg);
break;
case 'S':
if (label != NULL) {
log_warnx("-L and -S cannot be used together");
exit(1);
}
if (path != NULL)
xfree(path);
path = xstrdup(optarg);
@@ -267,9 +265,6 @@ main(int argc, char **argv)
case 'v':
debug_level++;
break;
case 'V':
printf("%s " BUILD "\n", __progname);
exit(0);
default:
usage();
}
@@ -283,46 +278,68 @@ main(int argc, char **argv)
options_init(&global_options, NULL);
options_set_number(&global_options, "bell-action", BELL_ANY);
options_set_number(&global_options, "buffer-limit", 9);
options_set_string(&global_options, "default-command", "%s", "");
options_set_number(&global_options, "display-time", 750);
options_set_number(&global_options, "history-limit", 2000);
options_set_number(&global_options, "lock-after-time", 0);
options_set_number(&global_options, "message-attr", GRID_ATTR_REVERSE);
options_set_number(&global_options, "message-bg", 3);
options_set_number(&global_options, "message-fg", 0);
options_set_number(&global_options, "message-attr", GRID_ATTR_REVERSE);
options_set_number(&global_options, "prefix", META);
options_set_number(&global_options, "prefix", '\002');
options_set_number(&global_options, "repeat-time", 500);
options_set_number(&global_options, "set-titles", 1);
options_set_number(&global_options, "lock-after-time", 0);
options_set_number(&global_options, "set-remain-on-exit", 0);
options_set_number(&global_options, "set-titles", 0);
options_set_number(&global_options, "status", 1);
options_set_number(&global_options, "status-attr", GRID_ATTR_REVERSE);
options_set_number(&global_options, "status-bg", 2);
options_set_number(&global_options, "status-fg", 0);
options_set_number(&global_options, "status-attr", GRID_ATTR_REVERSE);
options_set_number(&global_options, "status-interval", 15);
options_set_number(&global_options, "status-keys", MODEKEY_EMACS);
options_set_number(&global_options, "status-left-length", 10);
options_set_number(&global_options, "status-right-length", 40);
options_set_string(&global_options, "status-left", "[#S]");
options_set_string(
&global_options, "status-right", "\"#24T\" %%H:%%M %%d-%%b-%%y");
options_set_number(&global_options, "status-keys", MODEKEY_EMACS);
options_set_number(&global_options, "status-utf8", 0);
options_init(&global_window_options, NULL);
options_set_number(&global_window_options, "aggressive-resize", 0);
options_set_number(&global_window_options, "automatic-rename", 1);
options_set_number(&global_window_options, "clock-mode-colour", 4);
options_set_number(&global_window_options, "clock-mode-style", 1);
options_set_number(&global_window_options, "force-height", 0);
options_set_number(&global_window_options, "force-width", 0);
options_set_number(&global_window_options, "automatic-rename", 1);
options_set_number(&global_window_options, "mode-bg", 3);
options_set_number(&global_window_options, "mode-fg", 0);
options_set_number(
&global_window_options, "mode-attr", GRID_ATTR_REVERSE);
options_set_number(&global_window_options, "main-pane-width", 81);
options_set_number(&global_window_options, "main-pane-height", 24);
options_set_number(&global_window_options, "mode-bg", 3);
options_set_number(&global_window_options, "mode-fg", 0);
options_set_number(&global_window_options, "mode-keys", MODEKEY_EMACS);
options_set_number(&global_window_options, "monitor-activity", 0);
options_set_string(&global_window_options, "monitor-content", "%s", "");
options_set_number(&global_window_options, "utf8", 0);
options_set_number(&global_window_options, "xterm-keys", 0);
options_set_number(&global_window_options, "remain-on-exit", 0);
options_set_number(&global_window_options, "window-status-attr", 0);
options_set_number(&global_window_options, "window-status-bg", 8);
options_set_number(&global_window_options, "window-status-fg", 8);
options_set_number(&global_window_options, "window-status-attr", 0);
options_set_number(&global_window_options, "xterm-keys", 0);
options_set_number(&global_window_options, "remain-on-exit", 0);
if (!(flags & IDENTIFY_UTF8)) {
/*
* If the user has set whichever of LC_ALL, LC_CTYPE or LANG
* exist (in that order) to contain UTF-8, it is a safe
* assumption that either they are using a UTF-8 terminal, or
* if not they know that output from UTF-8-capable programs may
* be wrong.
*/
if ((s = getenv("LC_ALL")) == NULL) {
if ((s = getenv("LC_CTYPE")) == NULL)
s = getenv("LANG");
}
if (s != NULL && strcasestr(s, "UTF-8") != NULL)
flags |= IDENTIFY_UTF8;
}
if (cfg_file == NULL) {
home = getenv("HOME");
@@ -330,7 +347,6 @@ main(int argc, char **argv)
pw = getpwuid(getuid());
if (pw != NULL)
home = pw->pw_dir;
endpwent();
}
xasprintf(&cfg_file, "%s/%s", home, DEFAULT_CFG);
if (access(cfg_file, R_OK) != 0) {
@@ -352,22 +368,12 @@ main(int argc, char **argv)
}
xfree(label);
shell = getenv("SHELL");
if (shell == NULL || *shell == '\0') {
pw = getpwuid(getuid());
if (pw != NULL)
shell = pw->pw_shell;
endpwent();
if (shell == NULL || *shell == '\0')
shell = _PATH_BSHELL;
}
options_set_string(
&global_options, "default-command", "exec %s", shell);
if (getcwd(cwd, sizeof cwd) == NULL) {
log_warn("getcwd");
exit(1);
pw = getpwuid(getuid());
if (pw->pw_dir != NULL && *pw->pw_dir != '\0')
strlcpy(cwd, pw->pw_dir, sizeof cwd);
else
strlcpy(cwd, "/", sizeof cwd);
}
options_set_string(&global_options, "default-path", "%s", cwd);
@@ -404,7 +410,7 @@ main(int argc, char **argv)
}
}
}
memset(&cctx, 0, sizeof cctx);
if (client_init(path, &cctx, start_server, flags) != 0)
exit(1);
@@ -413,6 +419,7 @@ main(int argc, char **argv)
b = buffer_create(BUFSIZ);
if (unlock) {
cmd_send_string(b, pass);
memset(pass, 0, strlen(pass));
client_write_server(
&cctx, MSG_UNLOCK, BUFFER_OUT(b), BUFFER_USED(b));
} else {
@@ -479,8 +486,5 @@ out:
buffer_destroy(cctx.srv_in);
buffer_destroy(cctx.srv_out);
#ifdef DEBUG
xmalloc_report(getpid(), "client");
#endif
return (retcode);
}

270
tmux.h
View File

@@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.299 2009-04-03 17:21:46 nicm Exp $ */
/* $Id: tmux.h,v 1.349 2009-07-02 18:17:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,39 +19,13 @@
#ifndef TMUX_H
#define TMUX_H
#define PROTOCOL_VERSION -12
#include "config.h"
/* Shut up gcc warnings about empty if bodies. */
#define RB_AUGMENT(x) do {} while (0)
#define PROTOCOL_VERSION -13
#include <sys/param.h>
#include <sys/time.h>
#ifndef NO_QUEUE_H
#include <sys/queue.h>
#else
#include "compat/queue.h"
#endif
#ifndef NO_TREE_H
#include <sys/tree.h>
#else
#include "compat/tree.h"
#endif
#ifndef BROKEN_POLL
#include <poll.h>
#else
#undef HAVE_POLL
#include "compat/bsd-poll.h"
#endif
#ifndef BROKEN_GETOPT
#include <getopt.h>
#else
#include "compat/getopt.h"
#endif
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
@@ -61,57 +35,10 @@
#include "array.h"
#include "compat.h"
extern const char *__progname;
#ifndef INFTIM
#define INFTIM -1
#endif
#ifndef WAIT_ANY
#define WAIT_ANY -1
#endif
#ifndef SUN_LEN
#define SUN_LEN(sun) (sizeof (sun)->sun_path)
#endif
#ifndef __dead
#define __dead __attribute__ ((__noreturn__))
#endif
#ifndef __packed
#define __packed __attribute__ ((__packed__))
#endif
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#ifndef timeradd
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#endif
#ifndef TTY_NAME_MAX
#define TTY_NAME_MAX 32
#endif
#ifdef NO_PATHS_H
#define _PATH_BSHELL "/bin/sh"
#define _PATH_TMP "/tmp/"
#define _PATH_DEVNULL "/dev/null"
#define _PATH_TTY "/dev/tty"
#endif
/* Default configuration file. */
#define DEFAULT_CFG ".tmux.conf"
@@ -127,6 +54,9 @@ extern const char *__progname;
/* Escape timer period, in milliseconds. */
#define ESCAPE_PERIOD 250
/* Maximum poll timeout (when attached). */
#define POLL_TIMEOUT 50
/* Fatal errors. */
#define fatal(msg) log_fatal("%s: %s", __func__, msg);
#define fatalx(msg) log_fatalx("%s: %s", __func__, msg);
@@ -139,9 +69,12 @@ extern const char *__progname;
#define printflike2 __attribute__ ((format (printf, 2, 3)))
#define printflike3 __attribute__ ((format (printf, 3, 4)))
#define printflike4 __attribute__ ((format (printf, 4, 5)))
#define printflike5 __attribute__ ((format (printf, 5, 6)))
/* Number of items in array. */
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
/* Buffer macros. */
#define BUFFER_USED(b) ((b)->size)
@@ -317,8 +250,9 @@ enum tty_code_code {
TTYC_SMKX, /* keypad_xmit, ks */
TTYC_SMSO, /* enter_standout_mode, so */
TTYC_SMUL, /* enter_underline_mode, us */
TTYC_XENL, /* eat_newline_glitch, xn */
};
#define NTTYCODE (TTYC_SMUL + 1)
#define NTTYCODE (TTYC_XENL + 1)
/* Termcap types. */
enum tty_code_type {
@@ -347,7 +281,8 @@ struct tty_term_code_entry {
/* Output commands. */
enum tty_cmd {
TTY_CELL,
TTY_ALIGNMENTTEST,
TTY_CELL,
TTY_CLEARENDOFLINE,
TTY_CLEARENDOFSCREEN,
TTY_CLEARLINE,
@@ -419,7 +354,7 @@ struct msg_resize_data {
/* Editing keys. */
enum mode_key_cmd {
MODEKEYCMD_BACKSPACE,
MODEKEYCMD_BACKSPACE = 0x1000,
MODEKEYCMD_CHOOSE,
MODEKEYCMD_CLEARSELECTION,
MODEKEYCMD_COMPLETE,
@@ -432,6 +367,7 @@ enum mode_key_cmd {
MODEKEYCMD_NEXTWORD,
MODEKEYCMD_NONE,
MODEKEYCMD_OTHERKEY,
MODEKEYCMD_PASTE,
MODEKEYCMD_PREVIOUSPAGE,
MODEKEYCMD_PREVIOUSWORD,
MODEKEYCMD_QUIT,
@@ -441,7 +377,7 @@ enum mode_key_cmd {
MODEKEYCMD_UP,
};
struct mode_key_data {
struct mode_key_data {
int type;
int flags;
@@ -461,7 +397,9 @@ struct mode_key_data {
#define MODE_MOUSE 0x10
/* Grid output. */
#ifdef DEBUG
#if defined(DEBUG) && \
((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
(defined(__GNUC__) && __GNUC__ >= 3))
#define GRID_DEBUG(gd, fmt, ...) log_debug3("%s: (sx=%u, sy=%u, hsize=%u) " \
fmt, __func__, (gd)->sx, (gd)->sy, (gd)->hsize, ## __VA_ARGS__)
#else
@@ -571,6 +509,8 @@ struct screen {
int mode;
bitstr_t *tabs;
struct screen_sel sel;
};
@@ -602,7 +542,7 @@ struct input_ctx {
size_t off;
struct grid_cell cell;
struct grid_cell saved_cell;
u_int saved_cx;
@@ -655,9 +595,8 @@ struct window_pane {
int flags;
#define PANE_HIDDEN 0x1
#define PANE_RESTART 0x2
#define PANE_REDRAW 0x4
#define PANE_REDRAW 0x2
char *cmd;
char *cwd;
@@ -684,17 +623,18 @@ struct window {
char *name;
struct timeval name_timer;
struct window_pane *active;
struct window_pane *active;
struct window_panes panes;
u_int layout;
u_int sx;
u_int sy;
int flags;
#define WINDOW_BELL 0x1
#define WINDOW_HIDDEN 0x2
#define WINDOW_ACTIVITY 0x4
#define WINDOW_CONTENT 0x6
#define WINDOW_REDRAW 0x8
struct options options;
@@ -854,9 +794,14 @@ struct client {
size_t prompt_index;
int (*prompt_callback)(void *, const char *);
void *prompt_data;
int prompt_hidden;
#define PROMPT_HIDDEN 0x1
#define PROMPT_SINGLE 0x2
int prompt_flags;
u_int prompt_hindex;
ARRAY_DECL(, char *) prompt_hdata;
struct mode_key_data prompt_mdata;
struct session *session;
@@ -905,13 +850,13 @@ struct cmd_entry {
#define CMD_CANTNEST 0x2
#define CMD_ARG1 0x4
#define CMD_ARG01 0x8
#define CMD_KFLAG 0x10
#define CMD_AFLAG 0x10
#define CMD_DFLAG 0x20
#define CMD_GFLAG 0x40
#define CMD_UFLAG 0x80
#define CMD_AFLAG 0x100
#define CMD_UPPERUFLAG 0x200
#define CMD_UPPERDFLAG 0x400
#define CMD_KFLAG 0x80
#define CMD_UFLAG 0x100
#define CMD_BIGDFLAG 0x200
#define CMD_BIGUFLAG 0x400
int flags;
@@ -989,50 +934,16 @@ struct set_option_entry {
};
extern const struct set_option_entry set_option_table[];
extern const struct set_option_entry set_window_option_table[];
#define NSETOPTION 24
#define NSETWINDOWOPTION 17
#ifdef NO_STRTONUM
/* strtonum.c */
long long strtonum(const char *, long long, long long, const char **);
#endif
#ifdef NO_STRLCPY
/* strlcpy.c */
size_t strlcpy(char *, const char *, size_t);
#endif
#ifdef NO_STRLCAT
/* strlcat.c */
size_t strlcat(char *, const char *, size_t);
#endif
#ifdef NO_DAEMON
/* daemon.c */
int daemon(int, int);
#endif
#ifdef NO_FORKPTY
/* forkpty.c */
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
#ifdef NO_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifdef NO_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
#endif
#define NSETOPTION 25
#define NSETWINDOWOPTION 19
/* tmux.c */
extern volatile sig_atomic_t sigwinch;
extern volatile sig_atomic_t sigterm;
extern volatile sig_atomic_t sigcont;
extern volatile sig_atomic_t sigchld;
extern volatile sig_atomic_t sigusr1;
extern volatile sig_atomic_t sigusr2;
extern struct options global_options;
extern struct options global_window_options;
extern char *cfg_file;
@@ -1071,6 +982,7 @@ void options_set_number(struct options *, const char *, long long);
long long options_get_number(struct options *, const char *);
/* tty.c */
u_char tty_get_acs(struct tty *, u_char);
void tty_emulate_repeat(struct tty *,
enum tty_code_code, enum tty_code_code, u_int);
void tty_reset(struct tty *);
@@ -1082,10 +994,12 @@ void tty_putcode(struct tty *, enum tty_code_code);
void tty_putcode1(struct tty *, enum tty_code_code, int);
void tty_putcode2(struct tty *, enum tty_code_code, int, int);
void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, char);
void tty_putc(struct tty *, u_char);
void tty_pututf8(struct tty *, const struct grid_utf8 *);
void tty_init(struct tty *, char *, char *);
void tty_start_tty(struct tty *);
void tty_stop_tty(struct tty *);
void tty_detect_utf8(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int);
void tty_draw_line(
@@ -1094,8 +1008,6 @@ void tty_redraw_region(struct tty *, struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *, int);
void tty_free(struct tty *, int);
void tty_write(
struct tty *, struct window_pane *, enum tty_cmd, ...);
void tty_vwrite(
struct tty *, struct window_pane *, enum tty_cmd, va_list);
@@ -1121,7 +1033,6 @@ int tty_keys_next(struct tty *, int *, u_char *);
/* tty-write.c */
void tty_write_cmd(struct window_pane *, enum tty_cmd, ...);
void tty_write_mode(struct window_pane *, int);
/* options-cmd.c */
void set_option_string(struct cmd_ctx *,
@@ -1178,8 +1089,10 @@ extern const struct cmd_entry cmd_bind_key_entry;
extern const struct cmd_entry cmd_break_pane_entry;
extern const struct cmd_entry cmd_choose_session_entry;
extern const struct cmd_entry cmd_choose_window_entry;
extern const struct cmd_entry cmd_clear_history_entry;
extern const struct cmd_entry cmd_clock_mode_entry;
extern const struct cmd_entry cmd_command_prompt_entry;
extern const struct cmd_entry cmd_confirm_before_entry;
extern const struct cmd_entry cmd_copy_buffer_entry;
extern const struct cmd_entry cmd_copy_mode_entry;
extern const struct cmd_entry cmd_delete_buffer_entry;
@@ -1207,16 +1120,17 @@ extern const struct cmd_entry cmd_new_window_entry;
extern const struct cmd_entry cmd_next_layout_entry;
extern const struct cmd_entry cmd_next_window_entry;
extern const struct cmd_entry cmd_paste_buffer_entry;
extern const struct cmd_entry cmd_previous_layout_entry;
extern const struct cmd_entry cmd_previous_window_entry;
extern const struct cmd_entry cmd_refresh_client_entry;
extern const struct cmd_entry cmd_rename_session_entry;
extern const struct cmd_entry cmd_rename_window_entry;
extern const struct cmd_entry cmd_resize_pane_down_entry;
extern const struct cmd_entry cmd_resize_pane_up_entry;
extern const struct cmd_entry cmd_resize_pane_entry;
extern const struct cmd_entry cmd_respawn_window_entry;
extern const struct cmd_entry cmd_rotate_window_entry;
extern const struct cmd_entry cmd_save_buffer_entry;
extern const struct cmd_entry cmd_scroll_mode_entry;
extern const struct cmd_entry cmd_select_layout_entry;
extern const struct cmd_entry cmd_select_pane_entry;
extern const struct cmd_entry cmd_select_prompt_entry;
extern const struct cmd_entry cmd_select_window_entry;
@@ -1302,7 +1216,6 @@ size_t cmd_pane_print(struct cmd *, char *, size_t);
/* client.c */
int client_init(char *, struct client_ctx *, int, int);
int client_flush(struct client_ctx *);
int client_main(struct client_ctx *);
/* client-msg.c */
@@ -1347,8 +1260,6 @@ void server_write_client(
struct client *, enum hdrtype, const void *, size_t);
void server_write_session(
struct session *, enum hdrtype, const void *, size_t);
void server_write_window(
struct window *, enum hdrtype, const void *, size_t);
void server_redraw_client(struct client *);
void server_status_client(struct client *);
void server_redraw_session(struct session *);
@@ -1409,8 +1320,8 @@ void grid_set_utf8(struct grid *, u_int, u_int, const struct grid_utf8 *);
void grid_clear(struct grid *, u_int, u_int, u_int, u_int);
void grid_clear_lines(struct grid *, u_int, u_int);
void grid_move_lines(struct grid *, u_int, u_int, u_int);
void grid_clear_cells(struct grid *, u_int, u_int, u_int);
void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int);
char *grid_string_cells(struct grid *, u_int, u_int, u_int);
/* grid-view.c */
const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int);
@@ -1432,13 +1343,19 @@ void grid_view_delete_lines_region(
struct grid *, u_int, u_int, u_int, u_int);
void grid_view_insert_cells(struct grid *, u_int, u_int, u_int);
void grid_view_delete_cells(struct grid *, u_int, u_int, u_int);
char *grid_view_string_cells(struct grid *, u_int, u_int, u_int);
/* screen-write.c */
void screen_write_start(
struct screen_write_ctx *, struct window_pane *, struct screen *);
void screen_write_stop(struct screen_write_ctx *);
void printflike3 screen_write_puts(
struct screen_write_ctx *, struct grid_cell *, const char *, ...);
size_t printflike2 screen_write_strlen(int, const char *, ...);
void printflike3 screen_write_puts(struct screen_write_ctx *,
struct grid_cell *, const char *, ...);
void printflike5 screen_write_nputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, int, const char *, ...);
void screen_write_vnputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, int, const char *, va_list);
void screen_write_putc(
struct screen_write_ctx *, struct grid_cell *, u_char);
void screen_write_copy(struct screen_write_ctx *,
@@ -1447,6 +1364,7 @@ void screen_write_cursorup(struct screen_write_ctx *, u_int);
void screen_write_cursordown(struct screen_write_ctx *, u_int);
void screen_write_cursorright(struct screen_write_ctx *, u_int);
void screen_write_cursorleft(struct screen_write_ctx *, u_int);
void screen_write_alignmenttest(struct screen_write_ctx *);
void screen_write_insertcharacter(struct screen_write_ctx *, u_int);
void screen_write_deletecharacter(struct screen_write_ctx *, u_int);
void screen_write_insertline(struct screen_write_ctx *, u_int);
@@ -1479,17 +1397,17 @@ void screen_redraw_status(struct client *);
void screen_init(struct screen *, u_int, u_int, u_int);
void screen_reinit(struct screen *);
void screen_free(struct screen *);
void screen_reset_tabs(struct screen *);
void screen_set_title(struct screen *, const char *);
void screen_resize(struct screen *, u_int, u_int);
void screen_set_selection(
struct screen *, u_int, u_int, u_int, u_int, struct grid_cell *);
void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);
void screen_display_copy_area(struct screen *, struct screen *,
u_int, u_int, u_int, u_int, u_int, u_int);
/* window.c */
extern struct windows windows;
const char *window_default_command(void);
int window_cmp(struct window *, struct window *);
int winlink_cmp(struct winlink *, struct winlink *);
RB_PROTOTYPE(windows, window, entry, window_cmp);
@@ -1514,10 +1432,7 @@ void window_set_active_pane(struct window *, struct window_pane *);
struct window_pane *window_add_pane(struct window *, int,
const char *, const char *, const char **, u_int, char **);
void window_remove_pane(struct window *, struct window_pane *);
u_int window_index_of_pane(struct window *, struct window_pane *);
struct window_pane *window_pane_at_index(struct window *, u_int);
void window_fit_panes(struct window *);
void window_update_panes(struct window *);
u_int window_count_panes(struct window *);
void window_destroy_panes(struct window *);
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
@@ -1525,7 +1440,6 @@ void window_pane_destroy(struct window_pane *);
int window_pane_spawn(struct window_pane *,
const char *, const char *, const char **, char **);
int window_pane_resize(struct window_pane *, u_int, u_int);
void window_calculate_sizes(struct window *);
int window_pane_set_mode(
struct window_pane *, const struct window_mode *);
void window_pane_reset_mode(struct window_pane *);
@@ -1533,10 +1447,21 @@ void window_pane_parse(struct window_pane *);
void window_pane_key(struct window_pane *, struct client *, int);
void window_pane_mouse(struct window_pane *,
struct client *, u_char, u_char, u_char);
char *window_pane_search(
struct window_pane *, const char *, u_int *);
/* layout.c */
const char * layout_name(struct window *);
int layout_lookup(const char *);
void layout_refresh(struct window *, int);
int layout_resize(struct window_pane *, int);
int layout_select(struct window *, u_int);
void layout_next(struct window *);
void layout_previous(struct window *);
/* layout-manual.c */
void layout_manual_v_refresh(struct window *, int);
void layout_manual_v_resize(struct window_pane *, int);
/* window-clock.c */
extern const struct window_mode window_clock_mode;
@@ -1552,7 +1477,6 @@ void window_scroll_pageup(struct window_pane *);
/* window-more.c */
extern const struct window_mode window_more_mode;
void window_more_vadd(struct window_pane *, const char *, va_list);
void printflike2 window_more_add(struct window_pane *, const char *, ...);
/* window-choose.c */
extern const struct window_mode window_choose_mode;
@@ -1578,7 +1502,7 @@ struct session *session_create(const char *, const char *,
const char *, u_int, u_int, char **);
void session_destroy(struct session *);
int session_index(struct session *, u_int *);
struct winlink *session_new(struct session *,
struct winlink *session_new(struct session *,
const char *, const char *, const char *, int, char **);
struct winlink *session_attach(
struct session *, struct window *, int, char **);
@@ -1590,12 +1514,8 @@ int session_select(struct session *, int);
int session_last(struct session *);
/* utf8.c */
u_int utf8_combine(const u_char *);
void utf8_split(u_int, u_char *);
int utf8_width(u_int);
/* util.c */
char *section_string(char *, size_t, size_t, size_t);
void utf8_build(void);
int utf8_width(const u_char *);
/* osdep-*.c */
char *osdep_get_name(int, char *);
@@ -1603,42 +1523,27 @@ char *osdep_get_name(int, char *);
/* buffer.c */
struct buffer *buffer_create(size_t);
void buffer_destroy(struct buffer *);
void buffer_clear(struct buffer *);
void buffer_ensure(struct buffer *, size_t);
void buffer_add(struct buffer *, size_t);
void buffer_reverse_add(struct buffer *, size_t);
void buffer_remove(struct buffer *, size_t);
void buffer_reverse_remove(struct buffer *, size_t);
void buffer_insert_range(struct buffer *, size_t, size_t);
void buffer_delete_range(struct buffer *, size_t, size_t);
void buffer_write(struct buffer *, const void *, size_t);
void buffer_read(struct buffer *, void *, size_t);
void buffer_write8(struct buffer *, uint8_t);
void buffer_write16(struct buffer *, uint16_t);
uint8_t buffer_read8(struct buffer *);
uint16_t buffer_read16(struct buffer *);
/* buffer-poll.c */
void buffer_set(
struct pollfd *, int, struct buffer *, struct buffer *);
int buffer_poll(struct pollfd *, struct buffer *, struct buffer *);
void buffer_flush(int, struct buffer *n, struct buffer *);
/* log.c */
#define LOG_FACILITY LOG_DAEMON
void log_open_syslog(int);
void log_open_tty(int);
void log_open_file(int, const char *);
void log_close(void);
void log_vwrite(int, const char *, va_list);
void log_write(int, const char *, ...);
void printflike1 log_warn(const char *, ...);
void printflike1 log_warnx(const char *, ...);
void printflike1 log_info(const char *, ...);
void printflike1 log_debug(const char *, ...);
void printflike1 log_debug2(const char *, ...);
void printflike1 log_debug3(const char *, ...);
__dead void log_vfatal(const char *, va_list);
__dead void log_fatal(const char *, ...);
__dead void log_fatalx(const char *, ...);
@@ -1652,20 +1557,5 @@ int printflike2 xasprintf(char **, const char *, ...);
int xvasprintf(char **, const char *, va_list);
int printflike3 xsnprintf(char *, size_t, const char *, ...);
int xvsnprintf(char *, size_t, const char *, va_list);
int printflike3 printpath(char *, size_t, const char *, ...);
char *xdirname(const char *);
char *xbasename(const char *);
/* xmalloc-debug.c */
#ifdef DEBUG
#define xmalloc_caller() __builtin_return_address(0)
void xmalloc_clear(void);
void xmalloc_report(pid_t, const char *);
void xmalloc_new(void *, void *, size_t);
void xmalloc_change(void *, void *, void *, size_t);
void xmalloc_free(void *);
#endif
#endif
#endif /* TMUX_H */

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