456 Commits
1.0 ... 1.2

Author SHA1 Message Date
no_author
cd1ae9e79b This commit was manufactured by cvs2svn to create tag 'TMUX_1_2'. 2010-03-10 15:18:50 +00:00
Tiago Cunha
95c6d9d31d Done. 2010-03-10 15:18:49 +00:00
Tiago Cunha
3d85d2be6a Update CHANGES, and NOTES for the 1.2 release. 2010-03-10 15:18:11 +00:00
Tiago Cunha
6681db7af0 Bump VERSION. 2010-03-10 15:16:19 +00:00
Tiago Cunha
b90e869b8b Prepare the tree for the 1.2 release. 2010-03-10 15:15:33 +00:00
Nicholas Marriott
de64913786 Plug memory leak, from Gregory Thiemonge. 2010-03-10 13:41:13 +00:00
Tiago Cunha
b34c8f5f39 Sync OpenBSD patchset 658:
Permit keys in copy mode to be prefixed by a repeat count, entered with
[1-9] in vi mode, or M-[1-9] in emacs mode.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        pipe-pane 'cat >~/out'

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

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

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

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

This brings several advantages:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

set -g prefix ^a,^b

Any key in the list acts as the prefix. The send-prefix command always sends
the first key in the list.
2009-09-22 14:22:21 +00:00
Tiago Cunha
31ccf2f813 Sync OpenBSD patchset 342:
Use KEYC_NONE constant instead of 0 on init.
2009-09-22 14:06:40 +00:00
Tiago Cunha
480211f0ee Sync OpenBSD patchset 341:
Nuke -i option which isn't used anymore.
2009-09-22 14:03:11 +00:00
Tiago Cunha
59e65cbda2 Sync OpenBSD patchset 340:
Use option print function for info messages as well.
2009-09-22 13:59:46 +00:00
Tiago Cunha
649b7c132d Sync OpenBSD patchset 339:
Move common code from show-options and show-window-options into a function.
2009-09-22 13:56:02 +00:00
Tiago Cunha
b6bc8a6828 Sync OpenBSD patchset 338:
zap trailing whitespace;
2009-09-22 13:51:24 +00:00
Tiago Cunha
f2d249fdc7 Sync OpenBSD patchset 337:
Drop tiny union from option struct.
2009-09-22 13:49:13 +00:00
Tiago Cunha
c28d4e41cf Sync OpenBSD patchset 336:
Key options were implemented as a number so these struct members are unused.
2009-09-22 13:45:06 +00:00
Nicholas Marriott
1572e483c2 Done. 2009-09-22 11:40:11 +00:00
Tiago Cunha
f8ea4f44e8 Update. 2009-09-20 22:20:51 +00:00
Tiago Cunha
e3dcc5327a Sync OpenBSD patchset 335:
run-shell command to run a shell command without opening a window, sending
stdout to output mode.
2009-09-20 22:20:10 +00:00
Tiago Cunha
bd24bdd411 Sync OpenBSD patchset 334:
Nuke unused variables and fix stupid error message.
2009-09-20 22:17:03 +00:00
Tiago Cunha
7335ef5792 Sync OpenBSD patchset 333:
Move some common and untidy code for window link/unlink into generic functions
instead of duplicating it in move/link window..
2009-09-20 22:15:32 +00:00
Tiago Cunha
3266fb5441 Sync OpenBSD patchset 332:
Regularise some fatal messages.
2009-09-20 22:11:27 +00:00
Tiago Cunha
ab96772436 Delete backup files in the compat directory, as well. 2009-09-20 22:06:34 +00:00
Nicholas Marriott
c7ace08193 Now working on 1.1. 2009-09-20 19:01:01 +00:00
166 changed files with 10664 additions and 6851 deletions

111
CHANGES
View File

@@ -1,3 +1,112 @@
CHANGES FROM 1.1 TO 1.2, 10 March 2010
* Switch to libevent.
* Emulate the ri (reverse index) capability, ergo allowing tmux to at least
start on Sun consoles (TERM=sun, or sun-color).
* Assign each entry a number, or lowercase letter in choose mode, and accept
that as a shortcut key.
* Permit top-bit-set characters to be entered in the status line.
* Mark no-prefix keys with (no prefix), rather than [] in list-keys.
* New command show-messages (alias showmsgs), and new session option
message-limit, to show a per-client log of status lines messages up to the
number defined by message-limit.
* Do not interpret #() for display-message to avoid leaking commands.
* New window options window-status-format, and window-status-current-format to
control the format of each window in the status line.
* Add a -p flag to display-message to print the output, instead of displaying
it in the status line.
* Emulate il1, dl1, ich1 to run with vt100 feature set.
* New command capture-pane (alias capturep) to copy the entire pane contents
to a paste buffer.
* Avoid duplicating code by adding a -w flag to set-option, and show-options to
set, and show window options. The commands set-window-option, and
show-window-options are now aliases.
* Panes can now be referred to as top, bottom, top-left, etc.
* Add server-wide options, which can be set with set-option -s, and shown with
show-options -s.
* New server option quiet (like -q from the command line).
* New server option escape-time to set the timeout used to detect if escapes
are alone, part of a function key, or meta sequence.
* New session options pane-active-border-bg, pane-active-border-fg,
pane-border-bg, and pane-border-fg to set pane colours.
* Make split-window accept a pane target, instead of a window.
* New command join-pane (alias joinp) to split, and move an existing pane into
the space (the opposite of break-pane), thus simplifying calls to
split-window, followed by move-window.
* Permit S- prefix on keys for shift when the terminal/terminfo supports them.
* Window targets (-t flag) can now refer to the last window (!), next (+), and
previous (-) window by number.
* Mode keys to jump to the bottom/top of history, end of the next word, scroll
up/down, and reverse search in copy mode.
* New session option display-panes-active-colour to display the active pane in
a different colour with the display-panes command.
* Read the socket path from $TMUX if it's present, and -L, and -S are not
given.
* Vi-style mode keys B, W, and E to navigate between words in copy mode.
* Start in more mode when configuration file errors are detected.
* Rectangle copy support added.
* If attach-session was specified with the -r flag, make the client read-only.
* Per-window alternate-screen option.
* Make load-buffer work with FIFOs.
* New window option word-separators to set the characters considered as word
separators in copy mode.
* Permit keys in copy mode to be prefixed by a repeat count, entered with [1-9]
in vi mode, or M-[1-9] in emacs mode.
* utf8 improvements.
* As usual, additional code reduction, bug fixes, and manpage enhancements.
CHANGES FROM 1.0 TO 1.1, 05 November 2009
* New run-shell (alias run) command to run an external command without a
window, capture it's stdout, and send it to output mode.
* Ability to define multiple prefix keys.
* Internal locking mechanism removed. Instead, detach each client and run the
external command specified in the new session option lock-command (by default
lock -np), thus allowing the system password to be used.
* set-password command, and -U command line flag removed per the above change.
* Add support for -c command line flag to execute a shell command.
* New lock-client (alias lockc), and lock-session (alias locks) commands to
lock a particular client, or all clients attached to a session.
* Support C-n/C-p/C-v/M-v with emacs keys in choice mode.
* Use : for goto line rather than g in vi mode.
* Try to guess which client to use when no target client was specified. Finds
the current session, and if only one client is present, use it. Otherwise,
return the most recently used client.
* Make C-Down/C-Up in copy mode scroll the screen down/up one line without
moving the cursor.
* Scroll mode superseded by copy mode.
* New synchronize-panes window option to send all input to all other panes in
the same window.
* New lock-server session option to lock, when off (on by default), each
session when it has been idle for the lock-after-time setting. When on, the
entire server locks when all sessions have been idle for their individual
lock-after-time setting.
* Add support for grouped sessions which have independent name, options,
current window, but where the linked windows are synchronized (ie creating,
killing windows are mirrored between the sessions). A grouped session may be
created by passing -t to new-session.
* New mouse-select-pane session option to select the current pane with the
mouse.
* Queue, and run commands in the background for if-shell, status-left,
status-right, and #() by starting each once every status-interval. Adds the
capability to call some programs which would previously cause the server to
hang (eg sleep/tmux). It also avoids running commands excessively (ie if used
multiple times, it will be run only once).
* When a window is zombified and automatic-rename is on, append [dead] to the
name.
* Split list-panes (alias lsp) off from list-windows.
* New pipe-pane (alias pipep) to redirect a pane output to an external command.
* Support for automatic-renames for Solaris.
* Permit attributes to be turned off in #[] by prefixing with no (eg nobright).
* Add H/M/L in vi mode, and M-R/M-r in emacs to move the cursor to the top,
middle, and bottom of the screen.
* -a option added to kill-pane to kill all except current pane.
* The -d command line flag is now gone (can be replaced by terminal-overrides).
Just use op/AX to detect default colours.
* input/tty/utf8 improvements.
* xterm-keys rewrite.
* Additional code reduction, and bug fixes.
CHANGES FROM 0.9 TO 1.0, 20 Sept 2009
* Option to alter the format of the window title set by tmux.
@@ -1358,7 +1467,7 @@ The list of older changes is below.
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
$Id: CHANGES,v 1.300 2009-09-20 18:54:21 nicm Exp $
$Id: CHANGES,v 1.302 2010-03-10 15:18:11 tcunha Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms

58
FAQ
View File

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

View File

@@ -1,16 +1,37 @@
# $Id: GNUmakefile,v 1.114 2009-09-20 18:54:21 nicm Exp $
# $Id: GNUmakefile,v 1.122 2010-03-10 15:15:33 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
.PHONY: clean
VERSION= 1.0
VERSION= 1.2
#FDEBUG= 1
CC?= gcc
CC?= cc
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+=
# Sun CC
ifneq ($(shell ($(CC) -V 2>&1|awk '/Sun C/' || true)), )
CFLAGS+=-erroff=E_EMPTY_DECLARATION
FDEBUG=
endif
ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
@@ -48,7 +69,7 @@ depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
clean:
rm -f tmux *.o *~ *.core *.log compat/*.o
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
clean-depend:
rm -f .depend

View File

@@ -1,9 +1,24 @@
# $Id: Makefile,v 1.149 2009-09-20 18:54:21 nicm Exp $
# $Id: Makefile,v 1.155 2010-03-10 15:15:33 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
.SUFFIXES: .c .o
.PHONY: clean
VERSION= 1.0
VERSION= 1.2
#FDEBUG= 1
@@ -53,7 +68,7 @@ depend:
mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
clean:
rm -f tmux *.o *~ *.core *.log compat/*.o
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
clean-depend:
rm -f .depend

29
NOTES
View File

@@ -4,15 +4,15 @@ tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen.
This 0.9 release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they hasn't been tested in a while). It is
This release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they haven't been tested in a while). It is
usable, although there remain a number of missing features and some remaining
bugs are expected.
If upgrading from 0.5, PLEASE NOTE the following configuration file changes: it
is now required to pass the -g flag to set-option or set-window-option to set
global options; remain-by-default and utf8-default are now gone, use global
window options (set-window-option -g) instead.
Since the 1.2 release that tmux depends on libevent. Download the stable
version from:
http://www.monkey.org/~provos/libevent/
tmux consists of a server part and multiple clients. The server is created when
required and runs continuously unless killed by the user. Clients access the
@@ -37,22 +37,19 @@ The following is a summary of major features implemented in this version:
- Support for VT100 line drawing characters.
- A large command set.
- Vertical window splitting and layout.
- Automatic server locking on inactivity.
- Automatic server locking on inactivity by running an external command.
- A configuration file.
- UTF-8 support.
A more extensive, but rough, todo list is included in the TODO file.
tmux also depends on several features of the client terminal (TERM), if these
are missing it may refuse to run, or not behave correctly. Known working are
TERM=screen (tmux in screen), xterm, xterm-color and rxvt. Note that TERM=xterm
does not support colour on OpenBSD. screen ignores this, tmux does not: use
xterm-color or rxvt for colour.
are missing it may refuse to run, or not behave correctly.
tmux supports UTF-8. To use it, the utf8 option must be set on each window;
this may be turned on for all windows by setting it as a global option, see
tmux(1) and the FAQ file. As of 0.9, tmux attempts to autodetect a
UTF-8-capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment
UTF-8 capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment
variables. list-clients may be used to check if this is detected correctly; if
not, the -u command-line flag may be specified.
@@ -81,6 +78,12 @@ welcome. Please send by email to:
nicm@users.sf.net
This file and the CHANGES, FAQ and TODO files are licensed under the ISC
license. Files under examples/ remain copyright their authors unless otherwise
stated in the file but permission has been received to distribute them with
tmux. All other files have a license and copyright notice at their
start. Please contact me with any queries.
-- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.49 2009-07-06 18:53:24 nicm Exp $
$Id: NOTES,v 1.53 2010-03-10 15:18:11 tcunha Exp $

111
TODO
View File

@@ -9,98 +9,127 @@
- 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?
- better mode features: search
- flags to centre screen in window
- better terminal emulation
- activity/bell should be per-window not per-link? what if it is cur win in
session not being watched?
- next prev word etc in command prompt; also ^K
- next prev word etc in command prompt
- many more info() displays for various things
- backspace should perhaps wrap backwards over newlines which were not moved
down by a newline: screen and the OS X terminal does this but xterm and most
others do not. this might be hard: a flag for each grid line (top bit of size
maybe)? a single flag is insufficient as can't then tell when to /stop/
unwrapping
- input.c is too complicated. simplify?
- use a better termcap internally instead of screen, perhaps xterm
- kill all but current pane
- fix rxvt cursor fg issue (text under cursor can have non-white fg)
- 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
- support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically?
- set-option should be set-session-option and should be overall global options
for stuff like mode keys?
also quiet, utf8 and maybe other flags?
-g is a bit unexpected in conf file
- clear window title on exit
- the output code (tty.c) could do with optimisation depending on term
capibilities
capabilities
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- goto line and search history in copy/scroll modes
- clone session command
- make command sequences more usable: don't require space after ;, handle
errors better
- key to switch to copy mode from scroll mode
- attach should have a flag to create session if it doesn't exist
- rename split-window -> split-pane??
- fix UTF-8 guesswork on sparc64, improve tty checks
- choice and more mode would be better per client than per window?
- hooks to which commands may be attached, for example: tmux add-hook
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
$HOME/.tmux-session.conf
- get it passing all the vttest tests that don't require resizing the terminal
- esc seq to set window title should be documented and should set
automatic-rename
- esc seq to set window name and title should be documented, and name variant
should clear automatic-rename
- way to set socket path from config file
- XXX once env stuff is in, default-path and VISUAL/EDITOR should be picked up
when session is started
- what about utmp etc? can tmux update it like screen? setgid?
- H/M/L commands in copy mode with vi-keys, for jumping to the top/middle/last
line on the screen
- split list-windows into separate list-windows and list-panes
- warts on current naming:
- display-time but message-fg/bg/attr
- list-* vs show-*
- server-info
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-*
- pcvt25 doesn't work properly, why? (bce?)
- split-window -> split-pane??
- tidy up and prioritise todo list ;-)
- it is only possible to specify 8 colours to fg/bg options; should be able to
set 256 as well
- neww and attach can create a session if none exists?
would work fine with config file since
- a way for force-width/height to apply to only one pane (how?)
- **** a command to run something without a window and send any output to the
window-more. if no output, info() a line saying "'%s' returned %d". so i can
bind mpc control commands to function keys ;-)
- command to list what is actually running in each window with command line,
pid (need some adaption of the osdep code)
- string option to change/remove the symbols (*-+ etc) in status line
- support for bce
- it would be nice if the start/end line keys in copy mode were aware of
wrapped lines
- per session locking
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
-- idea of a "view" onto a window, need base x/y offsets
for redraw
- a window option which means data is echoed to all panes in a window
- support running tmux from inside tmux [#(), if-shell] --
generic system-like function which may take a callback
also sets up environment (TMUX) and has a timeout
for #(): command schedular, status line queues it with a time, run in
main loop, and uses most recent result -- can also be used for persistent
commands which never exit just continually output
for if-shell, callback??
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- fix line wrapping c&p problems in xterm etc
- a way to address panes by name ("top-left") and position ("0,0")
- ability to specify multiple prefix keys
- commands should be able to succeed or fail and have || or && for command
lists
- support the mouse wheel to scroll through history
- some way to KEEP a command running continually and just use its LAST line of
output
- bind commands to mouse buttons
- UTF-8 to a non-UTF-8 terminal should not be able to balls up
the terminal - www/ruby-addressable; make regress
- copy mode needs a tidy/cleanup
- ability to save history (to buffer?)
- multiple keys could be done with tables, ie have prefixes go and instead
bind -n ^A prefix-table "default"
where prefix-table sets command lookup table and sets prefix flag, then next
key is looked up in that table
- UTF-8 should be a pointer into a combined string buffer
- check irssi (term_charset) works with UTF-8
- support esc-esc to quit in modes
- fix ctrl+F1-F4 output. to what?
- look into xterm clearing its selection when scrolling etc
- better utf8 support:
window names
prompt input
message display
copy and paste cursor and wide characters
...?
- option so that when session is destroyed, attach client to another session
rather than exiting
- session history for client and last-session command
- option to change status line colour when current window is in a mode?
- option to move copy mode indicator into status line
- list-buffer/show-buffer should display UTF-8
- selection behaviour closer to vi in vi mode
- live update: server started with -U connects to server, requests sessions and
windows, receives fds
- convert status line history to be server global (anything else?)
- something for -t "last window in session" so a session can be used as a stack
- command to show a tree of sessions-windows-panes (active marked with *)
- sort out inheriting config from shell on new sessions/windows:
should pick up default-path/termios/etc from client if possible,
else leave empty/default
- define custom layouts
- link panes into multiple windows
- -h option to capture-pane to capture the history as well
- bells should be passed between sessions with visual-bell etc
- use screen-256color when started on 256 colour terminal??
- if-shell/run-shell should block further command execution in the same command
sequence until its shell exits, to allow them to be used from the config file
- better session sharing: create-socket command to create socket somewhere (-r
flag for readonly)
- allow buffer to be specified when copying in copy mode
- multiline status line
- flag for absolute pane size to resize-pane
- sanity check input to socket
- stdin fd should be passed up to parent so load-buffer and others could use it
for nonattaching clients
- environment should be set up for jobs
- select-buffer command
- fix jobs so they block in config file rather than executing at an arbitrary
future point -- need state stored in client so other clients can proceed
- rectangle copy:
when selecting leftward, cursor should be inside block per emacs
key to rotate corner at which cursor is
- double C-a should walk back over wrapped lines like C-e
- support title stack, both internally and externally
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
- copy buffers should be global, limit can be server option, nuke copy-buffer
command
- command to show status line information briefly when it is off

View File

@@ -1,4 +1,4 @@
/* $Id: array.h,v 1.7 2008-09-29 16:58:02 nicm Exp $ */
/* $Id: array.h,v 1.10 2010-02-08 18:29:32 tcunha Exp $ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,6 +19,8 @@
#ifndef ARRAY_H
#define ARRAY_H
#define ARRAY_INITIALIZER { NULL, 0, 0 }
#define ARRAY_DECL(n, c) \
struct n { \
c *list; \
@@ -85,7 +87,7 @@
ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \
} \
(a)->num--; \
if ((a)->num == 0) \
if ((a)->num == 0) \
ARRAY_FREE(a); \
} while (0)
@@ -102,7 +104,7 @@
#define ARRAY_CONCAT(a, b) do { \
ARRAY_ENSURE(a, (b)->num); \
memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)) \
memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \
(a)->num += (b)->num; \
} while (0)

View File

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

139
buffer.c
View File

@@ -1,139 +0,0 @@
/* $Id: buffer.c,v 1.8 2009-08-21 21:09:13 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/* Create a buffer. */
struct buffer *
buffer_create(size_t size)
{
struct buffer *b;
if (size == 0)
fatalx("zero size");
b = xcalloc(1, sizeof *b);
b->base = xmalloc(size);
b->space = size;
return (b);
}
/* Destroy a buffer. */
void
buffer_destroy(struct buffer *b)
{
xfree(b->base);
xfree(b);
}
/* Ensure free space for size in buffer. */
void
buffer_ensure(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (BUFFER_FREE(b) >= size)
return;
if (b->off > 0) {
if (b->size > 0)
memmove(b->base, b->base + b->off, b->size);
b->off = 0;
}
if (SIZE_MAX - b->size < size)
fatalx("size too big");
while (b->space < b->size + size) {
b->base = xrealloc(b->base, 2, b->space);
b->space *= 2;
}
}
/* Adjust buffer after data appended. */
void
buffer_add(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->space - b->size)
fatalx("overflow");
b->size += size;
}
/* Adjust buffer after data removed. */
void
buffer_remove(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
b->size -= size;
b->off += size;
}
/* Copy data into a buffer. */
void
buffer_write(struct buffer *b, const void *data, size_t size)
{
buffer_ensure(b, size);
memcpy(BUFFER_IN(b), data, size);
buffer_add(b, size);
}
/* Copy data out of a buffer. */
void
buffer_read(struct buffer *b, void *data, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
memcpy(data, BUFFER_OUT(b), size);
buffer_remove(b, size);
}
/* Store an 8-bit value. */
void
buffer_write8(struct buffer *b, uint8_t n)
{
buffer_ensure(b, 1);
BUFFER_IN(b)[0] = n;
b->size++;
}
/* Extract an 8-bit value. */
uint8_t
buffer_read8(struct buffer *b)
{
uint8_t n;
n = BUFFER_OUT(b)[0];
buffer_remove(b, 1);
return (n);
}

62
cfg.c
View File

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

View File

@@ -1,90 +0,0 @@
/* $Id: client-fn.c,v 1.10 2009-08-14 21:04:04 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
void
client_fill_session(struct msg_command_data *data)
{
char *env, *ptr1, *ptr2, buf[256];
size_t len;
const char *errstr;
long long ll;
data->pid = -1;
if ((env = getenv("TMUX")) == NULL)
return;
if ((ptr2 = strrchr(env, ',')) == NULL || ptr2 == env)
return;
for (ptr1 = ptr2 - 1; ptr1 > env && *ptr1 != ','; ptr1--)
;
if (*ptr1 != ',')
return;
ptr1++;
ptr2++;
len = ptr2 - ptr1 - 1;
if (len > (sizeof buf) - 1)
return;
memcpy(buf, ptr1, len);
buf[len] = '\0';
ll = strtonum(buf, 0, LONG_MAX, &errstr);
if (errstr != NULL)
return;
data->pid = ll;
ll = strtonum(ptr2, 0, UINT_MAX, &errstr);
if (errstr != NULL)
return;
data->idx = ll;
}
void
client_write_server(
struct client_ctx *cctx, enum msgtype type, void *buf, size_t len)
{
imsg_compose(&cctx->ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
void
client_suspend(void)
{
struct sigaction act;
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
act.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &act, NULL) != 0)
fatal("sigaction failed");
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
}

385
client.c
View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.70 2009-09-03 21:06:30 tcunha Exp $ */
/* $Id: client.c,v 1.90 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,6 +24,7 @@
#include <sys/wait.h>
#include <errno.h>
#include <event.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
@@ -33,21 +34,27 @@
#include "tmux.h"
void client_send_environ(struct client_ctx *);
void client_handle_winch(struct client_ctx *);
struct imsgbuf client_ibuf;
struct event client_event;
const char *client_exitmsg;
int client_exitval;
int
client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
void client_send_identify(int);
void client_send_environ(void);
void client_write_server(enum msgtype, void *, size_t);
void client_update_event(void);
void client_signal(int, short, void *);
void client_callback(int, short, void *);
int client_dispatch(void);
struct imsgbuf *
client_init(char *path, int cmdflags, int flags)
{
struct sockaddr_un sa;
struct stat sb;
struct msg_identify_data data;
struct winsize ws;
size_t size;
int fd, fd2, mode;
char *name, *term;
struct sockaddr_un sa;
size_t size;
int fd, mode;
#ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
char rpathbuf[MAXPATHLEN];
#endif
#ifdef HAVE_SETPROCTITLE
@@ -56,19 +63,6 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
setproctitle("client (%s)", rpathbuf);
#endif
if (lstat(path, &sb) != 0) {
if (cmdflags & CMD_STARTSERVER && errno == ENOENT) {
if ((fd = server_start(path)) == -1)
goto start_failed;
goto server_started;
}
goto not_found;
}
if (!S_ISSOCK(sb.st_mode)) {
errno = ENOTSOCK;
goto not_found;
}
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
@@ -78,12 +72,17 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
}
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket");
fatal("socket failed");
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
if (errno == ECONNREFUSED) {
if (unlink(path) != 0 || !(cmdflags & CMD_STARTSERVER))
if (!(cmdflags & CMD_STARTSERVER))
goto not_found;
switch (errno) {
case ECONNREFUSED:
if (unlink(path) != 0)
goto not_found;
/* FALLTHROUGH */
case ENOENT:
if ((fd = server_start(path)) == -1)
goto start_failed;
goto server_started;
@@ -96,211 +95,225 @@ server_started:
fatal("fcntl failed");
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
imsg_init(&cctx->ibuf, fd);
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
imsg_init(&client_ibuf, fd);
if (cmdflags & CMD_SENDENVIRON)
client_send_environ(cctx);
if (isatty(STDIN_FILENO)) {
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
data.flags = flags;
data.sx = ws.ws_col;
data.sy = ws.ws_row;
client_send_environ();
if (isatty(STDIN_FILENO))
client_send_identify(flags);
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0';
*data.term = '\0';
if ((term = getenv("TERM")) != NULL) {
if (strlcpy(data.term,
term, sizeof data.term) >= sizeof data.term)
*data.term = '\0';
}
*data.tty = '\0';
if ((name = ttyname(STDIN_FILENO)) == NULL)
fatal("ttyname failed");
if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty)
fatalx("ttyname failed");
fd2 = dup(STDIN_FILENO);
imsg_compose(&cctx->ibuf, MSG_IDENTIFY,
PROTOCOL_VERSION, -1, fd2, &data, sizeof data);
}
return (0);
return (&client_ibuf);
start_failed:
log_warnx("server failed to start");
return (1);
return (NULL);
not_found:
log_warn("server not found");
return (1);
return (NULL);
}
void
client_send_environ(struct client_ctx *cctx)
client_send_identify(int flags)
{
char **var;
struct msg_environ_data data;
struct msg_identify_data data;
struct winsize ws;
char *term;
int fd;
for (var = environ; *var != NULL; var++) {
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
data.flags = flags;
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0';
term = getenv("TERM");
if (term == NULL ||
strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
*data.term = '\0';
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf,
MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
}
void
client_send_environ(void)
{
struct msg_environ_data data;
char **var;
for (var = environ; *var != NULL; var++) {
if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
continue;
client_write_server(cctx, MSG_ENVIRON, &data, sizeof data);
client_write_server(MSG_ENVIRON, &data, sizeof data);
}
}
int
client_main(struct client_ctx *cctx)
void
client_write_server(enum msgtype type, void *buf, size_t len)
{
struct pollfd pfd;
int n, nfds;
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
siginit();
void
client_update_event(void)
{
short events;
event_del(&client_event);
events = EV_READ;
if (client_ibuf.w.queued > 0)
events |= EV_WRITE;
event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
event_add(&client_event, NULL);
}
__dead void
client_main(void)
{
struct event ev_sigcont, ev_sigterm, ev_sigwinch;
struct sigaction sigact;
logfile("client");
/* Note: event_init() has already been called. */
/* Set up signals. */
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_IGN;
if (sigaction(SIGINT, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGPIPE, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR1, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR2, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
signal_set(&ev_sigcont, SIGCONT, client_signal, NULL);
signal_add(&ev_sigcont, NULL);
signal_set(&ev_sigterm, SIGTERM, client_signal, NULL);
signal_add(&ev_sigterm, NULL);
signal_set(&ev_sigwinch, SIGWINCH, client_signal, NULL);
signal_add(&ev_sigwinch, NULL);
/*
* imsg_read in the first client poll loop (before the terminal has
* been initialiased) may have read messages into the buffer after the
* MSG_READY switched to here. Process anything outstanding now so poll
* doesn't hang waiting for messages that have already arrived.
* been initialised) may have read messages into the buffer after the
* MSG_READY switched to here. Process anything outstanding now to
* avoid hanging waiting for messages that have already arrived.
*/
if (client_msg_dispatch(cctx) != 0)
if (client_dispatch() != 0)
goto out;
for (;;) {
if (sigterm)
client_write_server(cctx, MSG_EXITING, NULL, 0);
if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG);
sigchld = 0;
}
if (sigwinch)
client_handle_winch(cctx);
if (sigcont) {
siginit();
client_write_server(cctx, MSG_WAKEUP, NULL, 0);
sigcont = 0;
}
pfd.fd = cctx->ibuf.fd;
pfd.events = POLLIN;
if (cctx->ibuf.w.queued > 0)
pfd.events |= POLLOUT;
if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
if (nfds == 0)
continue;
if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL))
fatalx("socket error");
if (pfd.revents & POLLIN) {
if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) {
cctx->exittype = CCTX_DIED;
break;
}
if (client_msg_dispatch(cctx) != 0)
break;
}
if (pfd.revents & POLLOUT) {
if (msgbuf_write(&cctx->ibuf.w) < 0) {
cctx->exittype = CCTX_DIED;
break;
}
}
}
/* Set the event and dispatch. */
client_update_event();
event_dispatch();
out:
if (sigterm) {
printf("[terminated]\n");
return (1);
}
switch (cctx->exittype) {
case CCTX_DIED:
printf("[lost server]\n");
return (0);
case CCTX_SHUTDOWN:
printf("[server exited]\n");
return (0);
case CCTX_EXIT:
if (cctx->errstr != NULL) {
printf("[error: %s]\n", cctx->errstr);
return (1);
}
printf("[exited]\n");
return (0);
case CCTX_DETACH:
printf("[detached]\n");
return (0);
default:
printf("[unknown error]\n");
return (1);
}
/* Print the exit message, if any, and exit. */
if (client_exitmsg != NULL && !login_shell)
printf("[%s]\n", client_exitmsg);
exit(client_exitval);
}
/* ARGSUSED */
void
client_handle_winch(struct client_ctx *cctx)
client_signal(int sig, unused short events, unused void *data)
{
struct msg_resize_data data;
struct winsize ws;
struct sigaction sigact;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl failed");
switch (sig) {
case SIGTERM:
client_exitmsg = "terminated";
client_exitval = 1;
client_write_server(MSG_EXITING, NULL, 0);
break;
case SIGWINCH:
client_write_server(MSG_RESIZE, NULL, 0);
break;
case SIGCONT:
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_IGN;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
client_write_server(MSG_WAKEUP, NULL, 0);
break;
}
data.sx = ws.ws_col;
data.sy = ws.ws_row;
client_write_server(cctx, MSG_RESIZE, &data, sizeof data);
client_update_event();
}
sigwinch = 0;
/* ARGSUSED */
void
client_callback(unused int fd, short events, unused void *data)
{
ssize_t n;
if (events & EV_READ) {
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
goto lost_server;
if (client_dispatch() != 0) {
event_loopexit(NULL);
return;
}
}
if (events & EV_WRITE) {
if (msgbuf_write(&client_ibuf.w) < 0)
goto lost_server;
}
client_update_event();
return;
lost_server:
client_exitmsg = "lost server";
client_exitval = 1;
event_loopexit(NULL);
}
int
client_msg_dispatch(struct client_ctx *cctx)
client_dispatch(void)
{
struct imsg imsg;
struct msg_print_data printdata;
ssize_t n, datalen;
struct imsg imsg;
struct msg_lock_data lockdata;
struct sigaction sigact;
ssize_t n, datalen;
for (;;) {
if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1)
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
fatalx("imsg_get failed");
if (n == 0)
return (0);
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
log_debug("client got %d", imsg.hdr.type);
switch (imsg.hdr.type) {
case MSG_DETACH:
if (datalen != 0)
fatalx("bad MSG_DETACH size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_DETACH;
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "detached";
break;
case MSG_ERROR:
if (datalen != sizeof printdata)
fatalx("bad MSG_ERROR size");
memcpy(&printdata, imsg.data, sizeof printdata);
printdata.msg[(sizeof printdata.msg) - 1] = '\0';
/* Error string used after exit message from server. */
cctx->errstr = xstrdup(printdata.msg);
imsg_free(&imsg);
return (-1);
case MSG_EXIT:
if (datalen != 0)
fatalx("bad MSG_EXIT size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_EXIT;
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "exited";
break;
case MSG_EXITED:
if (datalen != 0)
@@ -312,14 +325,30 @@ client_msg_dispatch(struct client_ctx *cctx)
if (datalen != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_SHUTDOWN;
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "server exited";
client_exitval = 1;
break;
case MSG_SUSPEND:
if (datalen != 0)
fatalx("bad MSG_SUSPEND size");
client_suspend();
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
break;
case MSG_LOCK:
if (datalen != sizeof lockdata)
fatalx("bad MSG_LOCK size");
memcpy(&lockdata, imsg.data, sizeof lockdata);
lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
system(lockdata.cmd);
client_write_server(MSG_UNLOCK, NULL, 0);
break;
default:
fatalx("unexpected message");

12
clock.c
View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-bind-key.c,v 1.25 2009-07-28 23:19:06 tcunha Exp $ */
/* $Id: cmd-bind-key.c,v 1.28 2010-01-25 17:12:44 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,7 +46,7 @@ struct cmd_bind_key_data {
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
"[-cnr] [-t key-table] key command [arguments]",
0, 0,
0, "",
NULL,
cmd_bind_key_parse,
cmd_bind_key_exec,
@@ -79,7 +79,8 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
data->can_repeat = 1;
break;
case 't':
data->tablename = xstrdup(optarg);
if (data->tablename == NULL)
data->tablename = xstrdup(optarg);
break;
default:
goto usage;
@@ -152,7 +153,7 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "unknown command: %s", data->modecmd);
return (-1);
}
mtmp.key = data->key & ~KEYC_PREFIX;
mtmp.mode = data->command_key ? 1 : 0;
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {

View File

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

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

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-session.c,v 1.13 2009-09-07 23:59:19 tcunha Exp $ */
/* $Id: cmd-choose-session.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_session_free(void *);
const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
CMD_ARG01, "",
cmd_target_init,
cmd_target_parse,
cmd_choose_session_exec,
@@ -54,7 +54,9 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_choose_session_data *cdata;
struct winlink *wl;
struct session *s;
struct session_group *sg;
u_int i, idx, cur;
char tmp[64];
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
@@ -76,10 +78,18 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx;
idx++;
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
else {
idx = session_group_index(sg);
xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
}
window_choose_add(wl->window->active, i,
"%s: %u windows [%ux%u]%s", s->name,
"%s: %u windows [%ux%u]%s%s", s->name,
winlink_count(&s->windows), s->sx, s->sy,
s->flags & SESSION_UNATTACHED ? "" : " (attached)");
tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
}
cdata = xmalloc(sizeof *cdata);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-window.c,v 1.17 2009-09-07 23:59:19 tcunha Exp $ */
/* $Id: cmd-choose-window.c,v 1.20 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_window_free(void *);
const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
CMD_ARG01, "",
cmd_target_init,
cmd_target_parse,
cmd_choose_window_exec,
@@ -89,7 +89,7 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
flag = '+';
else if (wm == s->curw)
flag = '*';
else if (wm == SLIST_FIRST(&s->lastw))
else if (wm == TAILQ_FIRST(&s->lastw))
flag = '-';
title = w->active->screen->title;
@@ -116,10 +116,10 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
window_choose_ready(wl->window->active,
cur, cmd_choose_window_callback, cmd_choose_window_free, cdata);
return (0);
return (0);
}
void
@@ -133,7 +133,7 @@ cmd_choose_window_callback(void *data, int idx)
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
return;
if (cdata->session->flags & SESSION_DEAD)
return;
if (cdata->client->session != cdata->session)

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-command-prompt.c,v 1.25 2009-08-25 13:53:39 tcunha Exp $ */
/* $Id: cmd-command-prompt.c,v 1.27 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -39,7 +39,7 @@ void cmd_command_prompt_cfree(void *);
const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL,
CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]",
0, 0,
0, "",
cmd_command_prompt_init,
cmd_command_prompt_parse,
cmd_command_prompt_exec,
@@ -90,7 +90,7 @@ cmd_command_prompt_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_command_prompt_data *data;
int opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "p:t:")) != -1) {

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-buffer.c,v 1.4 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-copy-buffer.c,v 1.7 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -43,7 +43,7 @@ struct cmd_copy_buffer_data {
const struct cmd_entry cmd_copy_buffer_entry = {
"copy-buffer", "copyb",
"[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
0, 0,
0, "",
cmd_copy_buffer_init,
cmd_copy_buffer_parse,
cmd_copy_buffer_exec,
@@ -51,6 +51,7 @@ const struct cmd_entry cmd_copy_buffer_entry = {
cmd_copy_buffer_print
};
/* ARGSUSED */
void
cmd_copy_buffer_init(struct cmd *self, unused int arg)
{
@@ -70,7 +71,7 @@ cmd_copy_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
const char *errstr;
int n, opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "a:b:s:t:")) != -1) {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */
/* $Id: cmd-copy-mode.c,v 1.26 2010-01-05 23:50:22 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,19 +24,35 @@
* Enter copy mode.
*/
void cmd_copy_mode_init(struct cmd *, int);
int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE,
0, CMD_CHFLAG('u'),
cmd_target_init,
0, "u",
cmd_copy_mode_init,
cmd_target_parse,
cmd_copy_mode_exec,
cmd_target_free,
NULL
cmd_target_print
};
void
cmd_copy_mode_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case KEYC_PPAGE:
cmd_set_flag(&data->chflags, 'u');
break;
}
}
int
cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{
@@ -47,7 +63,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
window_pane_set_mode(wp, &window_copy_mode);
if (wp->mode == &window_copy_mode && data->chflags & CMD_CHFLAG('u'))
if (wp->mode == &window_copy_mode && cmd_check_flag(data->chflags, 'u'))
window_copy_pageup(wp);
return (0);

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-down-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-down-pane.c,v 1.14 2010-01-05 23:52:37 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_down_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_down_pane_entry = {
"down-pane", "downp",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_down_pane_exec,
@@ -54,6 +54,7 @@ cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_FIRST(&w->panes);
} while (!window_pane_visible(w->active));
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,8 @@
/* $Id: cmd-if-shell.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-if-shell.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
* Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,9 +18,8 @@
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -28,124 +28,90 @@
* Executes a tmux command if a shell command returns true.
*/
int cmd_if_shell_parse(struct cmd *, int, char **, char **);
int cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_if_shell_free(struct cmd *);
void cmd_if_shell_init(struct cmd *, int);
size_t cmd_if_shell_print(struct cmd *, char *, size_t);
struct cmd_if_shell_data {
char *cmd;
char *sh_cmd;
};
void cmd_if_shell_callback(struct job *);
void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"shell-command command",
0, 0,
cmd_if_shell_init,
cmd_if_shell_parse,
CMD_ARG2, "",
cmd_target_init,
cmd_target_parse,
cmd_if_shell_exec,
cmd_if_shell_free,
cmd_if_shell_print
cmd_target_free,
cmd_target_print
};
void
cmd_if_shell_init(struct cmd *self, unused int arg)
{
struct cmd_if_shell_data *data;
self->data = data = xmalloc(sizeof *data);
data->cmd = NULL;
data->sh_cmd = NULL;
}
int
cmd_if_shell_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_if_shell_data *data;
int opt;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "")) != -1) {
switch (opt) {
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 2)
goto usage;
data->sh_cmd = xstrdup(argv[0]);
data->cmd = xstrdup(argv[1]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
struct cmd_if_shell_data {
char *cmd;
struct cmd_ctx ctx;
};
int
cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_if_shell_data *data = self->data;
struct cmd_target_data *data = self->data;
struct cmd_if_shell_data *cdata;
struct job *job;
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg2);
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
ctx->cmdclient->references++;
if (ctx->curclient != NULL)
ctx->curclient->references++;
job = job_add(NULL, 0, NULL,
data->arg, cmd_if_shell_callback, cmd_if_shell_free, cdata);
job_run(job);
return (1); /* don't let client exit */
}
void
cmd_if_shell_callback(struct job *job)
{
struct cmd_if_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
struct cmd_list *cmdlist;
char *cause;
int ret;
if ((ret = system(data->sh_cmd)) < 0) {
ctx->error(ctx, "system error: %s", strerror(errno));
return (-1);
} else if (ret != 0)
return (0);
if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
return;
if (cmd_string_parse(data->cmd, &cmdlist, &cause) != 0) {
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
ctx->error(ctx, "%s", cause);
xfree(cause);
}
return (-1);
return;
}
if (cmd_list_exec(cmdlist, ctx) < 0) {
cmd_list_free(cmdlist);
return (-1);
return;
}
cmd_list_free(cmdlist);
return (0);
}
void
cmd_if_shell_free(struct cmd *self)
cmd_if_shell_free(void *data)
{
struct cmd_if_shell_data *data = self->data;
struct cmd_if_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
if (data->cmd != NULL)
xfree(data->cmd);
if (data->sh_cmd != NULL)
xfree(data->sh_cmd);
xfree(data);
}
size_t
cmd_if_shell_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_if_shell_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->sh_cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->sh_cmd);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
xfree(cdata->cmd);
xfree(cdata);
}

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

@@ -0,0 +1,256 @@
/* $Id: cmd-join-pane.c,v 1.2 2010-01-08 16:34:17 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
/*
* Join a pane into another (like split/swap/kill).
*/
int cmd_join_pane_parse(struct cmd *, int, char **, char **);
int cmd_join_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_join_pane_free(struct cmd *);
void cmd_join_pane_init(struct cmd *, int);
size_t cmd_join_pane_print(struct cmd *, char *, size_t);
struct cmd_join_pane_data {
char *src;
char *dst;
int flag_detached;
int flag_horizontal;
int percentage;
int size;
};
const struct cmd_entry cmd_join_pane_entry = {
"join-pane", "joinp",
"[-dhv] [-p percentage|-l size] [-t src-pane] [-t dst-pane] [command]",
0, "",
cmd_join_pane_init,
cmd_join_pane_parse,
cmd_join_pane_exec,
cmd_join_pane_free,
cmd_join_pane_print
};
void
cmd_join_pane_init(struct cmd *self, int key)
{
struct cmd_join_pane_data *data;
self->data = data = xmalloc(sizeof *data);
data->src = NULL;
data->dst = NULL;
data->flag_detached = 0;
data->flag_horizontal = 0;
data->percentage = -1;
data->size = -1;
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
case '"':
data->flag_horizontal = 0;
break;
}
}
int
cmd_join_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_join_pane_data *data;
int opt;
const char *errstr;
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dhl:p:s:t:v")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
break;
case 'h':
data->flag_horizontal = 1;
break;
case 's':
if (data->src == NULL)
data->src = xstrdup(optarg);
break;
case 't':
if (data->dst == NULL)
data->dst = xstrdup(optarg);
break;
case 'l':
if (data->percentage != -1 || data->size != -1)
break;
data->size = strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "size %s", errstr);
goto error;
}
break;
case 'p':
if (data->size != -1 || data->percentage != -1)
break;
data->percentage = strtonum(optarg, 1, 100, &errstr);
if (errstr != NULL) {
xasprintf(cause, "percentage %s", errstr);
goto error;
}
break;
case 'v':
data->flag_horizontal = 0;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 0)
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
}
int
cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_join_pane_data *data = self->data;
struct session *dst_s;
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w;
struct window_pane *src_wp, *dst_wp;
int size;
enum layout_type type;
struct layout_cell *lc;
if ((dst_wl = cmd_find_pane(ctx, data->dst, &dst_s, &dst_wp)) == NULL)
return (-1);
dst_w = dst_wl->window;
if ((src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp)) == NULL)
return (-1);
src_w = src_wl->window;
if (src_w == dst_w) {
ctx->error(ctx, "can't join a pane to its own window");
return (-1);
}
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1) {
if (type == LAYOUT_TOPBOTTOM)
size = (dst_wp->sy * data->percentage) / 100;
else
size = (dst_wp->sx * data->percentage) / 100;
}
if ((lc = layout_split_pane(dst_wp, type, size)) == NULL) {
ctx->error(ctx, "create pane failed: pane too small");
return (-1);
}
layout_close_pane(src_wp);
if (src_w->active == src_wp) {
src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
if (src_w->active == NULL)
src_w->active = TAILQ_NEXT(src_wp, entry);
}
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
if (window_count_panes(src_w) == 0)
server_kill_window(src_w);
src_wp->window = dst_w;
TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
layout_assign_pane(lc, src_wp);
recalculate_sizes();
server_redraw_window(src_w);
server_redraw_window(dst_w);
if (!data->flag_detached) {
window_set_active_pane(dst_w, src_wp);
session_select(dst_s, dst_wl->idx);
server_redraw_session(dst_s);
} else
server_status_session(dst_s);
return (0);
}
void
cmd_join_pane_free(struct cmd *self)
{
struct cmd_join_pane_data *data = self->data;
if (data->src != NULL)
xfree(data->src);
if (data->dst != NULL)
xfree(data->dst);
xfree(data);
}
size_t
cmd_join_pane_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_join_pane_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->flag_horizontal)
off += xsnprintf(buf + off, len - off, " -h");
if (off < len && data->size > 0)
off += xsnprintf(buf + off, len - off, " -l %d", data->size);
if (off < len && data->percentage > 0) {
off += xsnprintf(
buf + off, len - off, " -p %d", data->percentage);
}
if (off < len && data->src != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->src);
if (off < len && data->dst != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->dst);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/* $Id: cmd-kill-pane.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,8 +30,8 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp",
CMD_TARGET_PANE_USAGE,
0, 0,
"[-a] " CMD_TARGET_PANE_USAGE,
0, "a",
cmd_target_init,
cmd_target_parse,
cmd_kill_pane_exec,
@@ -44,7 +44,7 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct window_pane *loopwp, *nextwp, *wp;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
return (-1);
@@ -52,11 +52,25 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (window_count_panes(wl->window) == 1) {
/* Only one pane, kill the window. */
server_kill_window(wl->window);
recalculate_sizes();
return (0);
}
layout_close_pane(wp);
window_remove_pane(wl->window, wp);
if (cmd_check_flag(data->chflags, 'a')) {
loopwp = TAILQ_FIRST(&wl->window->panes);
while (loopwp != NULL) {
nextwp = TAILQ_NEXT(loopwp, entry);
if (loopwp != wp) {
layout_close_pane(loopwp);
window_remove_pane(wl->window, loopwp);
}
loopwp = nextwp;
}
} else {
layout_close_pane(wp);
window_remove_pane(wl->window, wp);
}
server_redraw_window(wl->window);
return (0);
}

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-kill-session.c,v 1.17 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_kill_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL,
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_kill_session_exec,
@@ -45,7 +45,7 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct client *c;
struct client *c;
u_int i;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
@@ -53,7 +53,7 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c->session == s) {
if (c != NULL && c->session == s) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.19 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-kill-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_kill_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_kill_window_exec,
@@ -47,6 +47,7 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
server_kill_window(wl->window);
recalculate_sizes();
return (0);
}

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-link-window.c,v 1.32 2009-08-16 19:16:27 tcunha Exp $ */
/* $Id: cmd-link-window.c,v 1.36 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
0, "dk",
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_link_window_exec,
@@ -43,55 +43,23 @@ int
cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *dst;
struct winlink *wl_src, *wl_dst;
struct session *src, *dst;
struct winlink *wl;
char *cause;
int idx;
int idx, kflag, dflag;
if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL)
if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
wl_dst = NULL;
if (idx != -1)
wl_dst = winlink_find_by_index(&dst->windows, idx);
if (wl_dst != NULL) {
if (wl_dst->window == wl_src->window)
return (0);
if (data->chflags & CMD_CHFLAG('k')) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(dst, wl_dst);
winlink_stack_remove(&dst->lastw, wl_dst);
winlink_remove(&dst->windows, wl_dst);
/* Force select/redraw if current. */
if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d');
dst->curw = NULL;
}
}
}
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) {
ctx->error(ctx, "create session failed: %s", cause);
kflag = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't link window: %s", cause);
xfree(cause);
return (-1);
}
if (data->chflags & CMD_CHFLAG('d'))
server_status_session(dst);
else {
session_select(dst, wl_dst->idx);
server_redraw_session(dst);
}
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-buffers.c,v 1.12 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-list-buffers.c,v 1.15 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_buffers_entry = {
"list-buffers", "lsb",
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_buffers_exec,
@@ -63,14 +63,14 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
strvisx(tmp, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL);
/*
* If the first 50 characterswere encoded as a longer string,
* If the first 50 characters were encoded as a longer string,
* or there is definitely more data, add "...".
*/
if (size > 50 || strlen(tmp) > 50) {
tmp[50 - 3] = '\0';
strlcat(tmp, "...", sizeof tmp);
}
ctx->print(ctx, "%u: %zu bytes: \"%s\"", idx - 1, size, tmp);
}

View File

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

View File

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

View File

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

74
cmd-list-panes.c Normal file
View File

@@ -0,0 +1,74 @@
/* $Id: cmd-list-panes.c,v 1.4 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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 <unistd.h>
#include "tmux.h"
/*
* List panes on given window.
*/
int cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
CMD_TARGET_WINDOW_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_panes_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct grid *gd;
struct grid_line *gl;
u_int i, n;
unsigned long long size;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
n = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
gd = wp->base.grid;
size = 0;
for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i];
size += gl->cellsize * sizeof *gl->celldata;
size += gl->utf8size * sizeof *gl->utf8data;
}
size += gd->hsize * sizeof *gd->linedata;
ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes]",
n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
n++;
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-sessions.c,v 1.21 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-list-sessions.c,v 1.25 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", "",
0, 0,
0, "",
NULL,
NULL,
cmd_list_sessions_exec,
@@ -39,26 +39,36 @@ const struct cmd_entry cmd_list_sessions_entry = {
NULL
};
/* ARGSUSED */
int
cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
struct session *s;
char *tim;
u_int i;
time_t t;
struct session *s;
struct session_group *sg;
char *tim, tmp[64];
u_int i, idx;
time_t t;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
t = s->tv.tv_sec;
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
else {
idx = session_group_index(sg);
xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
}
t = s->creation_time.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s",
ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s%s",
s->name, winlink_count(&s->windows), tim, s->sx, s->sy,
s->flags & SESSION_UNATTACHED ? "" : " (attached)");
tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.40 2009-08-09 17:28:23 tcunha Exp $ */
/* $Id: cmd-list-windows.c,v 1.42 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw",
CMD_TARGET_SESSION_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_windows_exec,
@@ -45,42 +45,13 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct grid *gd;
struct grid_line *gl;
u_int i;
unsigned long long size;
const char *name;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
ctx->print(ctx,
"%3d: %s [%ux%u]", wl->idx, w->name, w->sx, w->sy);
TAILQ_FOREACH(wp, &w->panes, entry) {
gd = wp->base.grid;
size = 0;
for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i];
size += gl->cellsize * sizeof *gl->celldata;
size += gl->utf8size * sizeof *gl->utf8data;
}
size += gd->hsize * sizeof *gd->linedata;
name = NULL;
if (wp->fd != -1)
name = ttyname(wp->fd);
if (name == NULL)
name = "unknown";
ctx->print(ctx,
" %s [%ux%u] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
}
ctx->print(ctx, "%d: %s [%ux%u]",
wl->idx, wl->window->name, wl->window->sx, wl->window->sy);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-list.c,v 1.7 2010-02-02 23:51:04 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -77,13 +77,32 @@ int
cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
{
struct cmd *cmd;
int n;
int n, retval;
retval = 0;
TAILQ_FOREACH(cmd, cmdlist, qentry) {
if ((n = cmd_exec(cmd, ctx)) != 0)
return (n);
if ((n = cmd_exec(cmd, ctx)) == -1)
return (-1);
/*
* A 1 return value means the command client is being attached
* (sent MSG_READY).
*/
if (n == 1) {
retval = 1;
/*
* The command client has been attached, so mangle the
* context to treat any following commands as if they
* were called from inside.
*/
if (ctx->curclient == NULL) {
ctx->curclient = ctx->cmdclient;
ctx->cmdclient = NULL;
}
}
}
return (0);
return (retval);
}
void

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-load-buffer.c,v 1.15 2010-02-26 13:30:07 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -16,13 +16,10 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
@@ -35,7 +32,7 @@ int cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb",
CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_load_buffer_exec,
@@ -48,53 +45,55 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct session *s;
struct stat sb;
FILE *f;
u_char *buf;
char *pdata, *new_pdata;
size_t psize;
u_int limit;
int ch;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
if (stat(data->arg, &sb) < 0) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
/*
* We don't want to die due to memory exhaustion, hence xmalloc can't
* be used here.
*/
if ((buf = malloc(sb.st_size + 1)) == NULL) {
ctx->error(ctx, "malloc error: %s", strerror(errno));
fclose(f);
return (-1);
pdata = NULL;
psize = 0;
while ((ch = getc(f)) != EOF) {
/* Do not let the server die due to memory exhaustion. */
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
ctx->error(ctx, "realloc error: %s", strerror(errno));
goto error;
}
pdata = new_pdata;
pdata[psize++] = ch;
}
if (fread(buf, 1, sb.st_size, f) != (size_t) sb.st_size) {
ctx->error(ctx, "%s: fread error", data->arg);
xfree(buf);
fclose(f);
return (-1);
if (ferror(f)) {
ctx->error(ctx, "%s: read error", data->arg);
goto error;
}
if (pdata != NULL)
pdata[psize] = '\0';
fclose(f);
limit = options_get_number(&s->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&s->buffers, buf, sb.st_size, limit);
paste_add(&s->buffers, pdata, psize, limit);
return (0);
}
if (paste_replace(&s->buffers, data->buffer, buf, sb.st_size) != 0) {
if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf);
return (-1);
goto error;
}
return (0);
error:
if (pdata != NULL)
xfree(pdata);
fclose(f);
return (-1);
}

View File

@@ -1,7 +1,7 @@
/* $Id: buffer-poll.c,v 1.16 2009-08-19 09:28:10 nicm Exp $ */
/* $Id: cmd-lock-client.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,37 +18,36 @@
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include "tmux.h"
/* Fill buffers from socket based on poll results. */
int
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
{
ssize_t n;
/*
* Lock a single client.
*/
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
int cmd_lock_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_client_entry = {
"lock-client", "lockc",
CMD_TARGET_CLIENT_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_lock_client_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_lock_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
if (pfd->revents & POLLIN) {
buffer_ensure(in, BUFSIZ);
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
if (n == 0)
return (-1);
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
return (-1);
} else
buffer_add(in, n);
}
if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
return (-1);
} else
buffer_remove(out, n);
}
server_lock_client(c);
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-server.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-lock-server.c,v 1.9 2009-11-28 14:50:36 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock",
"",
0, 0,
0, "",
NULL,
NULL,
cmd_lock_server_exec,
@@ -41,10 +41,12 @@ const struct cmd_entry cmd_lock_server_entry = {
NULL,
};
/* ARGSUSED */
int
cmd_lock_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{
server_lock();
recalculate_sizes();
return (0);
}

View File

@@ -1,7 +1,7 @@
/* $Id: cmd-scroll-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */
/* $Id: cmd-lock-session.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,50 +21,33 @@
#include "tmux.h"
/*
* Enter scroll mode.
* Lock all clients attached to a session.
*/
void cmd_scroll_mode_init(struct cmd *, int);
int cmd_scroll_mode_exec(struct cmd *, struct cmd_ctx *);
int cmd_lock_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_scroll_mode_entry = {
"scroll-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE,
0, CMD_CHFLAG('u'),
cmd_scroll_mode_init,
const struct cmd_entry cmd_lock_session_entry = {
"lock-session", "locks",
CMD_TARGET_SESSION_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_scroll_mode_exec,
cmd_lock_session_exec,
cmd_target_free,
cmd_target_print
};
void
cmd_scroll_mode_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case KEYC_PPAGE:
data->chflags |= CMD_CHFLAG('u');
break;
}
}
int
cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_lock_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct window_pane *wp;
struct session *s;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
window_pane_set_mode(wp, &window_scroll_mode);
if (wp->mode == &window_scroll_mode && data->chflags & CMD_CHFLAG('u'))
window_scroll_pageup(wp);
server_lock_session(s);
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-move-window.c,v 1.9 2009-08-16 19:16:27 tcunha Exp $ */
/* $Id: cmd-move-window.c,v 1.13 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_move_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew",
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
0, "dk",
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_move_window_exec,
@@ -44,68 +44,23 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *src, *dst;
struct winlink *wl_src, *wl_dst;
struct client *c;
u_int i;
int destroyed, idx;
struct winlink *wl;
char *cause;
int idx, kflag, dflag;
if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
wl_dst = NULL;
if (idx != -1)
wl_dst = winlink_find_by_index(&dst->windows, idx);
if (wl_dst != NULL) {
if (wl_dst->window == wl_src->window)
return (0);
if (data->chflags & CMD_CHFLAG('k')) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(dst, wl_dst);
winlink_stack_remove(&dst->lastw, wl_dst);
winlink_remove(&dst->windows, wl_dst);
/* Force select/redraw if current. */
if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d');
dst->curw = NULL;
}
}
}
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) {
ctx->error(ctx, "attach window failed: %s", cause);
kflag = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't move window: %s", cause);
xfree(cause);
return (-1);
}
destroyed = session_detach(src, wl_src);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != src)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
if (data->chflags & CMD_CHFLAG('d'))
server_status_session(dst);
else {
session_select(dst, wl_dst->idx);
server_redraw_session(dst);
}
server_unlink_window(src, wl);
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.66 2009-09-16 12:36:27 nicm Exp $ */
/* $Id: cmd-new-session.c,v 1.76 2010-02-26 13:28:15 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,7 +20,6 @@
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "tmux.h"
@@ -35,6 +34,7 @@ void cmd_new_session_init(struct cmd *, int);
size_t cmd_new_session_print(struct cmd *, char *, size_t);
struct cmd_new_session_data {
char *target;
char *newname;
char *winname;
char *cmd;
@@ -43,8 +43,8 @@ struct cmd_new_session_data {
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"[-d] [-n window-name] [-s session-name] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, 0,
"[-d] [-n window-name] [-s session-name] [-t target-session] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, "",
cmd_new_session_init,
cmd_new_session_parse,
cmd_new_session_exec,
@@ -52,6 +52,7 @@ const struct cmd_entry cmd_new_session_entry = {
cmd_new_session_print
};
/* ARGSUSED */
void
cmd_new_session_init(struct cmd *self, unused int arg)
{
@@ -59,6 +60,7 @@ cmd_new_session_init(struct cmd *self, unused int arg)
self->data = data = xmalloc(sizeof *data);
data->flag_detached = 0;
data->target = NULL;
data->newname = NULL;
data->winname = NULL;
data->cmd = NULL;
@@ -70,10 +72,10 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_new_session_data *data;
int opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "ds:n:")) != -1) {
while ((opt = getopt(argc, argv, "ds:t:n:")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
@@ -82,6 +84,10 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
if (data->newname == NULL)
data->newname = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'n':
if (data->winname == NULL)
data->winname = xstrdup(optarg);
@@ -95,6 +101,9 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
if (argc != 0 && argc != 1)
goto usage;
if (data->target != NULL && (argc == 1 || data->winname != NULL))
goto usage;
if (argc == 1)
data->cmd = xstrdup(argv[0]);
@@ -111,20 +120,26 @@ int
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_new_session_data *data = self->data;
struct session *s;
struct session *s, *groupwith;
struct window *w;
struct window_pane *wp;
struct environ env;
struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
int detached, idx;
u_int sx, sy;
u_int sx, sy, i;
if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname);
return (-1);
}
groupwith = NULL;
if (data->target != NULL &&
(groupwith = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
/*
* There are three cases:
*
@@ -170,8 +185,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "not a terminal");
return (-1);
}
overrides =
overrides =
options_get_string(&global_s_options, "terminal-overrides");
if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause);
@@ -205,7 +220,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
sy = 1;
/* Figure out the command for the new window. */
if (data->cmd != NULL)
if (data->target != NULL)
cmd = NULL;
else if (data->cmd != NULL)
cmd = data->cmd;
else
cmd = options_get_string(&global_s_options, "default-command");
@@ -228,7 +245,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
environ_free(&env);
/* Set the initial window name if one given. */
if (data->winname != NULL) {
if (cmd != NULL && data->winname != NULL) {
w = s->curw->window;
xfree(w->name);
@@ -237,21 +254,47 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
options_set_number(&w->options, "automatic-rename", 0);
}
/*
* If a target session is given, this is to be part of a session group,
* so add it to the group and synchronize.
*/
if (groupwith != NULL) {
session_group_add(groupwith, s);
session_group_synchronize_to(s);
session_select(s, RB_ROOT(&s->windows)->idx);
}
/*
* Set the client to the new session. If a command client exists, it is
* taking this session and needs to get MSG_READY and stay around.
*/
if (!detached) {
if (!detached) {
if (ctx->cmdclient != NULL) {
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
ctx->cmdclient->session = s;
ctx->cmdclient->session = s;
server_redraw_client(ctx->cmdclient);
} else {
ctx->curclient->session = s;
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
}
}
recalculate_sizes();
server_update_socket();
/*
* If there are still configuration file errors to display, put the new
* session's current window into more mode and display them now.
*/
if (cfg_finished && !ARRAY_EMPTY(&cfg_causes)) {
wp = s->curw->window->active;
window_pane_set_mode(wp, &window_more_mode);
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
window_more_add(wp, "%s", cause);
xfree(cause);
}
ARRAY_FREE(&cfg_causes);
}
return (!detached); /* 1 means don't tell command client to exit */
}
@@ -281,10 +324,12 @@ cmd_new_session_print(struct cmd *self, char *buf, size_t len)
return (off);
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->newname != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
if (off < len && data->winname != NULL)
off += cmd_prarg(buf + off, len - off, " -n ", data->winname);
if (off < len && data->newname != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-window.c,v 1.37 2009-08-16 19:16:27 tcunha Exp $ */
/* $Id: cmd-new-window.c,v 1.43 2010-01-22 17:28:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -43,7 +43,7 @@ struct cmd_new_window_data {
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
"[-dk] [-n window-name] [-t target-window] [command]",
0, 0,
0, "",
cmd_new_window_init,
cmd_new_window_parse,
cmd_new_window_exec,
@@ -51,6 +51,7 @@ const struct cmd_entry cmd_new_window_entry = {
cmd_new_window_print
};
/* ARGSUSED */
void
cmd_new_window_init(struct cmd *self, unused int arg)
{
@@ -70,7 +71,7 @@ cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_new_window_data *data;
int opt;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dkt:n:")) != -1) {
@@ -128,21 +129,19 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl = NULL;
if (idx != -1)
wl = winlink_find_by_index(&s->windows, idx);
if (wl != NULL) {
if (data->flag_kill) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(s, wl);
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
if (wl != NULL && data->flag_kill) {
/*
* Can't use session_detach as it will destroy session if this
* makes it empty.
*/
session_alert_cancel(s, wl);
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
}
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
}
}
@@ -164,9 +163,9 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
if (!data->flag_detached) {
session_select(s, wl->idx);
server_redraw_session(s);
server_redraw_session_group(s);
} else
server_status_session(s);
server_status_session_group(s);
return (0);
}

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-paste-buffer.c,v 1.20 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-paste-buffer.c,v 1.24 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,12 +27,12 @@
*/
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_paste_buffer_lf2cr(struct buffer *, const char *, size_t);
void cmd_paste_buffer_lf2cr(struct window_pane *, const char *, size_t);
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
"[-dr] " CMD_BUFFER_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('r'),
0, "dr",
cmd_buffer_init,
cmd_buffer_parse,
cmd_paste_buffer_exec,
@@ -62,39 +62,39 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (pb != NULL && *pb->data != '\0') {
if (pb != NULL) {
/* -r means raw data without LF->CR conversion. */
if (data->chflags & CMD_CHFLAG('r'))
buffer_write(wp->out, pb->data, pb->size);
if (cmd_check_flag(data->chflags, 'r'))
bufferevent_write(wp->event, pb->data, pb->size);
else
cmd_paste_buffer_lf2cr(wp->out, pb->data, pb->size);
cmd_paste_buffer_lf2cr(wp, pb->data, pb->size);
}
/* Delete the buffer if -d. */
if (data->chflags & CMD_CHFLAG('d')) {
if (cmd_check_flag(data->chflags, 'd')) {
if (data->buffer == -1)
paste_free_top(&s->buffers);
else
paste_free_index(&s->buffers, data->buffer);
}
return (0);
return (0);
}
/* Add bytes to a buffer but change every '\n' to '\r'. */
void
cmd_paste_buffer_lf2cr(struct buffer *b, const char *data, size_t size)
cmd_paste_buffer_lf2cr(struct window_pane *wp, const char *data, size_t size)
{
const char *end = data + size;
const char *lf;
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
buffer_write(b, data, lf - data);
buffer_write8(b, '\r');
bufferevent_write(wp->event, data, lf - data);
bufferevent_write(wp->event, "\r", 1);
data = lf + 1;
}
if (end != data)
buffer_write(b, data, end - data);
bufferevent_write(wp->event, data, end - data);
}

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

@@ -0,0 +1,141 @@
/* $Id: cmd-pipe-pane.c,v 1.10 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
/*
* Open pipe to redirect pane output. If already open, close first.
*/
int cmd_pipe_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
CMD_TARGET_PANE_USAGE "[-o] [command]",
CMD_ARG01, "o",
cmd_target_init,
cmd_target_parse,
cmd_pipe_pane_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct window_pane *wp;
int old_fd, pipe_fd[2], null_fd, mode;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
/* Destroy the old pipe. */
old_fd = wp->pipe_fd;
if (wp->pipe_fd != -1) {
bufferevent_free(wp->pipe_event);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}
/* If no pipe command, that is enough. */
if (data->arg == NULL || *data->arg == '\0')
return (0);
/*
* With -o, only open the new pipe if there was no previous one. This
* allows a pipe to be toggled with a single key, for example:
*
* bind ^p pipep -o 'cat >>~/output'
*/
if (cmd_check_flag(data->chflags, 'o') && old_fd != -1)
return (0);
/* Open the new pipe. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
ctx->error(ctx, "socketpair error: %s", strerror(errno));
return (-1);
}
/* Fork the child. */
switch (fork()) {
case -1:
ctx->error(ctx, "fork error: %s", strerror(errno));
return (-1);
case 0:
/* Child process. */
close(pipe_fd[0]);
server_signal_clear();
if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
_exit(1);
if (pipe_fd[1] != STDIN_FILENO)
close(pipe_fd[1]);
null_fd = open(_PATH_DEVNULL, O_WRONLY, 0);
if (dup2(null_fd, STDOUT_FILENO) == -1)
_exit(1);
if (dup2(null_fd, STDERR_FILENO) == -1)
_exit(1);
if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
close(null_fd);
execl(_PATH_BSHELL, "sh", "-c", data->arg, (char *) NULL);
_exit(1);
default:
/* Parent process. */
close(pipe_fd[1]);
wp->pipe_fd = pipe_fd[0];
wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
wp->pipe_event = bufferevent_new(wp->pipe_fd,
NULL, NULL, cmd_pipe_pane_error_callback, wp);
bufferevent_enable(wp->pipe_event, EV_WRITE);
if ((mode = fcntl(wp->pipe_fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(wp->pipe_fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(wp->pipe_fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
return (0);
}
}
/* ARGSUSED */
void
cmd_pipe_pane_error_callback(
unused struct bufferevent *bufev, unused short what, void *data)
{
struct window_pane *wp = data;
bufferevent_free(wp->pipe_event);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.29 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-rename-window.c,v 1.31 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_rename_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew",
CMD_TARGET_WINDOW_USAGE " new-name",
CMD_ARG1, 0,
CMD_ARG1, "",
cmd_target_init,
cmd_target_parse,
cmd_rename_window_exec,
@@ -53,7 +53,7 @@ cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl->window->name = xstrdup(data->arg);
options_set_number(&wl->window->options, "automatic-rename", 0);
server_status_session(s);
server_status_window(wl->window);
return (0);
}

View File

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

View File

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

View File

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

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

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-save-buffer.c,v 1.8 2009-09-07 23:48:54 tcunha Exp $ */
/* $Id: cmd-save-buffer.c,v 1.10 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -33,7 +33,7 @@ int cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_save_buffer_entry = {
"save-buffer", "saveb",
"[-a] " CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, CMD_CHFLAG('a'),
CMD_ARG1, "a",
cmd_buffer_init,
cmd_buffer_parse,
cmd_save_buffer_exec,
@@ -66,10 +66,11 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
mask = umask(S_IRWXG | S_IRWXO);
if (data->chflags & CMD_CHFLAG('a'))
if (cmd_check_flag(data->chflags, 'a'))
f = fopen(data->arg, "ab");
else
f = fopen(data->arg, "wb");
umask(mask);
if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
@@ -82,7 +83,6 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
fclose(f);
umask(mask);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-layout.c,v 1.8 2009-07-28 23:04:29 tcunha Exp $ */
/* $Id: cmd-select-layout.c,v 1.10 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
CMD_TARGET_WINDOW_USAGE " [layout-name]",
CMD_ARG01, 0,
CMD_ARG01, "",
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
@@ -52,7 +52,7 @@ cmd_select_layout_init(struct cmd *self, int key)
break;
case ('2' | KEYC_ESCAPE):
data->arg = xstrdup("even-vertical");
break;
break;
case ('3' | KEYC_ESCAPE):
data->arg = xstrdup("main-horizontal");
break;
@@ -80,7 +80,7 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "unknown layout or ambiguous: %s", data->arg);
return (-1);
}
layout = layout_set_select(wl->window, layout);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-pane.c,v 1.10 2009-07-30 20:45:20 tcunha Exp $ */
/* $Id: cmd-select-pane.c,v 1.12 2010-01-05 23:52:37 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
CMD_TARGET_PANE_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_select_pane_exec,
@@ -53,6 +53,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
window_set_active_pane(wl->window, wp);
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-prompt.c,v 1.12 2009-08-16 19:29:24 tcunha Exp $ */
/* $Id: cmd-select-prompt.c,v 1.13 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ int cmd_select_prompt_callback(void *, const char *);
const struct cmd_entry cmd_select_prompt_entry = {
"select-prompt", NULL,
CMD_TARGET_CLIENT_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_select_prompt_exec,

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-keys.c,v 1.21 2009-08-20 11:37:46 tcunha Exp $ */
/* $Id: cmd-send-keys.c,v 1.24 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,15 +33,14 @@ size_t cmd_send_keys_print(struct cmd *, char *, size_t);
struct cmd_send_keys_data {
char *target;
int idx;
u_int nkeys;
u_int nkeys;
int *keys;
};
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"[-t target-pane] key ...",
0, 0,
0, "",
NULL,
cmd_send_keys_parse,
cmd_send_keys_exec,
@@ -58,7 +57,6 @@ cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause)
self->data = data = xmalloc(sizeof *data);
data->target = NULL;
data->idx = -1;
data->nkeys = 0;
data->keys = NULL;
@@ -143,8 +141,6 @@ cmd_send_keys_print(struct cmd *self, char *buf, size_t len)
return (off);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->idx != -1)
off += xsnprintf(buf + off, len - off, " -i %d", data->idx);
for (i = 0; i < data->nkeys; i++) {
if (off >= len)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-prefix.c,v 1.26 2009-08-20 11:37:46 tcunha Exp $ */
/* $Id: cmd-send-prefix.c,v 1.28 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
CMD_TARGET_PANE_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_send_prefix_exec,
@@ -43,13 +43,13 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct window_pane *wp;
int key;
struct keylist *keylist;
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
return (-1);
key = options_get_number(&s->options, "prefix");
window_pane_key(wp, ctx->curclient, key);
keylist = options_get_data(&s->options, "prefix");
window_pane_key(wp, ctx->curclient, ARRAY_FIRST(keylist));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.28 2009-09-07 23:59:19 tcunha Exp $ */
/* $Id: cmd-server-info.c,v 1.37 2009-12-10 16:59:02 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,7 +35,7 @@ int cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
"",
0, 0,
0, "",
NULL,
NULL,
cmd_server_info_exec,
@@ -43,6 +43,7 @@ const struct cmd_entry cmd_server_info_entry = {
NULL
};
/* ARGSUSED */
int
cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
@@ -55,6 +56,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct tty_code *code;
struct tty_term_code_entry *ent;
struct utsname un;
struct job *job;
struct grid *gd;
struct grid_line *gl;
u_int i, j, k;
@@ -68,11 +70,10 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
*strchr(tim, '\n') = '\0';
ctx->print(ctx,
"tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(ctx, "socket path %s, debug level %d%s%s",
socket_path, debug_level, be_quiet ? ", quiet" : "",
login_shell ? ", login shell" : "");
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
ctx->print(
ctx, "socket path %s, debug level %d", socket_path, debug_level);
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine);
}
if (cfg_file != NULL)
@@ -93,19 +94,19 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x, references=%u]", i, c->tty.path,
c->ibuf.fd, c->tty.fd, c->session->name,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags,
c->tty.flags, c->references);
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Sessions: [%zu/%zu]",
ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8));
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
t = s->tv.tv_sec;
t = s->creation_time.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
@@ -147,7 +148,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Terminals:");
ctx->print(ctx, "Terminals:");
SLIST_FOREACH(term, &tty_terms, entry) {
ctx->print(ctx, "%s [references=%u, flags=0x%x]:",
term->name, term->references, term->flags);
@@ -179,5 +180,11 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Jobs:");
SLIST_FOREACH(job, &all_jobs, lentry) {
ctx->print(ctx, "%s [fd=%d, pid=%d, status=%d, flags=0x%x]",
job->cmd, job->fd, job->pid, job->status, job->flags);
}
return (0);
}

View File

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

View File

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

View File

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

View File

@@ -1,145 +0,0 @@
/* $Id: cmd-set-password.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include "tmux.h"
/*
* Set server password.
*/
int cmd_set_password_parse(struct cmd *, int, char **, char **);
int cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_password_free(struct cmd *);
void cmd_set_password_init(struct cmd *, int);
size_t cmd_set_password_print(struct cmd *, char *, size_t);
struct cmd_set_password_data {
char *password;
int flag_encrypted;
};
const struct cmd_entry cmd_set_password_entry = {
"set-password", "pass",
"[-c] password",
0, 0,
cmd_set_password_init,
cmd_set_password_parse,
cmd_set_password_exec,
cmd_set_password_free,
cmd_set_password_print
};
void
cmd_set_password_init(struct cmd *self, unused int arg)
{
struct cmd_set_password_data *data;
self->data = data = xmalloc(sizeof *data);
data->password = NULL;
data->flag_encrypted = 0;
}
int
cmd_set_password_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_set_password_data *data;
int opt;
char *out;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "c")) != -1) {
switch (opt) {
case 'c':
data->flag_encrypted = 1;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 1)
goto usage;
if (!data->flag_encrypted) {
if ((out = crypt(argv[0], "$1")) != NULL)
data->password = xstrdup(out);
} else
data->password = xstrdup(argv[0]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_set_password_data *data = self->data;
if (data->password == NULL) {
ctx->error(ctx, "failed to encrypt password");
return (-1);
}
if (server_password != NULL)
xfree(server_password);
if (*data->password == '\0')
server_password = NULL;
else
server_password = xstrdup(data->password);
return (0);
}
void
cmd_set_password_free(struct cmd *self)
{
struct cmd_set_password_data *data = self->data;
if (data->password != NULL)
xfree(data->password);
xfree(data);
}
size_t
cmd_set_password_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_set_password_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_encrypted)
off += xsnprintf(buf + off, len - off, " -c");
if (off < len && data->password != NULL)
off += xsnprintf(buf + off, len - off, " password");
return (off);
}

View File

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

View File

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

View File

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

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

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.16 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-show-options.c,v 1.21 2009-12-10 16:59:02 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,8 +31,8 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_options_entry = {
"show-options", "show",
"[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'),
"[-gsw] [-t target-session|target-window]",
0, "gsw",
cmd_target_init,
cmd_target_parse,
cmd_show_options_exec,
@@ -44,61 +44,44 @@ int
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
char *vs;
long long vn;
const char *optval;
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_s_options;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
oo = &s->options;
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
table = set_option_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
}
for (entry = set_option_table; entry->name != NULL; entry++) {
if (options_find1(oo, entry->name) == NULL)
for (entry = table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
continue;
switch (entry->type) {
case SET_OPTION_STRING:
vs = options_get_string(oo, entry->name);
ctx->print(ctx, "%s \"%s\"", entry->name, vs);
break;
case SET_OPTION_NUMBER:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %lld", entry->name, vn);
break;
case SET_OPTION_KEY:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, key_string_lookup_key(vn));
break;
case SET_OPTION_COLOUR:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, colour_tostring(vn));
break;
case SET_OPTION_ATTRIBUTES:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, attributes_tostring(vn));
break;
case SET_OPTION_FLAG:
vn = options_get_number(oo, entry->name);
if (vn)
ctx->print(ctx, "%s on", entry->name);
else
ctx->print(ctx, "%s off", entry->name);
break;
case SET_OPTION_CHOICE:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, entry->choices[vn]);
break;
}
optval = cmd_set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-window-options.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-show-window-options.c,v 1.15 2009-12-04 22:11:23 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,7 +24,7 @@
#include "tmux.h"
/*
* Show window options.
* Show window options. This is an alias for show-options -w.
*/
int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
@@ -32,7 +32,7 @@ int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw",
"[-g] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('g'),
0, "g",
cmd_target_init,
cmd_target_parse,
cmd_show_window_options_exec,
@@ -44,62 +44,7 @@ int
cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct options *oo;
const struct set_option_entry *entry;
char *vs;
long long vn;
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_w_options;
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
for (entry = set_window_option_table; entry->name != NULL; entry++) {
if (options_find1(oo, entry->name) == NULL)
continue;
switch (entry->type) {
case SET_OPTION_STRING:
vs = options_get_string(oo, entry->name);
ctx->print(ctx, "%s \"%s\"", entry->name, vs);
break;
case SET_OPTION_NUMBER:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %lld", entry->name, vn);
break;
case SET_OPTION_KEY:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, key_string_lookup_key(vn));
break;
case SET_OPTION_COLOUR:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, colour_tostring(vn));
break;
case SET_OPTION_ATTRIBUTES:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, attributes_tostring(vn));
break;
case SET_OPTION_FLAG:
vn = options_get_number(oo, entry->name);
if (vn)
ctx->print(ctx, "%s on", entry->name);
else
ctx->print(ctx, "%s off", entry->name);
break;
case SET_OPTION_CHOICE:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, entry->choices[vn]);
break;
}
}
return (0);
cmd_set_flag(&data->chflags, 'w');
return (cmd_show_options_entry.exec(self, ctx));
}

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-split-window.c,v 1.27 2009-09-16 12:36:27 nicm Exp $ */
/* $Id: cmd-split-window.c,v 1.34 2010-01-08 16:31:35 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,8 +44,8 @@ struct cmd_split_window_data {
const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"[-dhv] [-p percentage|-l size] [-t target-window] [command]",
0, 0,
"[-dhv] [-p percentage|-l size] [-t target-pane] [command]",
0, "",
cmd_split_window_init,
cmd_split_window_parse,
cmd_split_window_exec,
@@ -69,7 +69,7 @@ cmd_split_window_init(struct cmd *self, int key)
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
break;
case '"':
data->flag_horizontal = 0;
break;
@@ -83,7 +83,7 @@ cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
int opt;
const char *errstr;
self->entry->init(self, 0);
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dhl:p:t:v")) != -1) {
@@ -148,15 +148,16 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct window_pane *wp, *new_wp = NULL;
struct environ env;
char *cmd, *cwd, *cause;
const char *shell;
u_int hlimit;
int size;
enum layout_type type;
struct layout_cell *lc;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
return (-1);
w = wl->window;
@@ -173,33 +174,39 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
else
cwd = ctx->cmdclient->cwd;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1)
size = (w->active->sy * data->percentage) / 100;
hlimit = options_get_number(&s->options, "history-limit");
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1) {
if (type == LAYOUT_TOPBOTTOM)
size = (wp->sy * data->percentage) / 100;
else
size = (wp->sx * data->percentage) / 100;
}
hlimit = options_get_number(&s->options, "history-limit");
shell = options_get_string(&s->options, "default-shell");
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
wp = window_add_pane(w, hlimit);
if (window_pane_spawn(wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
if (layout_split_pane(w->active, type, size, wp) != 0) {
if ((lc = layout_split_pane(wp, type, size)) == NULL) {
cause = xstrdup("pane too small");
goto error;
}
new_wp = window_add_pane(w, hlimit);
if (window_pane_spawn(
new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
layout_assign_pane(lc, new_wp);
server_redraw_window(w);
if (!data->flag_detached) {
window_set_active_pane(w, wp);
window_set_active_pane(w, new_wp);
session_select(s, wl->idx);
server_redraw_session(s);
} else
@@ -210,8 +217,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
error:
environ_free(&env);
if (wp != NULL)
window_remove_pane(w, wp);
if (new_wp != NULL)
window_remove_pane(w, new_wp);
ctx->error(ctx, "create pane failed: %s", cause);
xfree(cause);
return (-1);

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-window.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-swap-window.c,v 1.19 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw",
"[-d] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d'),
0, "d",
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_swap_window_exec,
@@ -44,6 +44,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *src, *dst;
struct session_group *sg_src, *sg_dst;
struct winlink *wl_src, *wl_dst;
struct window *w;
@@ -52,6 +53,14 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl_dst = cmd_find_window(ctx, data->dst, &dst)) == NULL)
return (-1);
sg_src = session_group_find(src);
sg_dst = session_group_find(dst);
if (src != dst &&
sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) {
ctx->error(ctx, "can't move window, sessions are grouped");
return (-1);
}
if (wl_dst->window == wl_src->window)
return (0);
@@ -59,14 +68,17 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl_dst->window = wl_src->window;
wl_src->window = w;
if (!(data->chflags & CMD_CHFLAG('d'))) {
if (!cmd_check_flag(data->chflags, 'd')) {
session_select(dst, wl_dst->idx);
if (src != dst)
session_select(src, wl_src->idx);
}
server_redraw_session(src);
if (src != dst)
server_redraw_session(dst);
session_group_synchronize_from(src);
server_redraw_session_group(src);
if (src != dst) {
session_group_synchronize_from(dst);
server_redraw_session_group(dst);
}
recalculate_sizes();
return (0);

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-up-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/* $Id: cmd-up-pane.c,v 1.14 2010-01-05 23:52:37 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_up_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_up_pane_entry = {
"up-pane", "upp",
CMD_TARGET_WINDOW_USAGE,
0, 0,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_up_pane_exec,
@@ -54,6 +54,7 @@ cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_LAST(&w->panes, window_panes);
} while (!window_pane_visible(w->active));
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

267
cmd.c
View File

@@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.115 2009-08-31 22:30:15 tcunha Exp $ */
/* $Id: cmd.c,v 1.137 2010-01-22 17:28:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,6 +30,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_attach_session_entry,
&cmd_bind_key_entry,
&cmd_break_pane_entry,
&cmd_capture_pane_entry,
&cmd_choose_client_entry,
&cmd_choose_session_entry,
&cmd_choose_window_entry,
@@ -47,6 +48,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_find_window_entry,
&cmd_has_session_entry,
&cmd_if_shell_entry,
&cmd_join_pane_entry,
&cmd_kill_pane_entry,
&cmd_kill_server_entry,
&cmd_kill_session_entry,
@@ -57,16 +59,20 @@ const struct cmd_entry *cmd_table[] = {
&cmd_list_clients_entry,
&cmd_list_commands_entry,
&cmd_list_keys_entry,
&cmd_list_panes_entry,
&cmd_list_sessions_entry,
&cmd_list_windows_entry,
&cmd_load_buffer_entry,
&cmd_lock_client_entry,
&cmd_lock_server_entry,
&cmd_lock_session_entry,
&cmd_move_window_entry,
&cmd_new_session_entry,
&cmd_new_window_entry,
&cmd_next_layout_entry,
&cmd_next_window_entry,
&cmd_paste_buffer_entry,
&cmd_pipe_pane_entry,
&cmd_previous_layout_entry,
&cmd_previous_window_entry,
&cmd_refresh_client_entry,
@@ -75,8 +81,8 @@ const struct cmd_entry *cmd_table[] = {
&cmd_resize_pane_entry,
&cmd_respawn_window_entry,
&cmd_rotate_window_entry,
&cmd_run_shell_entry,
&cmd_save_buffer_entry,
&cmd_scroll_mode_entry,
&cmd_select_layout_entry,
&cmd_select_pane_entry,
&cmd_select_prompt_entry,
@@ -87,10 +93,10 @@ const struct cmd_entry *cmd_table[] = {
&cmd_set_buffer_entry,
&cmd_set_environment_entry,
&cmd_set_option_entry,
&cmd_set_password_entry,
&cmd_set_window_option_entry,
&cmd_show_buffer_entry,
&cmd_show_environment_entry,
&cmd_show_messages_entry,
&cmd_show_options_entry,
&cmd_show_window_options_entry,
&cmd_source_file_entry,
@@ -106,7 +112,8 @@ const struct cmd_entry *cmd_table[] = {
NULL
};
struct session *cmd_newest_session(struct sessions *);
struct session *cmd_choose_session(struct sessions *);
struct client *cmd_choose_client(struct clients *);
struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(const char *, int *);
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
@@ -162,7 +169,7 @@ cmd_free_argv(int argc, char **argv)
int i;
if (argc == 0)
return;
return;
for (i = 0; i < argc; i++) {
if (argv[i] != NULL)
xfree(argv[i]);
@@ -174,7 +181,7 @@ struct cmd *
cmd_parse(int argc, char **argv, char **cause)
{
const struct cmd_entry **entryp, *entry;
struct cmd *cmd;
struct cmd *cmd;
char s[BUFSIZ];
int opt, ambiguous = 0;
@@ -258,10 +265,6 @@ usage:
int
cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
{
if (server_locked) {
ctx->error(ctx, "server is locked");
return (-1);
}
return (cmd->entry->exec(cmd, ctx));
}
@@ -276,17 +279,17 @@ cmd_free(struct cmd *cmd)
size_t
cmd_print(struct cmd *cmd, char *buf, size_t len)
{
if (cmd->entry->print == NULL) {
if (cmd->entry->print == NULL)
return (xsnprintf(buf, len, "%s", cmd->entry->name));
}
return (cmd->entry->print(cmd, buf, len));
}
/*
* Figure out the current session. Use: 1) the current session, if the command
* context has one; 2) the session containing the pty of the calling client, if
* any 3) the session specified in the TMUX variable from the environment (as
* passed from the client); 3) the newest session.
* context has one; 2) the most recently used session containing the pty of the
* calling client, if any; 3) the session specified in the TMUX variable from
* the environment (as passed from the client); 4) the most recently used
* session from all sessions.
*/
struct session *
cmd_current_session(struct cmd_ctx *ctx)
@@ -328,7 +331,7 @@ cmd_current_session(struct cmd_ctx *ctx)
ARRAY_ADD(&ss, s);
}
s = cmd_newest_session(&ss);
s = cmd_choose_session(&ss);
ARRAY_FREE(&ss);
if (s != NULL)
return (s);
@@ -345,29 +348,92 @@ cmd_current_session(struct cmd_ctx *ctx)
return (s);
}
return (cmd_newest_session(&sessions));
return (cmd_choose_session(&sessions));
}
/* Find the newest session. */
/* Find the most recently used session from a list. */
struct session *
cmd_newest_session(struct sessions *ss)
cmd_choose_session(struct sessions *ss)
{
struct session *s, *snewest;
struct session *s, *sbest;
struct timeval *tv = NULL;
u_int i;
snewest = NULL;
sbest = NULL;
for (i = 0; i < ARRAY_LENGTH(ss); i++) {
if ((s = ARRAY_ITEM(ss, i)) == NULL)
continue;
if (tv == NULL || timercmp(&s->tv, tv, >)) {
snewest = s;
tv = &s->tv;
if (tv == NULL || timercmp(&s->activity_time, tv, >)) {
sbest = s;
tv = &s->activity_time;
}
}
return (snewest);
return (sbest);
}
/*
* Find the current client. First try the current client if set, then pick the
* most recently used of the clients attached to the current session if any,
* then of all clients.
*/
struct client *
cmd_current_client(struct cmd_ctx *ctx)
{
struct session *s;
struct client *c;
struct clients cc;
u_int i;
if (ctx->curclient != NULL)
return (ctx->curclient);
/*
* No current client set. Find the current session and return the
* newest of its clients.
*/
s = cmd_current_session(ctx);
if (s != NULL && !(s->flags & SESSION_UNATTACHED)) {
ARRAY_INIT(&cc);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
continue;
if (s == c->session)
ARRAY_ADD(&cc, c);
}
c = cmd_choose_client(&cc);
ARRAY_FREE(&cc);
if (c != NULL)
return (c);
}
return (cmd_choose_client(&clients));
}
/* Choose the most recently used client from a list. */
struct client *
cmd_choose_client(struct clients *cc)
{
struct client *c, *cbest;
struct timeval *tv = NULL;
u_int i;
cbest = NULL;
for (i = 0; i < ARRAY_LENGTH(cc); i++) {
if ((c = ARRAY_ITEM(cc, i)) == NULL)
continue;
if (c->session == NULL)
continue;
if (tv == NULL || timercmp(&c->activity_time, tv, >)) {
cbest = c;
tv = &c->activity_time;
}
}
return (cbest);
}
/* Find the target client or report an error and return NULL. */
@@ -380,7 +446,7 @@ cmd_find_client(struct cmd_ctx *ctx, const char *arg)
/* A NULL argument means the current client. */
if (arg == NULL)
return (ctx->curclient);
return (cmd_current_client(ctx));
tmparg = xstrdup(arg);
/* Trim a single trailing colon if any. */
@@ -411,7 +477,8 @@ cmd_lookup_client(const char *name)
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
path = c->tty.path;
@@ -439,19 +506,25 @@ cmd_lookup_session(const char *name, int *ambiguous)
*ambiguous = 0;
/*
* Look for matches. Session names must be unique so an exact match
* can't be ambigious and can just be returned.
* Look for matches. First look for exact matches - session names must
* be unique so an exact match can't be ambigious and can just be
* returned.
*/
sfound = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
/* Check for an exact match and return it if found. */
if (strcmp(name, s->name) == 0)
return (s);
/* Then check for pattern matches. */
}
/*
* Otherwise look for partial matches, returning early if it is found to
* be ambiguous.
*/
sfound = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
if (strncmp(name, s->name, strlen(name)) == 0 ||
fnmatch(name, s->name, 0) == 0) {
if (sfound != NULL) {
@@ -461,8 +534,7 @@ cmd_lookup_session(const char *name, int *ambiguous)
sfound = s;
}
}
return (sfound);
return (sfound);
}
/*
@@ -486,7 +558,7 @@ cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
if ((wl = winlink_find_by_index(&s->windows, idx)) != NULL)
return (wl);
}
/* Look for exact matches, error if more than one. */
wlfound = NULL;
RB_FOREACH(wl, winlinks, &s->windows) {
@@ -512,7 +584,7 @@ cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
}
wlfound = wl;
}
}
}
if (wlfound != NULL)
return (wlfound);
@@ -629,20 +701,40 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
/*
* Then work out the window. An empty string is the current window,
* otherwise try to look it up in the session.
* otherwise try special cases then to look it up in the session.
*/
if (*winptr == '\0')
wl = s->curw;
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL)
else if (winptr[0] == '!' && winptr[1] == '\0')
wl = TAILQ_FIRST(&s->lastw);
else if (winptr[0] == '+' && winptr[1] == '\0')
wl = winlink_next(s->curw);
else if (winptr[0] == '-' && winptr[1] == '\0')
wl = winlink_previous(s->curw);
else
wl = cmd_lookup_window(s, winptr, &ambiguous);
if (wl == NULL)
goto not_found;
if (sessptr != NULL)
xfree(sessptr);
return (wl);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) {
/*
* No colon in the string, first try special cases, then as a window
* and lastly as a session.
*/
if (arg[0] == '!' && arg[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
} else if (arg[0] == '+' && arg[1] == '\0') {
if ((wl = winlink_next(s->curw)) == NULL)
goto not_found;
} else if (arg[0] == '-' && arg[1] == '\0') {
if ((wl = winlink_previous(s->curw)) == NULL)
goto not_found;
} else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
@@ -684,6 +776,7 @@ int
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
{
struct session *s;
struct winlink *wl;
const char *winptr;
char *sessptr = NULL;
int idx, ambiguous = 0;
@@ -729,21 +822,48 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
* try to look it up in the session.
*/
if (*winptr == '\0')
idx = -1;
else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) {
idx = -1;
else if (winptr[0] == '!' && winptr[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
idx = wl->idx;
} else if (winptr[0] == '+' && winptr[1] == '\0') {
if (s->curw->idx == INT_MAX)
goto not_found;
idx = s->curw->idx + 1;
} else if (winptr[0] == '-' && winptr[1] == '\0') {
if (s->curw->idx == 0)
goto not_found;
idx = s->curw->idx - 1;
} else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
ctx->error(ctx, "invalid index: %s", arg);
idx = -2;
}
if (sessptr != NULL)
xfree(sessptr);
return (idx);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) {
/*
* No colon in the string, first try special cases, then as a window
* and lastly as a session.
*/
if (arg[0] == '!' && arg[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
idx = wl->idx;
} else if (arg[0] == '+' && arg[1] == '\0') {
if (s->curw->idx == INT_MAX)
goto not_found;
idx = s->curw->idx + 1;
} else if (arg[0] == '-' && arg[1] == '\0') {
if (s->curw->idx == 0)
goto not_found;
idx = s->curw->idx - 1;
} else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
@@ -758,7 +878,7 @@ no_colon:
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
ctx->error(ctx, "multiple sessions: %s", arg);
else
ctx->error(ctx, "session not found: %s", arg);
if (sessptr != NULL)
@@ -784,16 +904,16 @@ struct winlink *
cmd_find_pane(struct cmd_ctx *ctx,
const char *arg, struct session **sp, struct window_pane **wpp)
{
struct session *s;
struct winlink *wl;
const char *period;
char *winptr, *paneptr;
const char *errstr;
u_int idx;
struct session *s;
struct winlink *wl;
struct layout_cell *lc;
const char *period, *errstr;
char *winptr, *paneptr;
u_int idx;
/* Get the current session. */
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
ctx->error(ctx, "can't establish current session");
return (NULL);
}
if (sp != NULL)
@@ -823,20 +943,27 @@ cmd_find_pane(struct cmd_ctx *ctx,
*wpp = wl->window->active;
else {
idx = strtonum(paneptr, 0, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "pane %s: %s", errstr, paneptr);
goto error;
}
if (errstr != NULL)
goto lookup_string;
*wpp = window_pane_at_index(wl->window, idx);
if (*wpp == NULL) {
ctx->error(ctx, "no such pane: %u", idx);
goto error;
}
if (*wpp == NULL)
goto lookup_string;
}
xfree(winptr);
return (wl);
lookup_string:
/* Try pane string description. */
if ((lc = layout_find_string(s->curw->window, paneptr)) == NULL) {
ctx->error(ctx, "can't find pane: %s", paneptr);
goto error;
}
*wpp = lc->wp;
xfree(winptr);
return (s->curw);
no_period:
/* Try as a pane number alone. */
idx = strtonum(arg, 0, INT_MAX, &errstr);
@@ -846,15 +973,21 @@ no_period:
/* Try index in the current session and window. */
if ((*wpp = window_pane_at_index(s->curw->window, idx)) == NULL)
goto lookup_window;
return (s->curw);
lookup_window:
/* Try pane string description. */
if ((lc = layout_find_string(s->curw->window, arg)) != NULL) {
*wpp = lc->wp;
return (s->curw);
}
/* Try as a window and use the active pane. */
if ((wl = cmd_find_window(ctx, arg, sp)) != NULL)
*wpp = wl->window->active;
return (wl);
error:
xfree(winptr);
return (NULL);

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