summaryrefslogtreecommitdiffstats
authorRaghavendra D Prabhu <[email protected]>2011-01-23 11:59:16 (GMT)
committer Raghavendra D Prabhu <[email protected]>2011-01-23 11:59:16 (GMT)
commit0426ab2b383afd38af7274759c3a8d017bc88f00 (patch) (side-by-side diff)
tree2cc4bf1da4062c9ef91f2e94a9625f2423f57102
parent4e4aed43dc2b40b36f1b31cd3af9f874b78fa454 (diff)
parentb67bfd382d3401de572bb3487b1af3382a9cbeda (diff)
downloadtmux-old-0426ab2b383afd38af7274759c3a8d017bc88f00.zip
tmux-old-0426ab2b383afd38af7274759c3a8d017bc88f00.tar.gz
tmux-old-0426ab2b383afd38af7274759c3a8d017bc88f00.tar.bz2
merged new changesmaster
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--.gitignore13
-rw-r--r--CHANGES43
-rw-r--r--FAQ165
-rw-r--r--Makefile84
-rw-r--r--Makefile.am243
-rw-r--r--NOTES28
-rw-r--r--TODO111
-rw-r--r--arguments.c221
-rw-r--r--attributes.obin0 -> 4208 bytes
-rwxr-xr-xautogen.sh16
-rw-r--r--cfg.c12
-rw-r--r--cfg.obin0 -> 4592 bytes
-rw-r--r--client.c352
-rw-r--r--client.obin0 -> 15440 bytes
-rw-r--r--clock.obin0 -> 3560 bytes
-rw-r--r--cmd-attach-session.c40
-rw-r--r--cmd-attach-session.obin0 -> 4008 bytes
-rw-r--r--cmd-bind-key.c181
-rw-r--r--cmd-bind-key.obin0 -> 5656 bytes
-rw-r--r--cmd-break-pane.c21
-rw-r--r--cmd-break-pane.obin0 -> 3688 bytes
-rw-r--r--cmd-capture-pane.c44
-rw-r--r--cmd-capture-pane.obin0 -> 3384 bytes
-rw-r--r--cmd-choose-buffer.c31
-rw-r--r--cmd-choose-buffer.obin0 -> 4808 bytes
-rw-r--r--cmd-choose-client.c21
-rw-r--r--cmd-choose-client.obin0 -> 4800 bytes
-rw-r--r--cmd-choose-session.c38
-rw-r--r--cmd-choose-session.obin0 -> 5192 bytes
-rw-r--r--cmd-choose-window.c51
-rw-r--r--cmd-choose-window.obin0 -> 5440 bytes
-rw-r--r--cmd-clear-history.c17
-rw-r--r--cmd-clear-history.obin0 -> 2400 bytes
-rw-r--r--cmd-clock-mode.c17
-rw-r--r--cmd-clock-mode.obin0 -> 2400 bytes
-rw-r--r--cmd-command-prompt.c152
-rw-r--r--cmd-command-prompt.obin0 -> 7064 bytes
-rw-r--r--cmd-confirm-before.c37
-rw-r--r--cmd-confirm-before.obin0 -> 4632 bytes
-rw-r--r--cmd-copy-buffer.c205
-rw-r--r--cmd-copy-buffer.obin0 -> 5424 bytes
-rw-r--r--cmd-copy-mode.c36
-rw-r--r--cmd-copy-mode.obin0 -> 2992 bytes
-rw-r--r--cmd-delete-buffer.c37
-rw-r--r--cmd-delete-buffer.obin0 -> 2672 bytes
-rw-r--r--cmd-detach-client.c19
-rw-r--r--cmd-detach-client.obin0 -> 2368 bytes
-rw-r--r--cmd-display-message.c23
-rw-r--r--cmd-display-message.obin0 -> 2992 bytes
-rw-r--r--cmd-display-panes.c19
-rw-r--r--cmd-display-panes.obin0 -> 2336 bytes
-rw-r--r--cmd-find-window.c60
-rw-r--r--cmd-find-window.obin0 -> 6528 bytes
-rw-r--r--cmd-generic.c423
-rw-r--r--cmd-generic.obin0 -> 9976 bytes
-rw-r--r--cmd-has-session.c17
-rw-r--r--cmd-has-session.obin0 -> 2264 bytes
-rw-r--r--cmd-if-shell.c19
-rw-r--r--cmd-if-shell.obin0 -> 3360 bytes
-rw-r--r--cmd-join-pane.c200
-rw-r--r--cmd-join-pane.obin0 -> 7224 bytes
-rw-r--r--cmd-kill-pane.c19
-rw-r--r--cmd-kill-pane.obin0 -> 3000 bytes
-rw-r--r--cmd-kill-server.c9
-rw-r--r--cmd-kill-server.obin0 -> 1992 bytes
-rw-r--r--cmd-kill-session.c19
-rw-r--r--cmd-kill-session.obin0 -> 2384 bytes
-rw-r--r--cmd-kill-window.c19
-rw-r--r--cmd-kill-window.obin0 -> 2424 bytes
-rw-r--r--cmd-last-pane.obin0 -> 2440 bytes
-rw-r--r--cmd-last-window.c58
-rw-r--r--cmd-last-window.obin0 -> 2600 bytes
-rw-r--r--cmd-link-window.c31
-rw-r--r--cmd-link-window.obin0 -> 3000 bytes
-rw-r--r--cmd-list-buffers.c25
-rw-r--r--cmd-list-buffers.obin0 -> 2648 bytes
-rw-r--r--cmd-list-clients.c9
-rw-r--r--cmd-list-clients.obin0 -> 2288 bytes
-rw-r--r--cmd-list-commands.c9
-rw-r--r--cmd-list-commands.obin0 -> 2112 bytes
-rw-r--r--cmd-list-keys.c30
-rw-r--r--cmd-list-keys.obin0 -> 4712 bytes
-rw-r--r--cmd-list-panes.c22
-rw-r--r--cmd-list-panes.obin0 -> 2768 bytes
-rw-r--r--cmd-list-sessions.c20
-rw-r--r--cmd-list-sessions.obin0 -> 2992 bytes
-rw-r--r--cmd-list-windows.c29
-rw-r--r--cmd-list-windows.obin0 -> 2712 bytes
-rw-r--r--cmd-list.c22
-rw-r--r--cmd-list.obin0 -> 3320 bytes
-rw-r--r--cmd-load-buffer.c126
-rw-r--r--cmd-load-buffer.obin0 -> 5128 bytes
-rw-r--r--cmd-lock-client.obin0 -> 2392 bytes
-rw-r--r--cmd-lock-server.c45
-rw-r--r--cmd-lock-server.obin0 -> 2032 bytes
-rw-r--r--cmd-lock-session.obin0 -> 2400 bytes
-rw-r--r--cmd-move-window.c31
-rw-r--r--cmd-move-window.obin0 -> 3104 bytes
-rw-r--r--cmd-new-session.c211
-rw-r--r--cmd-new-session.obin0 -> 8672 bytes
-rw-r--r--cmd-new-window.c162
-rw-r--r--cmd-new-window.obin0 -> 6920 bytes
-rw-r--r--cmd-next-layout.c54
-rw-r--r--cmd-next-layout.obin0 -> 2504 bytes
-rw-r--r--cmd-next-window.c76
-rw-r--r--cmd-next-window.obin0 -> 2976 bytes
-rw-r--r--cmd-paste-buffer.c197
-rw-r--r--cmd-paste-buffer.obin0 -> 6704 bytes
-rw-r--r--cmd-pipe-pane.c34
-rw-r--r--cmd-pipe-pane.obin0 -> 5088 bytes
-rw-r--r--cmd-previous-layout.c54
-rw-r--r--cmd-previous-layout.obin0 -> 2520 bytes
-rw-r--r--cmd-previous-window.c76
-rw-r--r--cmd-previous-window.obin0 -> 2992 bytes
-rw-r--r--cmd-refresh-client.c19
-rw-r--r--cmd-refresh-client.obin0 -> 2344 bytes
-rw-r--r--cmd-rename-session.c29
-rw-r--r--cmd-rename-session.obin0 -> 2696 bytes
-rw-r--r--cmd-rename-window.c23
-rw-r--r--cmd-rename-window.obin0 -> 2672 bytes
-rw-r--r--cmd-resize-pane.c100
-rw-r--r--cmd-resize-pane.obin0 -> 3840 bytes
-rw-r--r--cmd-respawn-window.c27
-rw-r--r--cmd-respawn-window.obin0 -> 4272 bytes
-rw-r--r--cmd-rotate-window.c31
-rw-r--r--cmd-rotate-window.obin0 -> 3760 bytes
-rw-r--r--cmd-run-shell.c19
-rw-r--r--cmd-run-shell.obin0 -> 3864 bytes
-rw-r--r--cmd-save-buffer.c61
-rw-r--r--cmd-save-buffer.obin0 -> 3872 bytes
-rw-r--r--cmd-select-layout.c113
-rw-r--r--cmd-select-layout.obin0 -> 3864 bytes
-rw-r--r--cmd-select-pane.c72
-rw-r--r--cmd-select-pane.obin0 -> 3832 bytes
-rw-r--r--cmd-select-window.c112
-rw-r--r--cmd-select-window.obin0 -> 2808 bytes
-rw-r--r--cmd-send-keys.c126
-rw-r--r--cmd-send-keys.obin0 -> 4128 bytes
-rw-r--r--cmd-send-prefix.c17
-rw-r--r--cmd-send-prefix.obin0 -> 2456 bytes
-rw-r--r--cmd-server-info.c65
-rw-r--r--cmd-server-info.obin0 -> 6264 bytes
-rw-r--r--cmd-set-buffer.c48
-rw-r--r--cmd-set-buffer.obin0 -> 3040 bytes
-rw-r--r--cmd-set-environment.c48
-rw-r--r--cmd-set-environment.obin0 -> 3336 bytes
-rw-r--r--cmd-set-option.c589
-rw-r--r--cmd-set-option.obin0 -> 21112 bytes
-rw-r--r--cmd-set-window-option.c47
-rw-r--r--cmd-set-window-option.obin0 -> 2456 bytes
-rw-r--r--cmd-show-buffer.c44
-rw-r--r--cmd-show-buffer.obin0 -> 3240 bytes
-rw-r--r--cmd-show-environment.c25
-rw-r--r--cmd-show-environment.obin0 -> 2792 bytes
-rw-r--r--cmd-show-messages.c25
-rw-r--r--cmd-show-messages.obin0 -> 2568 bytes
-rw-r--r--cmd-show-options.c65
-rw-r--r--cmd-show-options.obin0 -> 3536 bytes
-rw-r--r--cmd-show-window-options.c50
-rw-r--r--cmd-show-window-options.obin0 -> 2392 bytes
-rw-r--r--cmd-source-file.c115
-rw-r--r--cmd-source-file.obin0 -> 3688 bytes
-rw-r--r--cmd-split-window.c218
-rw-r--r--cmd-split-window.obin0 -> 8104 bytes
-rw-r--r--cmd-start-server.c9
-rw-r--r--cmd-start-server.obin0 -> 1808 bytes
-rw-r--r--cmd-string.c32
-rw-r--r--cmd-string.obin0 -> 6192 bytes
-rw-r--r--cmd-suspend-client.c26
-rw-r--r--cmd-suspend-client.obin0 -> 2440 bytes
-rw-r--r--cmd-swap-pane.c46
-rw-r--r--cmd-swap-pane.obin0 -> 4232 bytes
-rw-r--r--cmd-swap-window.c24
-rw-r--r--cmd-swap-window.obin0 -> 3328 bytes
-rw-r--r--cmd-switch-client.c157
-rw-r--r--cmd-switch-client.obin0 -> 5128 bytes
-rw-r--r--cmd-unbind-key.c126
-rw-r--r--cmd-unbind-key.obin0 -> 4000 bytes
-rw-r--r--cmd-unlink-window.c19
-rw-r--r--cmd-unlink-window.obin0 -> 2904 bytes
-rw-r--r--cmd.c135
-rw-r--r--cmd.obin0 -> 24152 bytes
-rw-r--r--colour.c121
-rw-r--r--colour.obin0 -> 4616 bytes
-rw-r--r--compat.h58
-rw-r--r--compat/asprintf.c29
-rw-r--r--compat/closefrom.c111
-rw-r--r--compat/closefrom.obin0 -> 2384 bytes
-rw-r--r--compat/daemon.c4
-rw-r--r--compat/fgetln.obin0 -> 2464 bytes
-rw-r--r--compat/forkpty-aix.c6
-rw-r--r--compat/forkpty-hpux.c89
-rw-r--r--compat/forkpty-sunos.c4
-rw-r--r--compat/getopt.obin0 -> 3576 bytes
-rw-r--r--compat/imsg-buffer.obin0 -> 5512 bytes
-rw-r--r--compat/imsg.c4
-rw-r--r--compat/imsg.obin0 -> 5440 bytes
-rw-r--r--compat/strlcat.obin0 -> 1520 bytes
-rw-r--r--compat/strlcpy.obin0 -> 1320 bytes
-rw-r--r--compat/strsep.c4
-rw-r--r--compat/strtonum.obin0 -> 2056 bytes
-rw-r--r--compat/unvis.c32
-rw-r--r--compat/unvis.obin0 -> 6624 bytes
-rw-r--r--compat/vis.c4
-rw-r--r--compat/vis.obin0 -> 4880 bytes
-rwxr-xr-xconfigure297
-rw-r--r--configure.ac423
-rw-r--r--environ.obin0 -> 8704 bytes
-rw-r--r--grid-utf8.obin0 -> 2944 bytes
-rw-r--r--grid-view.obin0 -> 4768 bytes
-rw-r--r--grid.obin0 -> 9304 bytes
-rw-r--r--input-keys.c38
-rw-r--r--input-keys.obin0 -> 7424 bytes
-rw-r--r--input.c37
-rw-r--r--input.obin0 -> 34248 bytes
-rw-r--r--job.c13
-rw-r--r--job.obin0 -> 9416 bytes
-rw-r--r--key-bindings.c11
-rw-r--r--key-bindings.obin0 -> 12104 bytes
-rw-r--r--key-string.c12
-rw-r--r--key-string.obin0 -> 5768 bytes
-rw-r--r--layout-custom.obin0 -> 5184 bytes
-rw-r--r--layout-set.c115
-rw-r--r--layout-set.obin0 -> 11032 bytes
-rw-r--r--layout-string.obin0 -> 3584 bytes
-rw-r--r--layout.obin0 -> 9432 bytes
-rw-r--r--log.obin0 -> 6176 bytes
-rw-r--r--mode-key.c12
-rw-r--r--mode-key.obin0 -> 11688 bytes
-rw-r--r--names.obin0 -> 3728 bytes
-rw-r--r--options-table.c643
-rw-r--r--options.obin0 -> 7648 bytes
-rw-r--r--osdep-aix.c (renamed from cmd-lock-session.c)42
-rw-r--r--osdep-darwin.c20
-rw-r--r--osdep-freebsd.c15
-rw-r--r--osdep-hpux.c (renamed from cmd-lock-client.c)40
-rw-r--r--osdep-linux.c19
-rw-r--r--osdep-linux.obin0 -> 2120 bytes
-rw-r--r--osdep-netbsd.c10
-rw-r--r--osdep-openbsd.c12
-rw-r--r--osdep-sunos.c9
-rw-r--r--osdep-unknown.c10
-rw-r--r--paste.c15
-rw-r--r--paste.obin0 -> 4512 bytes
-rw-r--r--resize.c18
-rw-r--r--resize.obin0 -> 3664 bytes
-rw-r--r--screen-redraw.obin0 -> 7416 bytes
-rw-r--r--screen-write.c29
-rw-r--r--screen-write.obin0 -> 19176 bytes
-rw-r--r--screen.c6
-rw-r--r--screen.obin0 -> 5456 bytes
-rw-r--r--server-client.c80
-rw-r--r--server-client.obin0 -> 24968 bytes
-rw-r--r--server-fn.c54
-rw-r--r--server-fn.obin0 -> 12240 bytes
-rw-r--r--server-window.c62
-rw-r--r--server-window.obin0 -> 5464 bytes
-rw-r--r--server.c120
-rw-r--r--server.obin0 -> 16160 bytes
-rw-r--r--session.c127
-rw-r--r--session.obin0 -> 14832 bytes
-rw-r--r--signal.obin0 -> 4408 bytes
-rw-r--r--status.c134
-rw-r--r--status.obin0 -> 29120 bytes
-rwxr-xr-xtmuxbin0 -> 330664 bytes
-rw-r--r--tmux.1279
-rw-r--r--tmux.c446
-rw-r--r--tmux.h275
-rw-r--r--tmux.obin0 -> 23920 bytes
-rw-r--r--tools/check-compat.sh5
-rw-r--r--tools/dist.mk33
-rw-r--r--tools/fuzz.c31
-rw-r--r--tty-acs.obin0 -> 3352 bytes
-rw-r--r--tty-keys.c70
-rw-r--r--tty-keys.obin0 -> 14096 bytes
-rw-r--r--tty-term.c39
-rw-r--r--tty-term.obin0 -> 14776 bytes
-rw-r--r--tty.c37
-rw-r--r--tty.obin0 -> 28856 bytes
-rw-r--r--utf8.c15
-rw-r--r--utf8.obin0 -> 8680 bytes
-rw-r--r--window-choose.c4
-rw-r--r--window-choose.obin0 -> 10352 bytes
-rw-r--r--window-clock.obin0 -> 3792 bytes
-rw-r--r--window-copy.c30
-rw-r--r--window-copy.obin0 -> 33440 bytes
-rw-r--r--window.c65
-rw-r--r--window.obin0 -> 23664 bytes
-rw-r--r--www/index.html.in6
-rw-r--r--xmalloc.obin0 -> 5280 bytes
-rw-r--r--xterm-keys.c20
-rw-r--r--xterm-keys.obin0 -> 4304 bytes
292 files changed, 5593 insertions, 5696 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..93fef5b
--- a/dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache/
+config.log
+config.status
+configure
+etc/
+tags
+*.patch
+tree-notes
+.deps
+*.sw*
diff --git a/CHANGES b/CHANGES
index 9223813..c0965b6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,44 @@
+CHANGES FROM 1.3 TO 1.4, 27 December 2010
+
+* Window bell reporting fixed.
+* Show which pane is active in the list-panes output.
+* Backoff reworked.
+* Prevent the server from dying when switching into copy mode when already
+ in a different mode.
+* Reset running jobs when the status line is enabled or disabled.
+* Simplify xterm modifier detection.
+* Avoid crashing in copy mode if the screen size is too small for the
+ indicator.
+* Flags -n and -p added to switch-client.
+* Use UTF-8 line drawing characters on UTF-8 terminals, thus fixing some
+ terminals (eg putty) which disable the vt100 ACS mode switching sequences
+ in UTF-8 mode. On terminals without ACS, use ASCII equivalents.
+* New server option exit-unattached added.
+* New session option destroy-unattached added.
+* Fall back on normal session choice method if $TMUX exists but is invalid
+ rather than rejecting.
+* Mark repeating keys with "(repeat)" in the key list.
+* When removing a pane, don't change the active pane unless the active pane
+ is actually the one being removed.
+* New command last-pane added.
+* AIX fixes.
+* Flag -a added to unbind-key.
+* Add XAUTHORITY to update-environment.
+* More info regarding window and pane flags is now shown in list-*.
+* If VISUAL or EDITOR contains "vi" configure mode-keys and status-key to vi.
+* New window option monitor-silence and session option visual-silence added.
+* In the built-in layouts distribute the panes more evenly.
+* Set the default value of main-pane-width to 80 instead of 81.
+* Command-line flag -V added.
+* Instead of keeping a per-client prompt history make it global.
+* Fix rectangle copy to behave like emacs (the cursor is not part of the
+ selection on the right edge but on the left it is).
+* Flag -l added to switch-client.
+* Retrieve environment variables from the global environment rather than
+ getenv(3), thus allowing them to be updated during the configuration file.
+* New window options other-pane-{height,width} added.
+* More minor bugs fixed and manpage improvements.
+
CHANGES FROM 1.2 TO 1.3, 18 July 2010
* New input parser.
@@ -1513,7 +1554,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.303 2010/07/18 13:40:59 tcunha Exp $
+$Id: CHANGES,v 1.304 2010/12/27 21:37:42 tcunha Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms
diff --git a/FAQ b/FAQ
index f832080..829973d 100644
--- a/FAQ
+++ b/FAQ
@@ -12,29 +12,99 @@ tmux frequently asked questions
* and derivatives. *
******************************************************************************
-* How is tmux different from GNU screen? What else does it offer?
-
-tmux offers several advantages over screen:
-
-- a clearly-defined client-server model: windows are independent entities which
- may be attached simultaneously to multiple sessions and viewed from multiple
- clients (terminals), as well as moved freely between sessions within the same
- tmux server;
-- a consistent, well-documented command interface, with the same syntax
- whether used interactively, as a key binding, or from the shell;
-- easily scriptable from the shell;
-- multiple paste buffers;
-- choice of vi or emacs key layouts;
-- an option to limit the window size;
-- a more usable status line syntax, with the ability to display the first line
- of output of a specific command;
-- a cleaner, modern, easily extended, BSD-licensed codebase.
-
-There are still a few features screen includes that tmux omits:
-
-- builtin serial and telnet support; this is bloat and is unlikely to be added
- to tmux;
-- wider platform support, for example IRIX and HP-UX, and for odd terminals.
+* How is tmux different from GNU screen?
+
+tmux and GNU screen have many similarities. Some of the main differences I am
+aware of are (bearing in mind I haven't used screen for a few years now):
+
+- tmux uses a client-server model. Each server has single Unix domain socket in
+ /tmp and within one server there are multiple sessions which may be attached
+ to multiple clients (terminals).
+
+ This has advantages, notably: windows may be linked simultaneously to
+ multiple sessions; windows may be moved freely between sessions; and a client
+ may be switched between sessions easily (C-b D). There is one major
+ disadvantage: if the server crashes, game over, all sessions die. In
+ practice, however, tmux is quite stable and gets more so as people report any
+ bugs they hit :-).
+
+ This model is different from screen, where typically each new screen instance
+ is independent. tmux supports the same behaviour by using multiple servers
+ with the -L option but it is not typically recommended.
+
+- Different command interfaces. One of the goals of tmux is that the shell
+ should be easily usable as a scripting language - almost all tmux commands
+ can be used from the shell and behave identically whether used from the
+ shell, from a key binding or from the command prompt. Personally I also find
+ tmux's command interface much more consistent and clearer, but this is
+ subjective.
+
+- tmux calls window names (what you see in the status line) "names", screen
+ calls them "titles".
+
+- tmux has a multiple paste buffers. Not a major one but comes in handy quite a
+ lot.
+
+- tmux supports automatically renaming windows to the running application
+ without gross hacks using escape sequences. Its even on by default.
+
+- tmux has a choice of vi or emacs key layouts. Again, not major, but I use
+ emacs so if tmux did support only one key set it would be emacs and then all
+ the vi users would get humpy. Key bindings may be completely reconfigured in
+ any case.
+
+- tmux has an option to limit the window size.
+
+- tmux has search in windows (C-b f).
+
+- The window split (pane) model is different. tmux has two objects, windows and
+ panes; screen has just windows. This difference has several implications:
+
+ * In screen you can have a window appear in several layouts, in tmux a pane
+ can only be in one window (fixing this is a big todo item but quite
+ invasive).
+
+ * tmux layouts are immutable and do not get changed unless you modify them.
+
+ * In tmux, all panes are closed when you kill a window.
+
+ * tmux panes do not have individual names, titles and so on.
+
+ I think tmux's model is much easier to manage and navigate within a window,
+ but breaking panes off from and joining them to windows is more clumsy.
+
+ tmux also has support for preset pane layouts.
+
+- tmux's status line syntax is more readable and easier to use. I think it'd be
+ hard for anyone to argue with this. tmux doesn't support running a command
+ constantly and always using the last line of its output, commands must be run
+ again each time.
+
+- tmux has modern, easily extended code. Again hard to argue screen is better
+ if you have looked at the code.
+
+- tmux depends on libevent. I don't see this as a disadvantage: libevent is
+ small and portable, and on modern systems with current package management
+ systems dependencies are not an issue. libevent brings advantages in code
+ simplicity and performance.
+
+- screen allows the window to be bigger than the terminal and can pan around
+ it. tmux limits the size to the largest attached client. This is a big todo
+ item for tmux but it is not trivial.
+
+- screen has builtin serial and telnet support; this is bloat and is unlikely
+ to be added to tmux.
+
+- screen has support for updating utmp. Nobody has really come up with a clean,
+ portable way to do this without making tmux setuid or setgid yet.
+
+- Environment handling is different.
+
+- tmux tends to be more demanding on the terminal so tends to show up terminal
+ and application bugs which screen does not.
+
+- screen has wider platform support, for example IRIX and HP-UX, and for odd
+ terminals.
* I found a bug! What do I do?
@@ -167,6 +237,8 @@ the ctrl (bit 5 set, for example ^[[5~ to ^[[5^) modifier in non-xterm(1) mode;
it may be possible to configure vim to accept these, an example of how to do so
would be welcome.
+vim users may also want to set the "ttyfast" option inside tmux.
+
* Why doesn't elinks set the window title inside tmux?
There isn't a way to detect if a terminal supports setting the window title, so
@@ -254,5 +326,50 @@ In addition, it's possible to have both blanking and locking (for instance via
lock(1) or vlock(1)) by using the following:
bind x set lock-command '/usr/bin/vlock' \; lock-client \; set lock-command 'tput civis && read -s -n1'
+
+* How can I open a new window in the same directory as the current window?
+
+One option is to just run "TMUX= tmux" in the window. However, this only works if no
+command is running, so that you can input the command.
+
+A workaround is to let tmux know about the current path through an environment
+variable. To do so, use the following command:
+
+ [ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#I") $PWD
+
+Which sets TMUXPWD_i (where i is the number of the current window) to the path
+of the current directory. This command can be added to PS1, for example:
+
+ PS1='$([ -n "$TMUX" ] && tmux setenv TMUXPWD_$(tmux display -p "#I") $PWD)\h$ '
+
+When a new window is created, the shell should be asked to change
+directory. You can define a new binding (for example, if using GNU bash):
+
+ bind-key C-c run-shell 'tmux neww "cd $(tmux display -p "\$TMUXPWD_#I"); exec bash"'
+
+This solution will work even if a command is currently running in the terminal,
+but it will not work from a window that has just been swapped with another
+because TMUXPWD_i will not be updated after a swap. However, once a new prompt
+is displayed, TMUXPWD_i is updated properly.
+
+* tmux doesn't start with "daemon failed"
+
+tmux shows something similar to this when started:
+
+ fatal: server_start: daemon failed: No such file or directory
+ fatal: main_dispatch: imsg_read failed
+
+A possible reason is that /dev/null is not a character device or is otherwise
+inaccessible.
+
+Check with:
+
+ file /dev/null
+ ls -l /dev/null
+
+If it is not a character device or has incorrect permissions, it can typically
+be recreated with:
+
+ cd /dev && rm null && ./MAKEDEV null
-$Id: FAQ,v 1.37 2010/07/31 11:46:28 nicm Exp $
+$Id: FAQ,v 1.41 2010/12/15 23:31:30 nicm Exp $
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 50a572f..0000000
--- a/Makefile
+++ b/dev/null
@@ -1,84 +0,0 @@
-# $Id: Makefile,v 1.161 2010/07/18 14:53:27 tcunha Exp $
-#
-# Copyright (c) 2009 Nicholas Marriott <[email protected]>
-#
-# 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.4
-
-FDEBUG= 1
-
-CC?= cc
-CFLAGS+= -DBUILD="\"$(VERSION)\""
-LDFLAGS+= -L/usr/local/lib
-LIBS+=
-
-.ifdef FDEBUG
-CFLAGS+= -g -ggdb -DDEBUG
-CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
-CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
-CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
-CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
-.endif
-
-# This sort of sucks but gets rid of the stupid warning and should work on
-# most platforms...
-CCV!= (LC_ALL=C ${CC} -v 2>&1|awk '/gcc version 4|clang/') || true
-.if empty(CCV)
-CPPFLAGS:= -I. -I- -I/usr/local/include ${CPPFLAGS}
-.else
-CPPFLAGS:= -iquote. -I/usr/local/include ${CPPFLAGS}
-.ifdef FDEBUG
-CFLAGS+= -Wno-pointer-sign
-.endif
-.endif
-
-PREFIX?= /usr/local
-INSTALL?= install
-INSTALLDIR= ${INSTALL} -d
-INSTALLBIN= ${INSTALL} -m 555
-INSTALLMAN= ${INSTALL} -m 444
-
-SRCS!= echo *.c|LC_ALL=C sed 's|osdep-[a-z0-9]*.c||g'
-.include "config.mk"
-OBJS= ${SRCS:S/.c/.o/}
-
-.c.o:
- ${CC} ${CPPFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-
-all: tmux
-
-tmux: ${OBJS}
- ${CC} ${LDFLAGS} -o tmux ${OBJS} ${LIBS}
-
-depend:
- mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
-
-clean:
- rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
-
-clean-depend:
- rm -f .depend
-
-clean-all: clean clean-depend
- rm -f config.h config.mk
-
-install: all
- ${INSTALLDIR} ${DESTDIR}${PREFIX}/bin
- ${INSTALLBIN} tmux ${DESTDIR}${PREFIX}/bin/
- ${INSTALLDIR} ${DESTDIR}${PREFIX}/man/man1
- ${INSTALLMAN} tmux.1 ${DESTDIR}${PREFIX}/man/man1/
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..13e94eb
--- a/dev/null
+++ b/Makefile.am
@@ -0,0 +1,243 @@
+# $Id: Makefile.am,v 1.9 2011/01/21 20:35:20 nicm Exp $
+
+# Obvious program stuff.
+bin_PROGRAMS = tmux
+dist_man1_MANS = tmux.1
+
+# Distribution tarball options.
+EXTRA_DIST = \
+ CHANGES FAQ NOTES TODO examples compat \
+ array.h compat.h tmux.h osdep-*.c
+dist-hook:
+ grep "^#found_debug=" configure
+ find $(distdir) -name CVS -type d|xargs rm -Rf
+
+# Preprocessor flags.
+CPPFLAGS += @[email protected]
+
+# glibc as usual does things ass-backwards and hides useful things by default,
+# so everyone has to add this.
+if IS_GLIBC
+CFLAGS += -D_GNU_SOURCE
+endif
+
+# Set flags for gcc. gcc4 whines abouts silly stuff so it needs slightly
+# different flags.
+if IS_GCC
+CFLAGS += -std=c99
+if IS_DEBUG
+CFLAGS += -g -ggdb -O0
+CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
+CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
+CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
+CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align
+CPPFLAGS += -DDEBUG
+endif
+if IS_GCC4
+CPPFLAGS += -iquote. -I/usr/local/include
+if IS_DEBUG
+CFLAGS += -Wno-pointer-sign
+endif
+else
+CPPFLAGS += -I. -I- -I/usr/local/include
+endif
+endif
+
+# Set flags for static.
+if IS_STATIC
+LDFLAGS+= -static
+endif
+
+# Set flags for Solaris.
+if IS_SUNOS
+CPPFLAGS+= -D_XPG4_2 -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS
+endif
+
+# Set flags for Sun CC.
+if IS_SUNCC
+CFLAGS+= -erroff=E_EMPTY_DECLARATION
+endif
+
+# List of sources.
+dist_tmux_SOURCES = \
+ arguments.c \
+ attributes.c \
+ cfg.c \
+ client.c \
+ clock.c \
+ cmd-attach-session.c \
+ cmd-bind-key.c \
+ cmd-break-pane.c \
+ cmd-capture-pane.c \
+ cmd-choose-buffer.c \
+ cmd-choose-client.c \
+ cmd-choose-session.c \
+ cmd-choose-window.c \
+ cmd-clear-history.c \
+ cmd-clock-mode.c \
+ cmd-command-prompt.c \
+ cmd-confirm-before.c \
+ cmd-copy-mode.c \
+ cmd-delete-buffer.c \
+ cmd-detach-client.c \
+ cmd-display-message.c \
+ cmd-display-panes.c \
+ cmd-find-window.c \
+ cmd-has-session.c \
+ cmd-if-shell.c \
+ cmd-join-pane.c \
+ cmd-kill-pane.c \
+ cmd-kill-server.c \
+ cmd-kill-session.c \
+ cmd-kill-window.c \
+ cmd-link-window.c \
+ cmd-list-buffers.c \
+ cmd-list-clients.c \
+ cmd-list-commands.c \
+ cmd-list-keys.c \
+ cmd-list-panes.c \
+ cmd-list-sessions.c \
+ cmd-list-windows.c \
+ cmd-list.c \
+ cmd-load-buffer.c \
+ cmd-lock-server.c \
+ cmd-move-window.c \
+ cmd-new-session.c \
+ cmd-new-window.c \
+ cmd-paste-buffer.c \
+ cmd-pipe-pane.c \
+ cmd-refresh-client.c \
+ cmd-rename-session.c \
+ cmd-rename-window.c \
+ cmd-resize-pane.c \
+ cmd-respawn-window.c \
+ cmd-rotate-window.c \
+ cmd-run-shell.c \
+ cmd-save-buffer.c \
+ cmd-select-layout.c \
+ cmd-select-pane.c \
+ cmd-select-window.c \
+ cmd-send-keys.c \
+ cmd-send-prefix.c \
+ cmd-server-info.c \
+ cmd-set-buffer.c \
+ cmd-set-environment.c \
+ cmd-set-option.c \
+ cmd-show-buffer.c \
+ cmd-show-environment.c \
+ cmd-show-messages.c \
+ cmd-show-options.c \
+ cmd-source-file.c \
+ cmd-split-window.c \
+ cmd-start-server.c \
+ cmd-string.c \
+ cmd-suspend-client.c \
+ cmd-swap-pane.c \
+ cmd-swap-window.c \
+ cmd-switch-client.c \
+ cmd-unbind-key.c \
+ cmd-unlink-window.c \
+ cmd.c \
+ colour.c \
+ environ.c \
+ grid-utf8.c \
+ grid-view.c \
+ grid.c \
+ input-keys.c \
+ input.c \
+ job.c \
+ key-bindings.c \
+ key-string.c \
+ layout-custom.c \
+ layout-set.c \
+ layout-string.c \
+ layout.c \
+ log.c \
+ mode-key.c \
+ names.c \
+ options-table.c \
+ options.c \
+ paste.c \
+ resize.c \
+ screen-redraw.c \
+ screen-write.c \
+ screen.c \
+ server-client.c \
+ server-fn.c \
+ server-window.c \
+ server.c \
+ session.c \
+ signal.c \
+ status.c \
+ tmux.c \
+ tty-acs.c \
+ tty-keys.c \
+ tty-term.c \
+ tty.c \
+ utf8.c \
+ window-choose.c \
+ window-clock.c \
+ window-copy.c \
+ window.c \
+ xmalloc.c \
+ xterm-keys.c
+nodist_tmux_SOURCES = [email protected]@.c
+
+# Pile in all the compat/ stuff that is needed.
+if NO_FORKPTY
+nodist_tmux_SOURCES += compat/[email protected]@.c
+endif
+if NO_IMSG
+nodist_tmux_SOURCES += compat/imsg.c compat/imsg-buffer.c
+endif
+if NO_CLOSEFROM
+nodist_tmux_SOURCES += compat/closefrom.c
+endif
+if NO_DAEMON
+nodist_tmux_SOURCES += compat/daemon.c
+endif
+if NO_SETENV
+nodist_tmux_SOURCES += compat/setenv.c
+endif
+if NO_STRLCAT
+nodist_tmux_SOURCES += compat/strlcat.c
+endif
+if NO_STRLCPY
+nodist_tmux_SOURCES += compat/strlcpy.c
+endif
+if NO_ASPRINTF
+nodist_tmux_SOURCES += compat/asprintf.c
+endif
+if NO_FGETLN
+nodist_tmux_SOURCES += compat/fgetln.c
+endif
+if NO_GETOPT
+nodist_tmux_SOURCES += compat/getopt.c
+endif
+if NO_STRCASESTR
+nodist_tmux_SOURCES += compat/strcasestr.c
+endif
+if NO_STRSEP
+nodist_tmux_SOURCES += compat/strsep.c
+endif
+if NO_VIS
+nodist_tmux_SOURCES += compat/vis.c compat/unvis.c
+endif
+if NO_STRTONUM
+nodist_tmux_SOURCES += compat/strtonum.c
+endif
+
+# Update SF web site.
+upload-index.html: update-index.html
+ scp www/index.html www/main.css www/images/*.png \
+ ${USER},[email protected]:/home/groups/t/tm/tmux/htdocs
+ rm -f www/index.html www/images/small-*
+
+update-index.html:
+ (cd www/images && \
+ rm -f small-* && \
+ for i in *.png; do \
+ convert "$$i" -resize 200x150 "small-$$i"; \
+ done \
+ )
+ sed "s/%%VERSION%%/${VERSION}/g" www/index.html.in >www/index.html
diff --git a/NOTES b/NOTES
index c2eb16d..03b828d 100644
--- a/NOTES
+++ b/NOTES
@@ -9,8 +9,7 @@ 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.
-Since the 1.2 release that tmux depends on libevent. Download the stable
-version from:
+Since the 1.2 release that tmux depends on libevent. Download it from:
http://www.monkey.org/~provos/libevent/
@@ -25,34 +24,11 @@ windows into several simultaneously displayed panes; and to bind and unbind
command keys (invoked preceded by a prefix key, by default ctrl-b). Please see
the tmux(1) man page for further information.
-The following is a summary of major features implemented in this version:
-
-- Basic multiplexing, window switching, attaching and detaching.
-- Window listing and renaming.
-- Key binding.
-- Handling of client terminal resize.
-- Terminal emulation sufficient to handle most curses applications.
-- A optional status line (enabled by default).
-- Window history and copy and paste.
-- Support for VT100 line drawing characters.
-- A large command set.
-- Vertical window splitting and layout.
-- Automatic server locking on inactivity 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.
-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
-variables. list-clients may be used to check if this is detected correctly; if
-not, the -u command-line flag may be specified.
-
A Vim syntax file is available in the examples directory. To install it:
- Drop the file in the syntax directory in your runtimepath (such as
@@ -86,4 +62,4 @@ start. Please contact me with any queries.
-- Nicholas Marriott <[email protected]>
-$Id: NOTES,v 1.53 2010/03/10 15:18:11 tcunha Exp $
+$Id: NOTES,v 1.55 2011/01/03 23:58:10 tcunha Exp $
diff --git a/TODO b/TODO
index 7aec002..b93bd61 100644
--- a/TODO
+++ b/TODO
@@ -1,32 +1,21 @@
-- window creation/idle time
-- better errors when creating new windows/sessions (how?)
- implicitly add exec to the commands for new windows (switch to disable it)?
-- it would be nice to have multichar commands eg C-b K K
- commands:
extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session?
- allow fnmatch for -c, so that you can, eg, detach all clients
- garbage collect window history (100 lines at a time?) if it hasn't been used
- in $x time (need window creation/use times)
+ in $x time
- lift SHRT_MAX limits for history?
- 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
-- many more info() displays for various things
- use a better termcap internally instead of screen, perhaps xterm
-- fix rxvt cursor fg issue (text under cursor can have non-white fg)
- should be able to move to a hidden pane and it would be moved into view. pane
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
- 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
- capabilities
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- make command sequences more usable: don't require space after ;, handle
@@ -37,11 +26,7 @@
"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 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?
- warts on current naming:
- display-time but message-fg/bg/attr
@@ -49,46 +34,25 @@
- server-info
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-*
- split-window -> split-pane??
-- tidy up and prioritise todo list ;-)
-- neww and attach can create a session if none exists?
- would work fine with config file since
- a way for force-width/height to apply to only one pane (how?)
- command to list what is actually running in each window with command line,
pid (need some adaption of the osdep code)
- support for bce
-- it would be nice if the start/end line keys in copy mode were aware of
- wrapped lines
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
- -- idea of a "view" onto a window, need base x/y offsets
- for redraw
+ -- idea of a "view" onto a window, need base x/y offsets for redraw
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- commands should be able to succeed or fail and have || or && for command
lists
-- 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
- ...?
+- better utf8 support: window names, prompt input, message display
- session history for client and last-session command
- option to change status line colour when current window is in a mode?
- option to move copy mode indicator into status line
@@ -96,7 +60,6 @@
- selection behaviour closer to vi in vi mode
- live update: server started with -U connects to server, requests sessions and
windows, receives fds
-- convert status line history to be server global (anything else?)
- command to show a tree of sessions-windows-panes (active marked with *)
- sort out inheriting config from shell on new sessions/windows:
should pick up default-path/termios/etc from client if possible,
@@ -110,14 +73,11 @@
- 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
+- multiline status line (no?)
- flag for absolute pane size to resize-pane
- sanity check input to socket
-- select-buffer command
- support title stack, both internally and externally
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
-- copy buffers should be global, limit can be server option, nuke copy-buffer
- command
- command to show status line information briefly when it is off
- some way to pad # stuff with spaces, #!2T maybe
- FreeBSD console problems
@@ -128,28 +88,43 @@
- ' and " should be parsed the same (eg "\e" vs '\e') in config and command
prompt?
- command to toggle selection not to move it in copy-mode
-- some way to create transient sessions which die when disconnected (option?)
-
-For 1.4 (not in order):
-
-3 why are alerts per-winlink? try per window?
-4 audit of escape sequence support vs xterm
-5 support binding keys to mouse (mouse-select-pane -> mouse-keys or something,
+- why are alerts per-winlink? try per window?
+- audit of escape sequence support vs xterm
+- support binding keys to mouse (mouse-select-pane -> mouse-keys or something,
mouse click == select-pane -t %%, mouse scroll up == copy-mode)
-6 rectangle copy: when selecting leftward, cursor should be inside block per
- emacs key to rotate corner at which cursor is
-7 last-pane command ***
-9 something for -t "last window in session" so a session can be used as a stack
-10 synchronous commands - client sends cmd and blocks, neww/splitw saves client
- ptr then when program inside died, sends MSG_SOMETHING with wait status to
- client
-11 documentation improvements - rlpowell's tutorial
- - build instructions
-12 better configure? with-libevent
-14 bind commands to key sequences?
-16 monitor, bell etc should monitor /all/ panes in the window not just one
-18 a history of commands that can be reversed (reverse member of each command, and a buffer)
-19 info() when changing to same window
-20 don't pass UTF-8 through vis for titles
-21 clearing screen should push lines into history
-...
+- something for -t "last window in session" so a session can be used as a stack
+- synchronous commands - client sends cmd and blocks, neww/splitw saves client
+ ptr then when program inside died, sends MSG_SOMETHING with wait status to
+ client
+- documentation improvements - rlpowell's tutorial - build instructions
+- bind commands to key sequences?
+- monitor, bell etc should monitor /all/ panes in the window not just one
+- a history of commands that can be reversed (reverse member of each command,
+ and a buffer) info() when changing to same window
+- don't pass UTF-8 through vis for titles
+- clearing screen should push lines into history
+- add a unique ever-increasing pane id to each pane, export it in $TMUX_PANE
+ (as %1, %2 etc) and allow it to be used as a target
+- way to add dest for break-pane; maybe some easier way to unbreak-pane
+- case insensitive searching
+- dynamically generated jobs (eg "date ...") do not work well because
+ their entries are never collected, should either store status jobs in
+ a different tree or flush all unused persist jobs every update rather
+ than just updating them
+- pane-index option like base-index
+- option to move status line to top
+- respawn-pane command
+- configurable borders and empty space filler for when panes < window?
+- mouse-select-pane will screw up with !MODE_MOUSE_STANDARD (it sets the
+ flag on w/o checking the others before calling tty_update_mode)
+- 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
+- pass shell commands as argv rather than strings, allow them to be specified
+ in commands without quotes
+- combine all options into 1 table (inc defaults) - can use C99 .foo = blah
+ syntax
+- a command to choose from a generic list, so you can do eg
+ choose-list -l Abc,Moo,Blah "run-shell 'sh /my/choose/script %%'"
+- else part for if-shell
diff --git a/arguments.c b/arguments.c
new file mode 100644
index 0000000..41fd171
--- a/dev/null
+++ b/arguments.c
@@ -0,0 +1,221 @@
+/* $Id: arguments.c,v 1.2 2011/01/07 14:46:57 tcunha Exp $ */
+
+/*
+ * Copyright (c) 2010 Nicholas Marriott <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tmux.h"
+
+/* Create an arguments set with no flags. */
+struct args *
+args_create(int argc, ...)
+{
+ struct args *args;
+ va_list ap;
+ int i;
+
+ args = xcalloc(1, sizeof *args);
+ if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
+ fatal("bit_alloc failed");
+
+ args->argc = argc;
+ if (argc == 0)
+ args->argv = NULL;
+ else
+ args->argv = xcalloc(argc, sizeof **args->argv);
+
+ va_start(ap, argc);
+ for (i = 0; i < argc; i++)
+ args->argv[i] = xstrdup(va_arg(ap, char *));
+ va_end(ap);
+
+ return (args);
+}
+
+/* Parse an argv and argc into a new argument set. */
+struct args *
+args_parse(const char *template, int argc, char **argv)
+{
+ struct args *args;
+ char *ptr;
+ int opt;
+
+ args = xcalloc(1, sizeof *args);
+ if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)
+ fatal("bit_alloc failed");
+
+ optreset = 1;
+ optind = 1;
+
+ while ((opt = getopt(argc, argv, template)) != -1) {
+ if (opt < 0 || opt >= SCHAR_MAX)
+ continue;
+ if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
+ xfree(args->flags);
+ xfree(args);
+ return (NULL);
+ }
+
+ bit_set(args->flags, opt);
+ if (ptr[1] == ':') {
+ if (args->values[opt] != NULL)
+ xfree(args->values[opt]);
+ args->values[opt] = xstrdup(optarg);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ args->argc = argc;
+ args->argv = cmd_copy_argv(argc, argv);
+
+ return (args);
+}
+
+/* Free an arguments set. */
+void
+args_free(struct args *args)
+{
+ u_int i;
+
+ cmd_free_argv(args->argc, args->argv);
+
+ for (i = 0; i < SCHAR_MAX; i++) {
+ if (args->values[i] != NULL)
+ xfree(args->values[i]);
+ }
+
+ xfree(args->flags);
+ xfree(args);
+}
+
+/* Print a set of arguments. */
+size_t
+args_print(struct args *args, char *buf, size_t len)
+{
+ size_t off;
+ int i;
+ const char *quotes;
+
+ /* There must be at least one byte at the start. */
+ if (len == 0)
+ return (0);
+ off = 0;
+
+ /* Process the flags first. */
+ buf[off++] = '-';
+ for (i = 0; i < SCHAR_MAX; i++) {
+ if (!bit_test(args->flags, i) || args->values[i] != NULL)
+ continue;
+
+ if (off == len - 1) {
+ buf[off] = '\0';
+ return (len);
+ }
+ buf[off++] = i;
+ buf[off] = '\0';
+ }
+ if (off == 1)
+ buf[--off] = '\0';
+
+ /* Then the flags with arguments. */
+ for (i = 0; i < SCHAR_MAX; i++) {
+ if (!bit_test(args->flags, i) || args->values[i] == NULL)
+ continue;
+
+ if (off >= len) {
+ /* snprintf will have zero terminated. */
+ return (len);
+ }
+
+ if (strchr(args->values[i], ' ') != NULL)
+ quotes = "\"";
+ else
+ quotes = "";
+ off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
+ off != 0 ? " " : "", i, quotes, args->values[i], quotes);
+ }
+
+ /* And finally the argument vector. */
+ for (i = 0; i < args->argc; i++) {
+ if (off >= len) {
+ /* snprintf will have zero terminated. */
+ return (len);
+ }
+
+ if (strchr(args->argv[i], ' ') != NULL)
+ quotes = "\"";
+ else
+ quotes = "";
+ off += xsnprintf(buf + off, len - off, "%s%s%s%s",
+ off != 0 ? " " : "", quotes, args->argv[i], quotes);
+ }
+
+ return (off);
+}
+
+/* Return if an argument is present. */
+int
+args_has(struct args *args, u_char ch)
+{
+ return (bit_test(args->flags, ch));
+}
+
+/* Set argument value. */
+void
+args_set(struct args *args, u_char ch, const char *value)
+{
+ if (value != NULL) {
+ if (args->values[ch] != NULL)
+ xfree(args->values[ch]);
+ args->values[ch] = xstrdup(value);
+ }
+ bit_set(args->flags, ch);
+}
+
+/* Get argument value. Will be NULL if it isn't present. */
+const char *
+args_get(struct args *args, u_char ch)
+{
+ return (args->values[ch]);
+}
+
+/* Convert an argument value to a number. */
+long long
+args_strtonum(struct args *args,
+ u_char ch, long long minval, long long maxval, char **cause)
+{
+ const char *errstr;
+ long long ll;
+
+ if (!args_has(args, ch)) {
+ *cause = xstrdup("missing");
+ return (0);
+ }
+
+ ll = strtonum(args->values[ch], minval, maxval, &errstr);
+ if (errstr != NULL) {
+ *cause = xstrdup(errstr);
+ return (0);
+ }
+
+ *cause = NULL;
+ return (ll);
+}
diff --git a/attributes.o b/attributes.o
new file mode 100644
index 0000000..5ba769a
--- a/dev/null
+++ b/attributes.o
Binary files differ
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..ccbd767
--- a/dev/null
+++ b/autogen.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# $Id: autogen.sh,v 1.2 2010/12/31 22:13:48 nicm Exp $
+
+[ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.10
+[ -z "$AUTOCONF_VERSION" ] && export AUTOCONF_VERSION=2.65
+
+die()
+{
+ echo "[email protected]" >&2
+ exit 1
+}
+
+mkdir -p etc
+aclocal || die "aclocal failed"
+automake --add-missing --force-missing --copy --foreign || die "automake failed"
+autoreconf || die "autoreconf failed"
diff --git a/cfg.c b/cfg.c
index e272fd0..98eb2d6 100644
--- a/cfg.c
+++ b/cfg.c
@@ -1,4 +1,4 @@
-/* $Id: cfg.c,v 1.27 2010/06/06 00:04:18 tcunha Exp $ */
+/* $Id: cfg.c,v 1.28 2010/12/30 22:26:07 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -80,6 +80,7 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
size_t len;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
+ int retval;
if ((f = fopen(path, "rb")) == NULL) {
cfg_add_cause(causes, "%s: %s", path, strerror(errno));
@@ -88,6 +89,7 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
n = 0;
line = NULL;
+ retval = 0;
while ((buf = fgetln(f, &len))) {
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
@@ -125,19 +127,17 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
ctx.info = cfg_print;
cfg_cause = NULL;
- cmd_list_exec(cmdlist, &ctx);
+ if (cmd_list_exec(cmdlist, &ctx) == 1)
+ retval = 1;
cmd_list_free(cmdlist);
if (cfg_cause != NULL) {
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);
+ return (retval);
}
diff --git a/cfg.o b/cfg.o
new file mode 100644
index 0000000..ff0836c
--- a/dev/null
+++ b/cfg.o
Binary files differ
diff --git a/client.c b/client.c
index 91584c6..d11affd 100644
--- a/client.c
+++ b/client.c
@@ -1,4 +1,4 @@
-/* $Id: client.c,v 1.97 2010/08/29 14:44:55 tcunha Exp $ */
+/* $Id: client.c,v 1.101 2011/01/21 23:44:13 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,7 +28,6 @@
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include <unistd.h>
#include "tmux.h"
@@ -37,83 +36,170 @@ struct imsgbuf client_ibuf;
struct event client_event;
const char *client_exitmsg;
int client_exitval;
+int client_attached;
+int client_connect(char *, int);
void client_send_identify(int);
void client_send_environ(void);
void client_write_server(enum msgtype, void *, size_t);
void client_update_event(void);
void client_signal(int, short, void *);
void client_callback(int, short, void *);
-int client_dispatch(void);
+int client_dispatch_attached(void);
+int client_dispatch_wait(void *);
-struct imsgbuf *
-client_init(char *path, int cmdflags, int flags)
+/* Connect client to server. */
+int
+client_connect(char *path, int start_server)
{
struct sockaddr_un sa;
size_t size;
- int fd, mode;
-#ifdef HAVE_SETPROCTITLE
- char rpathbuf[MAXPATHLEN];
-#endif
-
-#ifdef HAVE_SETPROCTITLE
- if (realpath(path, rpathbuf) == NULL)
- strlcpy(rpathbuf, path, sizeof rpathbuf);
- setproctitle("client (%s)", rpathbuf);
-#endif
+ int fd;
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
if (size >= sizeof sa.sun_path) {
errno = ENAMETOOLONG;
- goto not_found;
+ return (-1);
}
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket failed");
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
- if (!(cmdflags & CMD_STARTSERVER))
- goto not_found;
+ if (!start_server)
+ goto failed;
switch (errno) {
case ECONNREFUSED:
if (unlink(path) != 0)
- goto not_found;
+ goto failed;
/* FALLTHROUGH */
case ENOENT:
- if ((fd = server_start(path)) == -1)
- goto start_failed;
- goto server_started;
+ if ((fd = server_start()) == -1)
+ goto failed;
+ break;
+ default:
+ goto failed;
}
- goto not_found;
}
-server_started:
- if ((mode = fcntl(fd, F_GETFL)) == -1)
- fatal("fcntl failed");
- if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
- fatal("fcntl failed");
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
+ setblocking(fd, 0);
+ return (fd);
+
+failed:
+ close(fd);
+ return (-1);
+}
+
+/* Client main loop. */
+int
+client_main(int argc, char **argv, int flags)
+{
+ struct cmd *cmd;
+ struct cmd_list *cmdlist;
+ struct msg_command_data cmddata;
+ int cmdflags, fd;
+ enum msgtype msg;
+ char *cause;
+
+ /* Set up the initial command. */
+ cmdflags = 0;
+ if (shell_cmd != NULL) {
+ msg = MSG_SHELL;
+ cmdflags = CMD_STARTSERVER;
+ } else if (argc == 0) {
+ msg = MSG_COMMAND;
+ cmdflags = CMD_STARTSERVER|CMD_SENDENVIRON|CMD_CANTNEST;
+ } else {
+ msg = MSG_COMMAND;
+
+ /*
+ * It sucks parsing the command string twice (in client and
+ * later in server) but it is necessary to get the start server
+ * flag.
+ */
+ if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
+ log_warnx("%s", cause);
+ return (1);
+ }
+ cmdflags &= ~CMD_STARTSERVER;
+ TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
+ if (cmd->entry->flags & CMD_STARTSERVER)
+ cmdflags |= CMD_STARTSERVER;
+ if (cmd->entry->flags & CMD_SENDENVIRON)
+ cmdflags |= CMD_SENDENVIRON;
+ if (cmd->entry->flags & CMD_CANTNEST)
+ cmdflags |= CMD_CANTNEST;
+ }
+ cmd_list_free(cmdlist);
+ }
+
+ /*
+ * Check if this could be a nested session, if the command can't nest:
+ * if the socket path matches $TMUX, this is probably the same server.
+ */
+ if (shell_cmd == NULL && environ_path != NULL &&
+ cmdflags & CMD_CANTNEST && strcmp(socket_path, environ_path) == 0) {
+ log_warnx("sessions should be nested with care. "
+ "unset $TMUX to force.");
+ return (1);
+ }
+
+ /* Initialise the client socket and start the server. */
+ fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
+ if (fd == -1) {
+ log_warn("failed to connect to server");
+ return (1);
+ }
+
+ /* Set process title, log and signals now this is the client. */
+#ifdef HAVE_SETPROCTITLE
+ setproctitle("client (%s)", socket_path);
+#endif
+ logfile("client");
+
+ /* Create imsg. */
imsg_init(&client_ibuf, fd);
- event_set(&client_event, fd, EV_READ, client_callback, NULL);
+ event_set(&client_event, fd, EV_READ, client_callback, shell_cmd);
+
+ /* Establish signal handlers. */
+ set_signals(client_signal);
+ /* Send initial environment. */
if (cmdflags & CMD_SENDENVIRON)
client_send_environ();
client_send_identify(flags);
- return (&client_ibuf);
+ /* Send first command. */
+ if (msg == MSG_COMMAND) {
+ /* Fill in command line arguments. */
+ cmddata.pid = environ_pid;
+ cmddata.idx = environ_idx;
+
+ /* Prepare command for server. */
+ cmddata.argc = argc;
+ if (cmd_pack_argv(
+ argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
+ log_warnx("command too long");
+ return (1);
+ }
+
+ client_write_server(msg, &cmddata, sizeof cmddata);
+ } else if (msg == MSG_SHELL)
+ client_write_server(msg, NULL, 0);
-start_failed:
- log_warnx("server failed to start");
- return (NULL);
+ /* Set the event and dispatch. */
+ client_update_event();
+ event_dispatch();
-not_found:
- log_warn("server not found");
- return (NULL);
+ /* Print the exit message, if any, and exit. */
+ if (client_attached && client_exitmsg != NULL && !login_shell)
+ printf("[%s]\n", client_exitmsg);
+ return (client_exitval);
}
+/* Send identify message to server with the file descriptors. */
void
client_send_identify(int flags)
{
@@ -138,13 +224,16 @@ client_send_identify(int flags)
if ((fd = dup(STDOUT_FILENO)) == -1)
fatal("dup failed");
- imsg_compose(&client_ibuf, MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 0);
+ imsg_compose(&client_ibuf,
+ MSG_STDOUT, PROTOCOL_VERSION, -1, fd, NULL, 0);
if ((fd = dup(STDERR_FILENO)) == -1)
fatal("dup failed");
- imsg_compose(&client_ibuf, MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 0);
+ imsg_compose(&client_ibuf,
+ MSG_STDERR, PROTOCOL_VERSION, -1, fd, NULL, 0);
}
+/* Forward entire environment to server. */
void
client_send_environ(void)
{
@@ -158,12 +247,14 @@ client_send_environ(void)
}
}
+/* Write a message to the server without a file descriptor. */
void
client_write_server(enum msgtype type, void *buf, size_t len)
{
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
+/* Update client event based on whether it needs to read or read and write. */
void
client_update_event(void)
{
@@ -173,91 +264,74 @@ client_update_event(void)
events = EV_READ;
if (client_ibuf.w.queued > 0)
events |= EV_WRITE;
- event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
+ event_set(
+ &client_event, client_ibuf.fd, events, client_callback, shell_cmd);
event_add(&client_event, NULL);
}
-__dead void
-client_main(void)
-{
- logfile("client");
-
- /* Note: event_init() has already been called. */
-
- /* Set up signals. */
- set_signals(client_signal);
-
- /*
- * Send a resize message immediately in case the terminal size has
- * changed between the identify message to the server and the MSG_READY
- * telling us to move into the client code.
- */
- client_write_server(MSG_RESIZE, NULL, 0);
-
- /*
- * imsg_read in the first client poll loop (before the terminal has
- * been initialised) may have read messages into the buffer after the
- * MSG_READY switched to here. Process anything outstanding now to
- * avoid hanging waiting for messages that have already arrived.
- */
- if (client_dispatch() != 0)
- goto out;
-
- /* Set the event and dispatch. */
- client_update_event();
- event_dispatch();
-
-out:
- /* Print the exit message, if any, and exit. */
- if (client_exitmsg != NULL && !login_shell)
- printf("[%s]\n", client_exitmsg);
- exit(client_exitval);
-}
-
+/* Callback to handle signals in the client. */
/* ARGSUSED */
void
client_signal(int sig, unused short events, unused void *data)
{
- struct sigaction sigact;
+ struct sigaction sigact;
+ int status;
- switch (sig) {
- case SIGHUP:
- client_exitmsg = "lost tty";
- client_exitval = 1;
- client_write_server(MSG_EXITING, NULL, 0);
- break;
- case SIGTERM:
- client_exitmsg = "terminated";
- client_exitval = 1;
- client_write_server(MSG_EXITING, NULL, 0);
- break;
- case SIGWINCH:
- client_write_server(MSG_RESIZE, NULL, 0);
- break;
- case SIGCONT:
- memset(&sigact, 0, sizeof sigact);
- sigemptyset(&sigact.sa_mask);
- sigact.sa_flags = SA_RESTART;
- sigact.sa_handler = SIG_IGN;
- if (sigaction(SIGTSTP, &sigact, NULL) != 0)
- fatal("sigaction failed");
- client_write_server(MSG_WAKEUP, NULL, 0);
- break;
+ if (!client_attached) {
+ switch (sig) {
+ case SIGCHLD:
+ waitpid(WAIT_ANY, &status, WNOHANG);
+ break;
+ case SIGTERM:
+ event_loopexit(NULL);
+ break;
+ }
+ } else {
+ switch (sig) {
+ case SIGHUP:
+ client_exitmsg = "lost tty";
+ client_exitval = 1;
+ client_write_server(MSG_EXITING, NULL, 0);
+ break;
+ case SIGTERM:
+ client_exitmsg = "terminated";
+ client_exitval = 1;
+ client_write_server(MSG_EXITING, NULL, 0);
+ break;
+ case SIGWINCH:
+ client_write_server(MSG_RESIZE, NULL, 0);
+ break;
+ case SIGCONT:
+ memset(&sigact, 0, sizeof sigact);
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = SA_RESTART;
+ sigact.sa_handler = SIG_IGN;
+ if (sigaction(SIGTSTP, &sigact, NULL) != 0)
+ fatal("sigaction failed");
+ client_write_server(MSG_WAKEUP, NULL, 0);
+ break;
+ }
}
client_update_event();
}
+/* Callback for client imsg read events. */
/* ARGSUSED */
void
-client_callback(unused int fd, short events, unused void *data)
+client_callback(unused int fd, short events, void *data)
{
ssize_t n;
+ int retval;
if (events & EV_READ) {
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
goto lost_server;
- if (client_dispatch() != 0) {
+ if (client_attached)
+ retval = client_dispatch_attached();
+ else
+ retval = client_dispatch_wait(data);
+ if (retval != 0) {
event_loopexit(NULL);
return;
}
@@ -277,8 +351,76 @@ lost_server:
event_loopexit(NULL);
}
+/* Dispatch imsgs when in wait state (before MSG_READY). */
+int
+client_dispatch_wait(void *data)
+{
+ struct imsg imsg;
+ ssize_t n, datalen;
+ struct msg_shell_data shelldata;
+ struct msg_exit_data exitdata;
+ const char *shellcmd = data;
+
+ if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
+ fatalx("imsg_read failed");
+
+ for (;;) {
+ if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
+ fatalx("imsg_get failed");
+ if (n == 0)
+ return (0);
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+
+ switch (imsg.hdr.type) {
+ case MSG_EXIT:
+ case MSG_SHUTDOWN:
+ if (datalen != sizeof exitdata) {
+ if (datalen != 0)
+ fatalx("bad MSG_EXIT size");
+ } else {
+ memcpy(&exitdata, imsg.data, sizeof exitdata);
+ client_exitval = exitdata.retcode;
+ }
+ imsg_free(&imsg);
+ return (-1);
+ case MSG_READY:
+ if (datalen != 0)
+ fatalx("bad MSG_READY size");
+
+ client_attached = 1;
+ break;
+ case MSG_VERSION:
+ if (datalen != 0)
+ fatalx("bad MSG_VERSION size");
+
+ log_warnx("protocol version mismatch (client %u, "
+ "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
+ client_exitval = 1;
+
+ imsg_free(&imsg);
+ return (-1);
+ case MSG_SHELL:
+ if (datalen != sizeof shelldata)
+ fatalx("bad MSG_SHELL size");
+ memcpy(&shelldata, imsg.data, sizeof shelldata);
+ shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
+
+ clear_signals(0);
+
+ shell_exec(shelldata.shell, shellcmd);
+ /* NOTREACHED */
+ default:
+ fatalx("unexpected message");
+ }
+
+ imsg_free(&imsg);
+ }
+}
+
+/* Dispatch imsgs in attached state (after MSG_READY). */
+/* ARGSUSED */
int
-client_dispatch(void)
+client_dispatch_attached(void)
{
struct imsg imsg;
struct msg_lock_data lockdata;
diff --git a/client.o b/client.o
new file mode 100644
index 0000000..895a57f
--- a/dev/null
+++ b/client.o
Binary files differ
diff --git a/clock.o b/clock.o
new file mode 100644
index 0000000..8412766
--- a/dev/null
+++ b/clock.o
Binary files differ
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index c15b76b..555913c 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-attach-session.c,v 1.36 2010/02/08 18:27:34 tcunha Exp $ */
+/* $Id: cmd-attach-session.c,v 1.39 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,37 +28,37 @@ int cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach",
+ "drt:", 0, 0,
"[-dr] " CMD_TARGET_SESSION_USAGE,
- CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, "dr",
- cmd_target_init,
- cmd_target_parse,
- cmd_attach_session_exec,
- cmd_target_free,
- cmd_target_print
+ CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON,
+ NULL,
+ NULL,
+ cmd_attach_session_exec
};
int
cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
- struct client *c;
- const char *update;
- char *overrides, *cause;
- u_int i;
-
- if (ARRAY_LENGTH(&sessions) == 0) {
+ struct args *args = self->args;
+ struct session *s;
+ struct client *c;
+ const char *update;
+ char *overrides, *cause;
+ u_int i;
+
+ if (RB_EMPTY(&sessions)) {
ctx->error(ctx, "no sessions");
return (-1);
}
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+
+ if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL)
return (-1);
if (ctx->cmdclient == NULL && ctx->curclient == NULL)
return (0);
if (ctx->cmdclient == NULL) {
- if (cmd_check_flag(data->chflags, 'd')) {
+ if (args_has(self->args, 'd')) {
/*
* Can't use server_write_session in case attaching to
* the same session as currently attached to.
@@ -74,6 +74,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
}
ctx->curclient->session = s;
+ session_update_activity(s);
server_redraw_client(ctx->curclient);
} else {
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
@@ -89,13 +90,14 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
- if (cmd_check_flag(data->chflags, 'r'))
+ if (args_has(self->args, 'r'))
ctx->cmdclient->flags |= CLIENT_READONLY;
- if (cmd_check_flag(data->chflags, 'd'))
+ if (args_has(self->args, 'd'))
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
+ session_update_activity(s);
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
update = options_get_string(&s->options, "update-environment");
diff --git a/cmd-attach-session.o b/cmd-attach-session.o
new file mode 100644
index 0000000..7bb6daa
--- a/dev/null
+++ b/cmd-attach-session.o
Binary files differ
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 3547a13..f5d0716 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-bind-key.c,v 1.29 2010/07/02 02:43:01 tcunha Exp $ */
+/* $Id: cmd-bind-key.c,v 1.31 2011/01/22 00:00:23 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -26,136 +26,87 @@
* Bind a key to a command, this recurses through cmd_*.
*/
-int cmd_bind_key_parse(struct cmd *, int, char **, char **);
+int cmd_bind_key_check(struct args *);
int cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
-void cmd_bind_key_free(struct cmd *);
-size_t cmd_bind_key_print(struct cmd *, char *, size_t);
-int cmd_bind_key_table(struct cmd *, struct cmd_ctx *);
-
-struct cmd_bind_key_data {
- int key;
- int can_repeat;
- struct cmd_list *cmdlist;
-
- int command_key;
- char *tablename;
- char *modecmd;
-};
+int cmd_bind_key_table(struct cmd *, struct cmd_ctx *, int);
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
+ "cnrt:", 1, -1,
"[-cnr] [-t key-table] key command [arguments]",
- 0, "",
+ 0,
NULL,
- cmd_bind_key_parse,
- cmd_bind_key_exec,
- cmd_bind_key_free,
- cmd_bind_key_print
+ cmd_bind_key_check,
+ cmd_bind_key_exec
};
int
-cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
+cmd_bind_key_check(struct args *args)
{
- struct cmd_bind_key_data *data;
- int opt, no_prefix = 0;
-
- self->data = data = xmalloc(sizeof *data);
- data->can_repeat = 0;
- data->cmdlist = NULL;
- data->command_key = 0;
- data->tablename = NULL;
- data->modecmd = NULL;
-
- while ((opt = getopt(argc, argv, "cnrt:")) != -1) {
- switch (opt) {
- case 'c':
- data->command_key = 1;
- break;
- case 'n':
- no_prefix = 1;
- break;
- case 'r':
- data->can_repeat = 1;
- break;
- case 't':
- if (data->tablename == NULL)
- data->tablename = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc < 1)
- goto usage;
-
- if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) {
- xasprintf(cause, "unknown key: %s", argv[0]);
- goto error;
- }
- if (!no_prefix)
- data->key |= KEYC_PREFIX;
-
- argc--;
- argv++;
- if (data->tablename != NULL) {
- if (argc != 1)
- goto usage;
- data->modecmd = xstrdup(argv[0]);
+ if (args_has(args, 't')) {
+ if (args->argc != 2)
+ return (-1);
} else {
- if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
- goto error;
+ if (args->argc < 2)
+ return (-1);
}
-
return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
-error:
- self->entry->free(self);
- return (-1);
}
int
-cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
+cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_bind_key_data *data = self->data;
+ struct args *args = self->args;
+ char *cause;
+ struct cmd_list *cmdlist;
+ int key;
- if (data == NULL)
- return (0);
- if (data->tablename != NULL)
- return (cmd_bind_key_table(self, ctx));
+ key = key_string_lookup_string(args->argv[0]);
+ if (key == KEYC_NONE) {
+ ctx->error(ctx, "unknown key: %s", args->argv[0]);
+ return (-1);
+ }
+
+ if (args_has(args, 't'))
+ return (cmd_bind_key_table(self, ctx, key));
- key_bindings_add(data->key, data->can_repeat, data->cmdlist);
- data->cmdlist->references++;
+ cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, &cause);
+ if (cmdlist == NULL) {
+ ctx->error(ctx, "%s", cause);
+ xfree(cause);
+ return (-1);
+ }
+ if (!args_has(args, 'n'))
+ key |= KEYC_PREFIX;
+ key_bindings_add(key, args_has(args, 'r'), cmdlist);
return (0);
}
int
-cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
+cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
{
- struct cmd_bind_key_data *data = self->data;
+ struct args *args = self->args;
+ const char *tablename;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
enum mode_key_cmd cmd;
- if ((mtab = mode_key_findtable(data->tablename)) == NULL) {
- ctx->error(ctx, "unknown key table: %s", data->tablename);
+ tablename = args_get(args, 't');
+ if ((mtab = mode_key_findtable(tablename)) == NULL) {
+ ctx->error(ctx, "unknown key table: %s", tablename);
return (-1);
}
- cmd = mode_key_fromstring(mtab->cmdstr, data->modecmd);
+ cmd = mode_key_fromstring(mtab->cmdstr, args->argv[1]);
if (cmd == MODEKEY_NONE) {
- ctx->error(ctx, "unknown command: %s", data->modecmd);
+ ctx->error(ctx, "unknown command: %s", args->argv[1]);
return (-1);
}
- mtmp.key = data->key & ~KEYC_PREFIX;
- mtmp.mode = data->command_key ? 1 : 0;
+ mtmp.key = key;
+ mtmp.mode = !!args_has(args, 'c');
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
mbind->cmd = cmd;
return (0);
@@ -167,45 +118,3 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
SPLAY_INSERT(mode_key_tree, mtab->tree, mbind);
return (0);
}
-
-void
-cmd_bind_key_free(struct cmd *self)
-{
- struct cmd_bind_key_data *data = self->data;
-
- if (data->cmdlist != NULL)
- cmd_list_free(data->cmdlist);
- if (data->tablename != NULL)
- xfree(data->tablename);
- if (data->modecmd != NULL)
- xfree(data->modecmd);
- xfree(data);
-}
-
-size_t
-cmd_bind_key_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_bind_key_data *data = self->data;
- size_t off = 0;
- const char *skey;
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return (off);
-
- if (off < len && data->command_key)
- off += xsnprintf(buf + off, len - off, " -c");
- if (off < len && !(data->key & KEYC_PREFIX))
- off += xsnprintf(buf + off, len - off, " -n");
- if (off < len && data->can_repeat)
- off += xsnprintf(buf + off, len - off, " -r");
- if (off < len && data->tablename != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->tablename);
- if (off < len) {
- skey = key_string_lookup_key(data->key & ~KEYC_PREFIX);
- off += xsnprintf(buf + off, len - off, " %s ", skey);
- }
- if (off < len)
- off += cmd_list_print(data->cmdlist, buf + off, len - off);
- return (off);
-}
diff --git a/cmd-bind-key.o b/cmd-bind-key.o
new file mode 100644
index 0000000..23734fb
--- a/dev/null
+++ b/cmd-bind-key.o
Binary files differ
diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index 5ae2e1e..999a339 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-break-pane.c,v 1.11 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-break-pane.c,v 1.12 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -30,19 +30,18 @@ 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, "d",
- cmd_target_init,
- cmd_target_parse,
- cmd_break_pane_exec,
- cmd_target_free,
- cmd_target_print
+ "dt:", 0, 0,
+ "[-d] " CMD_TARGET_PANE_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_break_pane_exec
};
int
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
struct session *s;
struct window_pane *wp;
@@ -50,7 +49,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
char *cause;
int base_idx;
- if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
+ if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
return (-1);
if (window_count_panes(wl->window) == 1) {
@@ -74,7 +73,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
base_idx = options_get_number(&s->options, "base-index");
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
- if (!cmd_check_flag(data->chflags, 'd'))
+ if (!args_has(self->args, 'd'))
session_select(s, wl->idx);
server_redraw_session(s);
diff --git a/cmd-break-pane.o b/cmd-break-pane.o
new file mode 100644
index 0000000..5931856
--- a/dev/null
+++ b/cmd-break-pane.o
Binary files differ
diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index df3313a..a2c2fdd 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-capture-pane.c,v 1.3 2010/01/22 17:29:19 tcunha Exp $ */
+/* $Id: cmd-capture-pane.c,v 1.6 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2009 Jonathan Alvarado <[email protected]>
@@ -18,6 +18,7 @@
#include <sys/types.h>
+#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -30,27 +31,26 @@ 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
+ "b:t:", 0, 0,
+ "[-b buffer-index] [-t target-pane]",
+ 0,
+ NULL,
+ NULL,
+ cmd_capture_pane_exec
};
int
cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_buffer_data *data = self->data;
+ struct args *args = self->args;
struct window_pane *wp;
- char *buf, *line;
+ char *buf, *line, *cause;
struct screen *s;
- struct session *sess;
+ int buffer;
u_int i, limit;
size_t len, linelen;
- if (cmd_find_pane(ctx, data->target, &sess, &wp) == NULL)
+ if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (-1);
s = &wp->base;
@@ -69,15 +69,25 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
xfree(line);
}
- limit = options_get_number(&sess->options, "buffer-limit");
- if (data->buffer == -1) {
- paste_add(&sess->buffers, buf, len, limit);
+ limit = options_get_number(&global_options, "buffer-limit");
+
+ if (!args_has(args, 'b')) {
+ paste_add(&global_buffers, buf, len, limit);
return (0);
}
- if (paste_replace(&sess->buffers, data->buffer, buf, len) != 0) {
- ctx->error(ctx, "no buffer %d", data->buffer);
+
+ buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "buffer %s", cause);
+ xfree(cause);
+ return (-1);
+ }
+
+ if (paste_replace(&global_buffers, buffer, buf, len) != 0) {
+ ctx->error(ctx, "no buffer %d", buffer);
xfree(buf);
return (-1);
}
+
return (0);
}
diff --git a/cmd-capture-pane.o b/cmd-capture-pane.o
new file mode 100644
index 0000000..ac90601
--- a/dev/null
+++ b/cmd-capture-pane.o
Binary files differ
diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c
index 6a94fca..1a2bdb3 100644
--- a/cmd-choose-buffer.c
+++ b/cmd-choose-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-choose-buffer.c,v 1.1 2010/06/22 23:35:20 tcunha Exp $ */
+/* $Id: cmd-choose-buffer.c,v 1.4 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2010 Nicholas Marriott <[email protected]>
@@ -33,26 +33,24 @@ void cmd_choose_buffer_free(void *);
const struct cmd_entry cmd_choose_buffer_entry = {
"choose-buffer", NULL,
+ "t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [template]",
- CMD_ARG01, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_choose_buffer_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_choose_buffer_exec
};
struct cmd_choose_buffer_data {
- struct client *client;
- char *template;
+ struct client *client;
+ char *template;
};
int
cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_choose_buffer_data *cdata;
- struct session *s;
struct winlink *wl;
struct paste_buffer *pb;
u_int idx;
@@ -62,19 +60,18 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "must be run interactively");
return (-1);
}
- s = ctx->curclient->session;
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
- if (paste_get_top(&s->buffers) == NULL)
+ if (paste_get_top(&global_buffers) == NULL)
return (0);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
idx = 0;
- while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
+ while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
tmp = paste_print(pb, 50);
window_choose_add(wl->window->active, idx - 1,
"%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp);
@@ -82,8 +79,8 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
cdata = xmalloc(sizeof *cdata);
- if (data->arg != NULL)
- cdata->template = xstrdup(data->arg);
+ if (args->argc != 0)
+ cdata->template = xstrdup(args->argv[0]);
else
cdata->template = xstrdup("paste-buffer -b '%%'");
cdata->client = ctx->curclient;
diff --git a/cmd-choose-buffer.o b/cmd-choose-buffer.o
new file mode 100644
index 0000000..4d213be
--- a/dev/null
+++ b/cmd-choose-buffer.o
Binary files differ
diff --git a/cmd-choose-client.c b/cmd-choose-client.c
index 045a42e..8cd40ec 100644
--- a/cmd-choose-client.c
+++ b/cmd-choose-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-choose-client.c,v 1.4 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-choose-client.c,v 1.5 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -33,13 +33,12 @@ void cmd_choose_client_free(void *);
const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL,
+ "t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [template]",
- CMD_ARG01, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_choose_client_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_choose_client_exec
};
struct cmd_choose_client_data {
@@ -50,7 +49,7 @@ struct cmd_choose_client_data {
int
cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_choose_client_data *cdata;
struct winlink *wl;
struct client *c;
@@ -61,7 +60,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
@@ -83,8 +82,8 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
}
cdata = xmalloc(sizeof *cdata);
- if (data->arg != NULL)
- cdata->template = xstrdup(data->arg);
+ if (args->argc != 0)
+ cdata->template = xstrdup(args->argv[0]);
else
cdata->template = xstrdup("detach-client -t '%%'");
cdata->client = ctx->curclient;
diff --git a/cmd-choose-client.o b/cmd-choose-client.o
new file mode 100644
index 0000000..54167c2
--- a/dev/null
+++ b/cmd-choose-client.o
Binary files differ
diff --git a/cmd-choose-session.c b/cmd-choose-session.c
index 7d9cdd4..badb360 100644
--- a/cmd-choose-session.c
+++ b/cmd-choose-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-choose-session.c,v 1.15 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-choose-session.c,v 1.18 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -33,13 +33,12 @@ void cmd_choose_session_free(void *);
const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL,
+ "t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [template]",
- CMD_ARG01, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_choose_session_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_choose_session_exec
};
struct cmd_choose_session_data {
@@ -50,12 +49,12 @@ struct cmd_choose_session_data {
int
cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_choose_session_data *cdata;
struct winlink *wl;
struct session *s;
struct session_group *sg;
- u_int i, idx, cur;
+ u_int idx, sgidx, cur;
char tmp[64];
if (ctx->curclient == NULL) {
@@ -63,17 +62,14 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
cur = idx = 0;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s == NULL)
- continue;
+ RB_FOREACH(s, sessions, &sessions) {
if (s == ctx->curclient->session)
cur = idx;
idx++;
@@ -82,19 +78,19 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if (sg == NULL)
*tmp = '\0';
else {
- idx = session_group_index(sg);
- xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
+ sgidx = session_group_index(sg);
+ xsnprintf(tmp, sizeof tmp, " (group %u)", sgidx);
}
- window_choose_add(wl->window->active, i,
+ window_choose_add(wl->window->active, s->idx,
"%s: %u windows [%ux%u]%s%s", s->name,
winlink_count(&s->windows), s->sx, s->sy,
tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
}
cdata = xmalloc(sizeof *cdata);
- if (data->arg != NULL)
- cdata->template = xstrdup(data->arg);
+ if (args->argc != 0)
+ cdata->template = xstrdup(args->argv[0]);
else
cdata->template = xstrdup("switch-client -t '%%'");
cdata->client = ctx->curclient;
@@ -120,9 +116,7 @@ cmd_choose_session_callback(void *data, int idx)
if (cdata->client->flags & CLIENT_DEAD)
return;
- if ((u_int) idx > ARRAY_LENGTH(&sessions) - 1)
- return;
- s = ARRAY_ITEM(&sessions, idx);
+ s = session_find_by_index(idx);
if (s == NULL)
return;
template = cmd_template_replace(cdata->template, s->name, 1);
diff --git a/cmd-choose-session.o b/cmd-choose-session.o
new file mode 100644
index 0000000..f9148cf
--- a/dev/null
+++ b/cmd-choose-session.o
Binary files differ
diff --git a/cmd-choose-window.c b/cmd-choose-window.c
index 43f38db..5bdc1e4 100644
--- a/cmd-choose-window.c
+++ b/cmd-choose-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-choose-window.c,v 1.22 2010/06/22 23:26:18 tcunha Exp $ */
+/* $Id: cmd-choose-window.c,v 1.26 2011/01/07 16:55:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -33,13 +33,12 @@ void cmd_choose_window_free(void *);
const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL,
+ "t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [template]",
- CMD_ARG01, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_choose_window_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_choose_window_exec
};
struct cmd_choose_window_data {
@@ -51,13 +50,13 @@ struct cmd_choose_window_data {
int
cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_choose_window_data *cdata;
struct session *s;
struct winlink *wl, *wm;
struct window *w;
u_int idx, cur;
- char flag, *title;
+ char *flags, *title;
const char *left, *right;
if (ctx->curclient == NULL) {
@@ -66,7 +65,7 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
s = ctx->curclient->session;
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
@@ -80,18 +79,7 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx;
idx++;
- flag = ' ';
- if (wm->flags & WINLINK_ACTIVITY)
- flag = '#';
- else if (wm->flags & WINLINK_BELL)
- flag = '!';
- else if (wm->flags & WINLINK_CONTENT)
- flag = '+';
- else if (wm == s->curw)
- flag = '*';
- else if (wm == TAILQ_FIRST(&s->lastw))
- flag = '-';
-
+ flags = window_printable_flags(s, wm);
title = w->active->screen->title;
if (wm == wl)
title = w->active->base.title;
@@ -101,15 +89,17 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
left = right = "";
window_choose_add(wl->window->active,
- wm->idx, "%3d: %s%c [%ux%u] (%u panes%s)%s%s%s",
- wm->idx, w->name, flag, w->sx, w->sy, window_count_panes(w),
+ wm->idx, "%3d: %s%s [%ux%u] (%u panes%s)%s%s%s",
+ wm->idx, w->name, flags, w->sx, w->sy, window_count_panes(w),
w->active->fd == -1 ? ", dead" : "",
left, title, right);
+
+ xfree(flags);
}
cdata = xmalloc(sizeof *cdata);
- if (data->arg != NULL)
- cdata->template = xstrdup(data->arg);
+ if (args->argc != 0)
+ cdata->template = xstrdup(args->argv[0]);
else
cdata->template = xstrdup("select-window -t '%%'");
cdata->session = s;
@@ -127,20 +117,19 @@ void
cmd_choose_window_callback(void *data, int idx)
{
struct cmd_choose_window_data *cdata = data;
+ struct session *s = cdata->session;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *target, *template, *cause;
if (idx == -1)
return;
- if (cdata->client->flags & CLIENT_DEAD)
+ if (!session_alive(s))
return;
- if (cdata->session->flags & SESSION_DEAD)
- return;
- if (cdata->client->session != cdata->session)
+ if (cdata->client->flags & CLIENT_DEAD)
return;
- xasprintf(&target, "%s:%d", cdata->session->name, idx);
+ xasprintf(&target, "%s:%d", s->name, idx);
template = cmd_template_replace(cdata->template, target, 1);
xfree(target);
diff --git a/cmd-choose-window.o b/cmd-choose-window.o
new file mode 100644
index 0000000..8bfae11
--- a/dev/null
+++ b/cmd-choose-window.o
Binary files differ
diff --git a/cmd-clear-history.c b/cmd-clear-history.c
index a8a828d..3767ed2 100644
--- a/cmd-clear-history.c
+++ b/cmd-clear-history.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-clear-history.c,v 1.8 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-clear-history.c,v 1.9 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -28,23 +28,22 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
+ "t:", 0, 0,
CMD_TARGET_PANE_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_clear_history_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_clear_history_exec
};
int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct window_pane *wp;
struct grid *gd;
- if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
+ if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (-1);
gd = wp->base.grid;
diff --git a/cmd-clear-history.o b/cmd-clear-history.o
new file mode 100644
index 0000000..33b1455
--- a/dev/null
+++ b/cmd-clear-history.o
Binary files differ
diff --git a/cmd-clock-mode.c b/cmd-clock-mode.c
index 136fae0..8f54379 100644
--- a/cmd-clock-mode.c
+++ b/cmd-clock-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-clock-mode.c,v 1.7 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-clock-mode.c,v 1.8 2011/01/07 14:45:33 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -28,22 +28,21 @@ int cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
+ "t:", 0, 0,
CMD_TARGET_PANE_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_clock_mode_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_clock_mode_exec
};
int
cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct window_pane *wp;
- if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
+ if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (-1);
window_pane_set_mode(wp, &window_clock_mode);
diff --git a/cmd-clock-mode.o b/cmd-clock-mode.o
new file mode 100644
index 0000000..0f540b8
--- a/dev/null
+++ b/cmd-clock-mode.o
Binary files differ
diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c
index ddb88bf..8742c2f 100644
--- a/cmd-command-prompt.c
+++ b/cmd-command-prompt.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-command-prompt.c,v 1.28 2010/05/14 14:33:39 tcunha Exp $ */
+/* $Id: cmd-command-prompt.c,v 1.30 2011/01/07 15:04:51 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -27,30 +27,21 @@
* Prompt for command in client.
*/
-void cmd_command_prompt_init(struct cmd *, int);
-int cmd_command_prompt_parse(struct cmd *, int, char **, char **);
-int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
-void cmd_command_prompt_free(struct cmd *);
-size_t cmd_command_prompt_print(struct cmd *, char *, size_t);
+void cmd_command_prompt_key_binding(struct cmd *, int);
+int cmd_command_prompt_check(struct args *);
+int cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
-int cmd_command_prompt_callback(void *, const char *);
-void cmd_command_prompt_cfree(void *);
+int cmd_command_prompt_callback(void *, const char *);
+void cmd_command_prompt_free(void *);
const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL,
+ "p:t:", 0, 1,
CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]",
- 0, "",
- cmd_command_prompt_init,
- cmd_command_prompt_parse,
- cmd_command_prompt_exec,
- cmd_command_prompt_free,
- cmd_command_prompt_print
-};
-
-struct cmd_command_prompt_data {
- char *prompts;
- char *target;
- char *template;
+ 0,
+ cmd_command_prompt_key_binding,
+ NULL,
+ cmd_command_prompt_exec
};
struct cmd_command_prompt_cdata {
@@ -62,82 +53,39 @@ struct cmd_command_prompt_cdata {
};
void
-cmd_command_prompt_init(struct cmd *self, int key)
+cmd_command_prompt_key_binding(struct cmd *self, int key)
{
- struct cmd_command_prompt_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->prompts = NULL;
- data->target = NULL;
- data->template = NULL;
-
switch (key) {
case ',':
- data->template = xstrdup("rename-window '%%'");
+ self->args = args_create(1, "rename-window '%%'");
break;
case '.':
- data->template = xstrdup("move-window -t '%%'");
+ self->args = args_create(1, "move-window -t '%%'");
break;
case 'f':
- data->template = xstrdup("find-window '%%'");
+ self->args = args_create(1, "find-window '%%'");
break;
case '\'':
- data->template = xstrdup("select-window -t ':%%'");
- data->prompts = xstrdup("index");
+ self->args = args_create(1, "select-window -t ':%%'");
+ args_set(self->args, 'p', "index");
+ break;
+ default:
+ self->args = args_create(0);
break;
}
}
int
-cmd_command_prompt_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_command_prompt_data *data;
- int opt;
-
- self->entry->init(self, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "p:t:")) != -1) {
- switch (opt) {
- case 'p':
- if (data->prompts == NULL)
- data->prompts = xstrdup(optarg);
- break;
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 0 && argc != 1)
- goto usage;
-
- if (argc == 1)
- data->template = xstrdup(argv[0]);
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
-}
-
-int
cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_command_prompt_data *data = self->data;
+ struct args *args = self->args;
+ const char *prompts;
struct cmd_command_prompt_cdata *cdata;
struct client *c;
char *prompt, *ptr;
size_t n;
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
if (c->prompt_string != NULL)
@@ -150,63 +98,33 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata->prompts = NULL;
cdata->template = NULL;
- if (data->template != NULL)
- cdata->template = xstrdup(data->template);
+ if (args->argc != 0)
+ cdata->template = xstrdup(args->argv[0]);
else
cdata->template = xstrdup("%1");
- if (data->prompts != NULL)
- cdata->prompts = xstrdup(data->prompts);
- else if (data->template != NULL) {
- n = strcspn(data->template, " ,");
- xasprintf(&cdata->prompts, "(%.*s) ", (int) n, data->template);
+
+ prompts = args_get(args, 'p');
+ if (prompts != NULL)
+ cdata->prompts = xstrdup(prompts);
+ else if (args->argc != 0) {
+ n = strcspn(cdata->template, " ,");
+ xasprintf(&cdata->prompts, "(%.*s) ", (int) n, cdata->template);
} else
cdata->prompts = xstrdup(":");
cdata->next_prompt = cdata->prompts;
ptr = strsep(&cdata->next_prompt, ",");
- if (data->prompts == NULL)
+ if (prompts == NULL)
prompt = xstrdup(ptr);
else
xasprintf(&prompt, "%s ", ptr);
status_prompt_set(c, prompt, cmd_command_prompt_callback,
- cmd_command_prompt_cfree, cdata, 0);
+ cmd_command_prompt_free, cdata, 0);
xfree(prompt);
return (0);
}
-void
-cmd_command_prompt_free(struct cmd *self)
-{
- struct cmd_command_prompt_data *data = self->data;
-
- if (data->prompts != NULL)
- xfree(data->prompts);
- if (data->target != NULL)
- xfree(data->target);
- if (data->template != NULL)
- xfree(data->template);
- xfree(data);
-}
-
-size_t
-cmd_command_prompt_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_command_prompt_data *data = self->data;
- size_t off = 0;
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return (off);
- if (off < len && data->prompts != NULL)
- off += cmd_prarg(buf + off, len - off, " -p ", data->prompts);
- if (off < len && data->target != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->target);
- if (off < len && data->template != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->template);
- return (off);
-}
-
int
cmd_command_prompt_callback(void *data, const char *s)
{
@@ -258,7 +176,7 @@ cmd_command_prompt_callback(void *data, const char *s)
}
void
-cmd_command_prompt_cfree(void *data)
+cmd_command_prompt_free(void *data)
{
struct cmd_command_prompt_cdata *cdata = data;
diff --git a/cmd-command-prompt.o b/cmd-command-prompt.o
new file mode 100644
index 0000000..b30da7a
--- a/dev/null
+++ b/cmd-command-prompt.o
Binary files differ
diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c
index 8777176..fa05c1e 100644
--- a/cmd-confirm-before.c
+++ b/cmd-confirm-before.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-confirm-before.c,v 1.12 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-confirm-before.c,v 1.13 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <[email protected]>
@@ -25,21 +25,20 @@
* Asks for confirmation before executing a command.
*/
+void cmd_confirm_before_key_binding(struct cmd *, int);
int cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *);
-void cmd_confirm_before_init(struct cmd *, int);
int cmd_confirm_before_callback(void *, const char *);
void cmd_confirm_before_free(void *);
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
+ "t:", 1, 1,
CMD_TARGET_CLIENT_USAGE " command",
- CMD_ARG1, "",
- cmd_confirm_before_init,
- cmd_target_parse,
- cmd_confirm_before_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ cmd_confirm_before_key_binding,
+ NULL,
+ cmd_confirm_before_exec
};
struct cmd_confirm_before_data {
@@ -48,19 +47,17 @@ struct cmd_confirm_before_data {
};
void
-cmd_confirm_before_init(struct cmd *self, int key)
+cmd_confirm_before_key_binding(struct cmd *self, int key)
{
- struct cmd_target_data *data;
-
- cmd_target_init(self, key);
- data = self->data;
-
switch (key) {
case '&':
- data->arg = xstrdup("kill-window");
+ self->args = args_create(1, "kill-window");
break;
case 'x':
- data->arg = xstrdup("kill-pane");
+ self->args = args_create(1, "kill-pane");
+ break;
+ default:
+ self->args = args_create(0);
break;
}
}
@@ -68,7 +65,7 @@ cmd_confirm_before_init(struct cmd *self, int key)
int
cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_confirm_before_data *cdata;
struct client *c;
char *buf, *cmd, *ptr;
@@ -78,17 +75,17 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
- ptr = xstrdup(data->arg);
+ ptr = xstrdup(args->argv[0]);
if ((cmd = strtok(ptr, " \t")) == NULL)
cmd = ptr;
xasprintf(&buf, "Confirm '%s'? (y/n) ", cmd);
xfree(ptr);
cdata = xmalloc(sizeof *cdata);
- cdata->cmd = xstrdup(data->arg);
+ cdata->cmd = xstrdup(args->argv[0]);
cdata->c = c;
status_prompt_set(cdata->c, buf,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
diff --git a/cmd-confirm-before.o b/cmd-confirm-before.o
new file mode 100644
index 0000000..787d27b
--- a/dev/null
+++ b/cmd-confirm-before.o
Binary files differ
diff --git a/cmd-copy-buffer.c b/cmd-copy-buffer.c
deleted file mode 100644
index 36d7271..0000000
--- a/cmd-copy-buffer.c
+++ b/dev/null
@@ -1,205 +0,0 @@
-/* $Id: cmd-copy-buffer.c,v 1.7 2009/11/28 14:50:36 tcunha Exp $ */
-
-/*
- * Copyright (c) 2009 Tiago Cunha <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "tmux.h"
-
-/*
- * Copies a session paste buffer to another session.
- */
-
-int cmd_copy_buffer_parse(struct cmd *, int, char **, char **);
-int cmd_copy_buffer_exec(struct cmd *, struct cmd_ctx *);
-void cmd_copy_buffer_free(struct cmd *);
-void cmd_copy_buffer_init(struct cmd *, int);
-size_t cmd_copy_buffer_print(struct cmd *, char *, size_t);
-
-struct cmd_copy_buffer_data {
- char *dst_session;
- char *src_session;
- int dst_idx;
- int src_idx;
-};
-
-const struct cmd_entry cmd_copy_buffer_entry = {
- "copy-buffer", "copyb",
- "[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
- 0, "",
- cmd_copy_buffer_init,
- cmd_copy_buffer_parse,
- cmd_copy_buffer_exec,
- cmd_copy_buffer_free,
- cmd_copy_buffer_print
-};
-
-/* ARGSUSED */
-void
-cmd_copy_buffer_init(struct cmd *self, unused int arg)
-{
- struct cmd_copy_buffer_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->dst_session = NULL;
- data->src_session = NULL;
- data->dst_idx = -1;
- data->src_idx = -1;
-}
-
-int
-cmd_copy_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_copy_buffer_data *data;
- const char *errstr;
- int n, opt;
-
- self->entry->init(self, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "a:b:s:t:")) != -1) {
- switch (opt) {
- case 'a':
- if (data->src_idx == -1) {
- n = strtonum(optarg, 0, INT_MAX, &errstr);
- if (errstr != NULL) {
- xasprintf(cause, "buffer %s", errstr);
- goto error;
- }
- data->src_idx = n;
- }
- break;
- case 'b':
- if (data->dst_idx == -1) {
- n = strtonum(optarg, 0, INT_MAX, &errstr);
- if (errstr != NULL) {
- xasprintf(cause, "buffer %s", errstr);
- goto error;
- }
- data->dst_idx = n;
- }
- break;
- case 's':
- if (data->src_session == NULL)
- data->src_session = xstrdup(optarg);
- break;
- case 't':
- if (data->dst_session == NULL)
- data->dst_session = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
-error:
- self->entry->free(self);
- return (-1);
-}
-
-int
-cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_copy_buffer_data *data = self->data;
- struct paste_buffer *pb;
- struct paste_stack *dst_ps, *src_ps;
- u_char *pdata;
- struct session *dst_session, *src_session;
- u_int limit;
-
- if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL ||
- (src_session = cmd_find_session(ctx, data->src_session)) == NULL)
- return (-1);
- dst_ps = &dst_session->buffers;
- src_ps = &src_session->buffers;
-
- if (data->src_idx == -1) {
- if ((pb = paste_get_top(src_ps)) == NULL) {
- ctx->error(ctx, "no buffers");
- return (-1);
- }
- } else {
- if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) {
- ctx->error(ctx, "no buffer %d", data->src_idx);
- return (-1);
- }
- }
- limit = options_get_number(&dst_session->options, "buffer-limit");
-
- pdata = xmalloc(pb->size);
- memcpy(pdata, pb->data, pb->size);
-
- if (data->dst_idx == -1)
- paste_add(dst_ps, pdata, pb->size, limit);
- else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) {
- ctx->error(ctx, "no buffer %d", data->dst_idx);
- xfree(pdata);
- return (-1);
- }
-
- return (0);
-}
-
-void
-cmd_copy_buffer_free(struct cmd *self)
-{
- struct cmd_copy_buffer_data *data = self->data;
-
- if (data->dst_session != NULL)
- xfree(data->dst_session);
- if (data->src_session != NULL)
- xfree(data->src_session);
- xfree(data);
-}
-
-size_t
-cmd_copy_buffer_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_copy_buffer_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->src_idx != -1) {
- off += xsnprintf(buf + off, len - off, " -a %d",
- data->src_idx);
- }
- if (off < len && data->dst_idx != -1) {
- off += xsnprintf(buf + off, len - off, " -b %d",
- data->dst_idx);
- }
- if (off < len && data->src_session != NULL) {
- off += cmd_prarg(buf + off, len - off, " -s ",
- data->src_session);
- }
- if (off < len && data->dst_session != NULL) {
- off += cmd_prarg(buf + off, len - off, " -t ",
- data->dst_session);
- }
- return (off);
-}
diff --git a/cmd-copy-buffer.o b/cmd-copy-buffer.o
new file mode 100644
index 0000000..21f70d5
--- a/dev/null
+++ b/cmd-copy-buffer.o
Binary files differ
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c
index 77e807a..611ae28 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-copy-mode.c,v 1.28 2010/08/11 22:18:28 tcunha Exp $ */
+/* $Id: cmd-copy-mode.c,v 1.29 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -24,48 +24,40 @@
* Enter copy mode.
*/
-void cmd_copy_mode_init(struct cmd *, int);
+void cmd_copy_mode_key_binding(struct cmd *, int);
int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
+ "t:u", 0, 0,
"[-u] " CMD_TARGET_PANE_USAGE,
- 0, "u",
- cmd_copy_mode_init,
- cmd_target_parse,
- cmd_copy_mode_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ cmd_copy_mode_key_binding,
+ NULL,
+ cmd_copy_mode_exec
};
void
-cmd_copy_mode_init(struct cmd *self, int key)
+cmd_copy_mode_key_binding(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;
- }
+ self->args = args_create(0);
+ if (key == KEYC_PPAGE)
+ args_set(self->args, 'u', NULL);
}
int
cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct window_pane *wp;
- if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
+ if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (-1);
if (window_pane_set_mode(wp, &window_copy_mode) != 0)
return (0);
window_copy_init_from_pane(wp);
- if (wp->mode == &window_copy_mode && cmd_check_flag(data->chflags, 'u'))
+ if (wp->mode == &window_copy_mode && args_has(self->args, 'u'))
window_copy_pageup(wp);
return (0);
diff --git a/cmd-copy-mode.o b/cmd-copy-mode.o
new file mode 100644
index 0000000..d4d001f
--- a/dev/null
+++ b/cmd-copy-mode.o
Binary files differ
diff --git a/cmd-delete-buffer.c b/cmd-delete-buffer.c
index 2c1c0ea..c20a653 100644
--- a/cmd-delete-buffer.c
+++ b/cmd-delete-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-delete-buffer.c,v 1.8 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-delete-buffer.c,v 1.10 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,28 +30,35 @@ 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, "",
- cmd_buffer_init,
- cmd_buffer_parse,
- cmd_delete_buffer_exec,
- cmd_buffer_free,
- cmd_buffer_print
+ "b:", 0, 0,
+ CMD_BUFFER_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_delete_buffer_exec
};
int
cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_buffer_data *data = self->data;
- struct session *s;
+ struct args *args = self->args;
+ char *cause;
+ int buffer;
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ if (!args_has(args, 'b')) {
+ paste_free_top(&global_buffers);
+ return (0);
+ }
+
+ buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "buffer %s", cause);
+ xfree(cause);
return (-1);
+ }
- if (data->buffer == -1)
- paste_free_top(&s->buffers);
- else if (paste_free_index(&s->buffers, data->buffer) != 0) {
- ctx->error(ctx, "no buffer %d", data->buffer);
+ if (paste_free_index(&global_buffers, buffer) != 0) {
+ ctx->error(ctx, "no buffer %d", buffer);
return (-1);
}
diff --git a/cmd-delete-buffer.o b/cmd-delete-buffer.o
new file mode 100644
index 0000000..88d1a9c
--- a/dev/null
+++ b/cmd-delete-buffer.o
Binary files differ
diff --git a/cmd-detach-client.c b/cmd-detach-client.c
index 609fded..432b2fd 100644
--- a/cmd-detach-client.c
+++ b/cmd-detach-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-detach-client.c,v 1.11 2010/02/08 18:27:34 tcunha Exp $ */
+/* $Id: cmd-detach-client.c,v 1.12 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,22 +28,21 @@ int cmd_detach_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_detach_client_entry = {
"detach-client", "detach",
+ "t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
- CMD_READONLY, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_detach_client_exec,
- cmd_target_free,
- cmd_target_print
+ CMD_READONLY,
+ NULL,
+ NULL,
+ cmd_detach_client_exec
};
int
cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
server_write_client(c, MSG_DETACH, NULL, 0);
diff --git a/cmd-detach-client.o b/cmd-detach-client.o
new file mode 100644
index 0000000..71fc1de
--- a/dev/null
+++ b/cmd-detach-client.o
Binary files differ
diff --git a/cmd-display-message.c b/cmd-display-message.c
index 032d6d9..31ef156 100644
--- a/cmd-display-message.c
+++ b/cmd-display-message.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-display-message.c,v 1.7 2009/11/28 14:39:53 tcunha Exp $ */
+/* $Id: cmd-display-message.c,v 1.8 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <[email protected]>
@@ -30,33 +30,32 @@ int cmd_display_message_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_message_entry = {
"display-message", "display",
+ "pt:", 0, 1,
"[-p] " CMD_TARGET_CLIENT_USAGE " [message]",
- CMD_ARG01, "p",
- cmd_target_init,
- cmd_target_parse,
- cmd_display_message_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_display_message_exec
};
int
cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct client *c;
const char *template;
char *msg;
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
- if (data->arg == NULL)
+ if (args->argc == 0)
template = "[#S] #I:#W, current pane #P - (%H:%M %d-%b-%y)";
else
- template = data->arg;
+ template = args->argv[0];
msg = status_replace(c, NULL, template, time(NULL), 0);
- if (cmd_check_flag(data->chflags, 'p'))
+ if (args_has(self->args, 'p'))
ctx->print(ctx, "%s", msg);
else
status_message_set(c, "%s", msg);
diff --git a/cmd-display-message.o b/cmd-display-message.o
new file mode 100644
index 0000000..441f62a
--- a/dev/null
+++ b/cmd-display-message.o
Binary files differ
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 804425a..3e2f1ca 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-display-panes.c,v 1.2 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-display-panes.c,v 1.3 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -28,22 +28,21 @@ int cmd_display_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
+ "t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_display_panes_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_display_panes_exec
};
int
cmd_display_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
server_set_identify(c);
diff --git a/cmd-display-panes.o b/cmd-display-panes.o
new file mode 100644
index 0000000..6ccab00
--- a/dev/null
+++ b/cmd-display-panes.o
Binary files differ
diff --git a/cmd-find-window.c b/cmd-find-window.c
index bd3eadf..1be2c4c 100644
--- a/cmd-find-window.c
+++ b/cmd-find-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-find-window.c,v 1.14 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-find-window.c,v 1.16 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -30,26 +30,26 @@
int cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_find_window_callback(void *, int);
+void cmd_find_window_free(void *);
const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw",
+ "t:", 1, 1,
CMD_TARGET_WINDOW_USAGE " match-string",
- CMD_ARG1, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_find_window_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_find_window_exec
};
struct cmd_find_window_data {
- u_int session;
+ struct session *session;
};
int
cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_find_window_data *cdata;
struct session *s;
struct winlink *wl, *wm;
@@ -57,7 +57,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_pane *wp;
ARRAY_DECL(, u_int) list_idx;
ARRAY_DECL(, char *) list_ctx;
- char *sres, *sctx, *searchstr;
+ char *str, *sres, *sctx, *searchstr;
u_int i, line;
if (ctx->curclient == NULL) {
@@ -66,13 +66,15 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
s = ctx->curclient->session;
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
+ str = args->argv[0];
+
ARRAY_INIT(&list_idx);
ARRAY_INIT(&list_ctx);
- xasprintf(&searchstr, "*%s*", data->arg);
+ xasprintf(&searchstr, "*%s*", str);
RB_FOREACH(wm, winlinks, &s->windows) {
i = 0;
TAILQ_FOREACH(wp, &wm->window->panes, entry) {
@@ -81,7 +83,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (fnmatch(searchstr, wm->window->name, 0) == 0)
sctx = xstrdup("");
else {
- sres = window_pane_search(wp, data->arg, &line);
+ sres = window_pane_search(wp, str, &line);
if (sres == NULL &&
fnmatch(searchstr, wp->base.title, 0) != 0)
continue;
@@ -105,7 +107,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
xfree(searchstr);
if (ARRAY_LENGTH(&list_idx) == 0) {
- ctx->error(ctx, "no windows matching: %s", data->arg);
+ ctx->error(ctx, "no windows matching: %s", str);
ARRAY_FREE(&list_idx);
ARRAY_FREE(&list_ctx);
return (-1);
@@ -134,11 +136,11 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
cdata = xmalloc(sizeof *cdata);
- if (session_index(s, &cdata->session) != 0)
- fatalx("session not found");
+ cdata->session = s;
+ cdata->session->references++;
- window_choose_ready(
- wl->window->active, 0, cmd_find_window_callback, xfree, cdata);
+ window_choose_ready(wl->window->active,
+ 0, cmd_find_window_callback, cmd_find_window_free, cdata);
out:
ARRAY_FREE(&list_idx);
@@ -151,12 +153,24 @@ void
cmd_find_window_callback(void *data, int idx)
{
struct cmd_find_window_data *cdata = data;
- struct session *s;
+ struct session *s = cdata->session;
- if (idx != -1 && cdata->session <= ARRAY_LENGTH(&sessions) - 1) {
- s = ARRAY_ITEM(&sessions, cdata->session);
- if (s != NULL && session_select(s, idx) == 0)
- server_redraw_session(s);
+ if (idx == -1)
+ return;
+ if (!session_alive(s))
+ return;
+
+ if (session_select(s, idx) == 0) {
+ server_redraw_session(s);
recalculate_sizes();
}
}
+
+void
+cmd_find_window_free(void *data)
+{
+ struct cmd_find_window_data *cdata = data;
+
+ cdata->session->references--;
+ xfree(cdata);
+}
diff --git a/cmd-find-window.o b/cmd-find-window.o
new file mode 100644
index 0000000..5bad5fc
--- a/dev/null
+++ b/cmd-find-window.o
Binary files differ
diff --git a/cmd-generic.c b/cmd-generic.c
deleted file mode 100644
index 17871d1..0000000
--- a/cmd-generic.c
+++ b/dev/null
@@ -1,423 +0,0 @@
-/* $Id: cmd-generic.c,v 1.38 2009/12/04 22:14:47 tcunha Exp $ */
-
-/*
- * Copyright (c) 2008 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "tmux.h"
-
-int cmd_getopt(int, char **, const char *, const char *);
-int cmd_parse_flags(int, const char *, uint64_t *);
-size_t cmd_print_flags(char *, size_t, size_t, uint64_t);
-int cmd_fill_argument(int, char **, char **, int, char **);
-
-size_t
-cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
-{
- if (strchr(arg, ' ') != NULL)
- return (xsnprintf(buf, len, "%s\"%s\"", prefix, arg));
- return (xsnprintf(buf, len, "%s%s", prefix, arg));
-}
-
-/* Append two flag strings together and call getopt. */
-int
-cmd_getopt(int argc, char **argv, const char *flagstr, const char *chflagstr)
-{
- char tmp[BUFSIZ];
-
- if (strlcpy(tmp, flagstr, sizeof tmp) >= sizeof tmp)
- fatalx("strlcpy overflow");
- if (strlcat(tmp, chflagstr, sizeof tmp) >= sizeof tmp)
- fatalx("strlcat overflow");
- return (getopt(argc, argv, tmp));
-}
-
-/* Return if flag character is set. */
-int
-cmd_check_flag(uint64_t chflags, int flag)
-{
- if (flag >= 'A' && flag <= 'Z')
- flag = 26 + flag - 'A';
- else if (flag >= 'a' && flag <= 'z')
- flag = flag - 'a';
- else
- return (0);
- return ((chflags & (1ULL << flag)) != 0);
-}
-
-/* Set flag character. */
-void
-cmd_set_flag(uint64_t *chflags, int flag)
-{
- if (flag >= 'A' && flag <= 'Z')
- flag = 26 + flag - 'A';
- else if (flag >= 'a' && flag <= 'z')
- flag = flag - 'a';
- else
- return;
- (*chflags) |= (1ULL << flag);
-}
-
-/* If this option is expected, set it in chflags, otherwise return -1. */
-int
-cmd_parse_flags(int opt, const char *chflagstr, uint64_t *chflags)
-{
- if (strchr(chflagstr, opt) == NULL)
- return (-1);
- cmd_set_flag(chflags, opt);
- return (0);
-}
-
-/* Print the flags present in chflags. */
-size_t
-cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags)
-{
- u_char ch;
- size_t boff = off;
-
- if (chflags == 0)
- return (0);
- off += xsnprintf(buf + off, len - off, " -");
-
- for (ch = 0; ch < 26; ch++) {
- if (cmd_check_flag(chflags, 'a' + ch))
- off += xsnprintf(buf + off, len - off, "%c", 'a' + ch);
- if (cmd_check_flag(chflags, 'A' + ch))
- off += xsnprintf(buf + off, len - off, "%c", 'A' + ch);
- }
- return (off - boff);
-}
-
-int
-cmd_fill_argument(int flags, char **arg, char **arg2, int argc, char **argv)
-{
- *arg = NULL;
- *arg2 = NULL;
-
- if (flags & CMD_ARG1) {
- if (argc != 1)
- return (-1);
- *arg = xstrdup(argv[0]);
- return (0);
- }
-
- if (flags & CMD_ARG01) {
- if (argc != 0 && argc != 1)
- return (-1);
- if (argc == 1)
- *arg = xstrdup(argv[0]);
- return (0);
- }
-
- if (flags & CMD_ARG2) {
- if (argc != 2)
- return (-1);
- *arg = xstrdup(argv[0]);
- *arg2 = xstrdup(argv[1]);
- return (0);
- }
-
- if (flags & CMD_ARG12) {
- if (argc != 1 && argc != 2)
- return (-1);
- *arg = xstrdup(argv[0]);
- if (argc == 2)
- *arg2 = xstrdup(argv[1]);
- return (0);
- }
-
- if (argc != 0)
- return (-1);
- return (0);
-}
-
-/* ARGSUSED */
-void
-cmd_target_init(struct cmd *self, unused int key)
-{
- struct cmd_target_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->chflags = 0;
- data->target = NULL;
- data->arg = NULL;
- data->arg2 = NULL;
-}
-
-int
-cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_target_data *data;
- const struct cmd_entry *entry = self->entry;
- int opt;
-
- /* Don't use the entry version since it may be dependent on key. */
- cmd_target_init(self, 0);
- data = self->data;
-
- while ((opt = cmd_getopt(argc, argv, "t:", entry->chflags)) != -1) {
- if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
- continue;
- switch (opt) {
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (cmd_fill_argument(
- self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
- goto usage;
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
-}
-
-void
-cmd_target_free(struct cmd *self)
-{
- struct cmd_target_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- if (data->arg != NULL)
- xfree(data->arg);
- if (data->arg2 != NULL)
- xfree(data->arg2);
- xfree(data);
-}
-
-size_t
-cmd_target_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_target_data *data = self->data;
- size_t off = 0;
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return (off);
- off += cmd_print_flags(buf, len, off, data->chflags);
- if (off < len && data->target != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->target);
- if (off < len && data->arg != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->arg);
- if (off < len && data->arg2 != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->arg2);
- return (off);
-}
-
-/* ARGSUSED */
-void
-cmd_srcdst_init(struct cmd *self, unused int key)
-{
- struct cmd_srcdst_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->chflags = 0;
- data->src = NULL;
- data->dst = NULL;
- data->arg = NULL;
- data->arg2 = NULL;
-}
-
-int
-cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_srcdst_data *data;
- const struct cmd_entry *entry = self->entry;
- int opt;
-
- cmd_srcdst_init(self, 0);
- data = self->data;
-
- while ((opt = cmd_getopt(argc, argv, "s:t:", entry->chflags)) != -1) {
- if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
- continue;
- switch (opt) {
- case 's':
- if (data->src == NULL)
- data->src = xstrdup(optarg);
- break;
- case 't':
- if (data->dst == NULL)
- data->dst = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (cmd_fill_argument(
- self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
- goto usage;
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
-}
-
-void
-cmd_srcdst_free(struct cmd *self)
-{
- struct cmd_srcdst_data *data = self->data;
-
- if (data->src != NULL)
- xfree(data->src);
- if (data->dst != NULL)
- xfree(data->dst);
- if (data->arg != NULL)
- xfree(data->arg);
- if (data->arg2 != NULL)
- xfree(data->arg2);
- xfree(data);
-}
-
-size_t
-cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_srcdst_data *data = self->data;
- size_t off = 0;
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return (off);
- off += cmd_print_flags(buf, len, off, data->chflags);
- if (off < len && data->src != NULL)
- off += xsnprintf(buf + off, len - off, " -s %s", data->src);
- if (off < len && data->dst != NULL)
- off += xsnprintf(buf + off, len - off, " -t %s", data->dst);
- if (off < len && data->arg != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->arg);
- if (off < len && data->arg2 != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->arg2);
- return (off);
-}
-
-/* ARGSUSED */
-void
-cmd_buffer_init(struct cmd *self, unused int key)
-{
- struct cmd_buffer_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->chflags = 0;
- data->target = NULL;
- data->buffer = -1;
- data->arg = NULL;
- data->arg2 = NULL;
-}
-
-int
-cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_buffer_data *data;
- const struct cmd_entry *entry = self->entry;
- int opt, n;
- const char *errstr;
-
- cmd_buffer_init(self, 0);
- data = self->data;
-
- while ((opt = cmd_getopt(argc, argv, "b:t:", entry->chflags)) != -1) {
- if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
- continue;
- switch (opt) {
- case 'b':
- if (data->buffer == -1) {
- n = strtonum(optarg, 0, INT_MAX, &errstr);
- if (errstr != NULL) {
- xasprintf(cause, "buffer %s", errstr);
- goto error;
- }
- data->buffer = n;
- }
- break;
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (cmd_fill_argument(
- self->entry->flags, &data->arg, &data->arg2, argc, argv) != 0)
- goto usage;
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
-error:
- self->entry->free(self);
- return (-1);
-}
-
-void
-cmd_buffer_free(struct cmd *self)
-{
- struct cmd_buffer_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- if (data->arg != NULL)
- xfree(data->arg);
- if (data->arg2 != NULL)
- xfree(data->arg2);
- xfree(data);
-}
-
-size_t
-cmd_buffer_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_buffer_data *data = self->data;
- size_t off = 0;
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return (off);
- off += cmd_print_flags(buf, len, off, data->chflags);
- if (off < len && data->buffer != -1)
- off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
- if (off < len && data->target != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->target);
- if (off < len && data->arg != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->arg);
- if (off < len && data->arg2 != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->arg2);
- return (off);
-}
diff --git a/cmd-generic.o b/cmd-generic.o
new file mode 100644
index 0000000..23129c8
--- a/dev/null
+++ b/cmd-generic.o
Binary files differ
diff --git a/cmd-has-session.c b/cmd-has-session.c
index fe81099..9deb127 100644
--- a/cmd-has-session.c
+++ b/cmd-has-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-has-session.c,v 1.15 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-has-session.c,v 1.16 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,21 +28,20 @@ int cmd_has_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
+ "t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_has_session_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_has_session_exec
};
int
cmd_has_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
- if (cmd_find_session(ctx, data->target) == NULL)
+ if (cmd_find_session(ctx, args_get(args, 't')) == NULL)
return (-1);
return (0);
diff --git a/cmd-has-session.o b/cmd-has-session.o
new file mode 100644
index 0000000..30f8518
--- a/dev/null
+++ b/cmd-has-session.o
Binary files differ
diff --git a/cmd-if-shell.c b/cmd-if-shell.c
index 08d20e3..21f9676 100644
--- a/cmd-if-shell.c
+++ b/cmd-if-shell.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-if-shell.c,v 1.10 2010/08/09 21:44:25 tcunha Exp $ */
+/* $Id: cmd-if-shell.c,v 1.11 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <[email protected]>
@@ -35,13 +35,12 @@ void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
+ "", 2, 2,
"shell-command command",
- CMD_ARG2, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_if_shell_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_if_shell_exec
};
struct cmd_if_shell_data {
@@ -52,12 +51,12 @@ struct cmd_if_shell_data {
int
cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_if_shell_data *cdata;
struct job *job;
cdata = xmalloc(sizeof *cdata);
- cdata->cmd = xstrdup(data->arg2);
+ cdata->cmd = xstrdup(args->argv[1]);
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
@@ -66,7 +65,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->curclient->references++;
job = job_add(NULL, 0, NULL,
- data->arg, cmd_if_shell_callback, cmd_if_shell_free, cdata);
+ args->argv[0], cmd_if_shell_callback, cmd_if_shell_free, cdata);
job_run(job);
return (1); /* don't let client exit */
diff --git a/cmd-if-shell.o b/cmd-if-shell.o
new file mode 100644
index 0000000..b04837b
--- a/dev/null
+++ b/cmd-if-shell.o
Binary files differ
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index 4fd31d2..14fb824 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-join-pane.c,v 1.5 2010/08/11 22:17:32 tcunha Exp $ */
+/* $Id: cmd-join-pane.c,v 1.6 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -27,139 +27,54 @@
* Join a pane into another (like split/swap/kill).
*/
-int cmd_join_pane_parse(struct cmd *, int, char **, char **);
+void cmd_join_pane_key_binding(struct cmd *, int);
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",
+ "dhvp:l:s:t:", 0, 0,
"[-dhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
- 0, "",
- cmd_join_pane_init,
- cmd_join_pane_parse,
- cmd_join_pane_exec,
- cmd_join_pane_free,
- cmd_join_pane_print
+ 0,
+ cmd_join_pane_key_binding,
+ NULL,
+ cmd_join_pane_exec
};
void
-cmd_join_pane_init(struct cmd *self, int key)
+cmd_join_pane_key_binding(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;
+ self->args = args_create(0);
+ args_set(self->args, 'h', NULL);
break;
- case '"':
- data->flag_horizontal = 0;
+ default:
+ self->args = args_create(0);
break;
}
}
int
-cmd_join_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_join_pane_data *data;
- int opt;
- const char *errstr;
-
- self->entry->init(self, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "dhl:p:s:t:v")) != -1) {
- switch (opt) {
- case 'd':
- data->flag_detached = 1;
- break;
- case 'h':
- data->flag_horizontal = 1;
- break;
- case 's':
- if (data->src == NULL)
- data->src = xstrdup(optarg);
- break;
- case 't':
- if (data->dst == NULL)
- data->dst = xstrdup(optarg);
- break;
- case 'l':
- if (data->percentage != -1 || data->size != -1)
- break;
- data->size = strtonum(optarg, 1, INT_MAX, &errstr);
- if (errstr != NULL) {
- xasprintf(cause, "size %s", errstr);
- goto error;
- }
- break;
- case 'p':
- if (data->size != -1 || data->percentage != -1)
- break;
- data->percentage = strtonum(optarg, 1, 100, &errstr);
- if (errstr != NULL) {
- xasprintf(cause, "percentage %s", errstr);
- goto error;
- }
- break;
- case 'v':
- data->flag_horizontal = 0;
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 0)
- goto usage;
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
-error:
- self->entry->free(self);
- return (-1);
-}
-
-int
cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_join_pane_data *data = self->data;
- struct session *dst_s;
- struct winlink *src_wl, *dst_wl;
- struct window *src_w, *dst_w;
- struct window_pane *src_wp, *dst_wp;
- int size, dst_idx;
- enum layout_type type;
- struct layout_cell *lc;
-
- if ((dst_wl = cmd_find_pane(ctx, data->dst, &dst_s, &dst_wp)) == NULL)
+ struct args *args = self->args;
+ struct session *dst_s;
+ struct winlink *src_wl, *dst_wl;
+ struct window *src_w, *dst_w;
+ struct window_pane *src_wp, *dst_wp;
+ char *cause;
+ int size, percentage, dst_idx;
+ enum layout_type type;
+ struct layout_cell *lc;
+
+ dst_wl = cmd_find_pane(ctx, args_get(args, 't'), &dst_s, &dst_wp);
+ if (dst_wl == NULL)
return (-1);
dst_w = dst_wl->window;
dst_idx = dst_wl->idx;
- if ((src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp)) == NULL)
+ src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp);
+ if (src_wl == NULL)
return (-1);
src_w = src_wl->window;
@@ -169,17 +84,28 @@ cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
type = LAYOUT_TOPBOTTOM;
- if (data->flag_horizontal)
+ if (args_has(args, 'h'))
type = LAYOUT_LEFTRIGHT;
size = -1;
- if (data->size != -1)
- size = data->size;
- else if (data->percentage != -1) {
+ if (args_has(args, 's')) {
+ size = args_strtonum(args, 's', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "size %s", cause);
+ xfree(cause);
+ return (-1);
+ }
+ } else if (args_has(args, 'p')) {
+ percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "percentage %s", cause);
+ xfree(cause);
+ return (-1);
+ }
if (type == LAYOUT_TOPBOTTOM)
- size = (dst_wp->sy * data->percentage) / 100;
+ size = (dst_wp->sy * percentage) / 100;
else
- size = (dst_wp->sx * data->percentage) / 100;
+ size = (dst_wp->sx * percentage) / 100;
}
if ((lc = layout_split_pane(dst_wp, type, size)) == NULL) {
@@ -208,7 +134,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_window(src_w);
server_redraw_window(dst_w);
- if (!data->flag_detached) {
+ if (!args_has(args, 'd')) {
window_set_active_pane(dst_w, src_wp);
session_select(dst_s, dst_idx);
server_redraw_session(dst_s);
@@ -217,41 +143,3 @@ cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
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);
-}
diff --git a/cmd-join-pane.o b/cmd-join-pane.o
new file mode 100644
index 0000000..0c123b6
--- a/dev/null
+++ b/cmd-join-pane.o
Binary files differ
diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c
index 7df68b7..0a67415 100644
--- a/cmd-kill-pane.c
+++ b/cmd-kill-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-pane.c,v 1.15 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-kill-pane.c,v 1.16 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -30,23 +30,22 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp",
+ "at:", 0, 0,
"[-a] " CMD_TARGET_PANE_USAGE,
- 0, "a",
- cmd_target_init,
- cmd_target_parse,
- cmd_kill_pane_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_kill_pane_exec
};
int
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
struct window_pane *loopwp, *nextwp, *wp;
- if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
+ if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL)
return (-1);
if (window_count_panes(wl->window) == 1) {
@@ -56,7 +55,7 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
- if (cmd_check_flag(data->chflags, 'a')) {
+ if (args_has(self->args, 'a')) {
loopwp = TAILQ_FIRST(&wl->window->panes);
while (loopwp != NULL) {
nextwp = TAILQ_NEXT(loopwp, entry);
diff --git a/cmd-kill-pane.o b/cmd-kill-pane.o
new file mode 100644
index 0000000..24cffd6
--- a/dev/null
+++ b/cmd-kill-pane.o
Binary files differ
diff --git a/cmd-kill-server.c b/cmd-kill-server.c
index 2f3d268..145a9fa 100644
--- a/cmd-kill-server.c
+++ b/cmd-kill-server.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-server.c,v 1.11 2009/11/28 14:50:36 tcunha Exp $ */
+/* $Id: cmd-kill-server.c,v 1.12 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -31,13 +31,12 @@ int cmd_kill_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_server_entry = {
"kill-server", NULL,
+ "", 0, 0,
"",
- 0, "",
+ 0,
NULL,
NULL,
- cmd_kill_server_exec,
- NULL,
- NULL
+ cmd_kill_server_exec
};
/* ARGSUSED */
diff --git a/cmd-kill-server.o b/cmd-kill-server.o
new file mode 100644
index 0000000..d18027f
--- a/dev/null
+++ b/cmd-kill-server.o
Binary files differ
diff --git a/cmd-kill-session.c b/cmd-kill-session.c
index 8c3daa7..116e257 100644
--- a/cmd-kill-session.c
+++ b/cmd-kill-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-session.c,v 1.18 2010/07/02 02:43:50 tcunha Exp $ */
+/* $Id: cmd-kill-session.c,v 1.19 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -31,22 +31,21 @@ int cmd_kill_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL,
+ "t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_kill_session_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_kill_session_exec
};
int
cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
+ struct args *args = self->args;
+ struct session *s;
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL)
return (-1);
server_destroy_session(s);
diff --git a/cmd-kill-session.o b/cmd-kill-session.o
new file mode 100644
index 0000000..3357f51
--- a/dev/null
+++ b/cmd-kill-session.o
Binary files differ
diff --git a/cmd-kill-window.c b/cmd-kill-window.c
index 8b97c64..1673c95 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-window.c,v 1.21 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-kill-window.c,v 1.22 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,22 +28,21 @@ int cmd_kill_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw",
+ "t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_kill_window_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_kill_window_exec
};
int
cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct winlink *wl;
+ struct args *args = self->args;
+ struct winlink *wl;
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
server_kill_window(wl->window);
diff --git a/cmd-kill-window.o b/cmd-kill-window.o
new file mode 100644
index 0000000..fb534ab
--- a/dev/null
+++ b/cmd-kill-window.o
Binary files differ
diff --git a/cmd-last-pane.o b/cmd-last-pane.o
new file mode 100644
index 0000000..b00b8cb
--- a/dev/null
+++ b/cmd-last-pane.o
Binary files differ
diff --git a/cmd-last-window.c b/cmd-last-window.c
deleted file mode 100644
index c004ea0..0000000
--- a/cmd-last-window.c
+++ b/dev/null
@@ -1,58 +0,0 @@
-/* $Id: cmd-last-window.c,v 1.19 2009/11/14 17:56:39 tcunha Exp $ */
-
-/*
- * Copyright (c) 2007 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include "tmux.h"
-
-/*
- * Move to last window.
- */
-
-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, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_last_window_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-int
-cmd_last_window_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_target_data *data = self->data;
- struct session *s;
-
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
-
- if (session_last(s) == 0)
- server_redraw_session(s);
- else {
- ctx->error(ctx, "no last window");
- return (-1);
- }
- recalculate_sizes();
-
- return (0);
-}
diff --git a/cmd-last-window.o b/cmd-last-window.o
new file mode 100644
index 0000000..83f6e71
--- a/dev/null
+++ b/cmd-last-window.o
Binary files differ
diff --git a/cmd-link-window.c b/cmd-link-window.c
index 34d0c31..009834c 100644
--- a/cmd-link-window.c
+++ b/cmd-link-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-link-window.c,v 1.36 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-link-window.c,v 1.37 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,31 +30,30 @@ int cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
+ "dks:t:", 0, 0,
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
- 0, "dk",
- cmd_srcdst_init,
- cmd_srcdst_parse,
- cmd_link_window_exec,
- cmd_srcdst_free,
- cmd_srcdst_print
+ 0,
+ NULL,
+ NULL,
+ cmd_link_window_exec
};
int
cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_srcdst_data *data = self->data;
- struct session *src, *dst;
- struct winlink *wl;
- char *cause;
- int idx, kflag, dflag;
+ struct args *args = self->args;
+ struct session *src, *dst;
+ struct winlink *wl;
+ char *cause;
+ int idx, kflag, dflag;
- if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 's'), &src)) == NULL)
return (-1);
- if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
+ if ((idx = cmd_find_index(ctx, args_get(args, 't'), &dst)) == -2)
return (-1);
- kflag = cmd_check_flag(data->chflags, 'k');
- dflag = cmd_check_flag(data->chflags, 'd');
+ kflag = args_has(self->args, 'k');
+ dflag = args_has(self->args, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't link window: %s", cause);
xfree(cause);
diff --git a/cmd-link-window.o b/cmd-link-window.o
new file mode 100644
index 0000000..b1be6aa
--- a/dev/null
+++ b/cmd-link-window.o
Binary files differ
diff --git a/cmd-list-buffers.c b/cmd-list-buffers.c
index f456821..89d6af2 100644
--- a/cmd-list-buffers.c
+++ b/cmd-list-buffers.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-buffers.c,v 1.16 2010/06/22 23:35:20 tcunha Exp $ */
+/* $Id: cmd-list-buffers.c,v 1.18 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,29 +30,24 @@ 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, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_list_buffers_exec,
- cmd_target_free,
- cmd_target_print
+ "", 0, 0,
+ "",
+ 0,
+ NULL,
+ NULL,
+ cmd_list_buffers_exec
};
+/* ARGSUSED */
int
-cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
+cmd_list_buffers_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
struct paste_buffer *pb;
u_int idx;
char *tmp;
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
-
idx = 0;
- while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
+ while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
tmp = paste_print(pb, 50);
ctx->print(ctx,
"%u: %zu bytes: \"%s\"", idx - 1, pb->size, tmp);
diff --git a/cmd-list-buffers.o b/cmd-list-buffers.o
new file mode 100644
index 0000000..d3b24e7
--- a/dev/null
+++ b/cmd-list-buffers.o
Binary files differ
diff --git a/cmd-list-clients.c b/cmd-list-clients.c
index 16c2549..86e2a06 100644
--- a/cmd-list-clients.c
+++ b/cmd-list-clients.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-clients.c,v 1.20 2009/11/28 14:50:36 tcunha Exp $ */
+/* $Id: cmd-list-clients.c,v 1.21 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -31,13 +31,12 @@ int cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc",
+ "", 0, 0,
"",
- 0, "",
+ 0,
NULL,
NULL,
- cmd_list_clients_exec,
- NULL,
- NULL
+ cmd_list_clients_exec
};
/* ARGSUSED */
diff --git a/cmd-list-clients.o b/cmd-list-clients.o
new file mode 100644
index 0000000..a651431
--- a/dev/null
+++ b/cmd-list-clients.o
Binary files differ
diff --git a/cmd-list-commands.c b/cmd-list-commands.c
index 8a1238c..a1b9d72 100644
--- a/cmd-list-commands.c
+++ b/cmd-list-commands.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-commands.c,v 1.7 2009/11/28 14:50:36 tcunha Exp $ */
+/* $Id: cmd-list-commands.c,v 1.8 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,13 +28,12 @@ int cmd_list_commands_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm",
+ "", 0, 0,
"",
- 0, "",
+ 0,
NULL,
NULL,
- cmd_list_commands_exec,
- NULL,
- NULL
+ cmd_list_commands_exec
};
/* ARGSUSED */
diff --git a/cmd-list-commands.o b/cmd-list-commands.o
new file mode 100644
index 0000000..b401bd7
--- a/dev/null
+++ b/cmd-list-commands.o
Binary files differ
diff --git a/cmd-list-keys.c b/cmd-list-keys.c
index 4a02b1c..96b09b9 100644
--- a/cmd-list-keys.c
+++ b/cmd-list-keys.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-keys.c,v 1.24 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-list-keys.c,v 1.26 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -32,26 +32,25 @@ int cmd_list_keys_table(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk",
+ "t:", 0, 0,
"[-t key-table]",
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_list_keys_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_list_keys_exec
};
int
cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct key_binding *bd;
const char *key;
char tmp[BUFSIZ];
size_t used;
int width, keywidth;
- if (data->target != NULL)
+ if (args_has(args, 't'))
return (cmd_list_keys_table(self, ctx));
width = 0;
@@ -80,6 +79,11 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
if (used >= sizeof tmp)
continue;
}
+ if (bd->can_repeat) {
+ used = strlcat(tmp, "(repeat) ", sizeof tmp);
+ if (used >= sizeof tmp)
+ continue;
+ }
cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
ctx->print(ctx, "%s", tmp);
}
@@ -90,14 +94,16 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
int
cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
+ const char *tablename;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind;
const char *key, *cmdstr, *mode;
int width, keywidth;
- if ((mtab = mode_key_findtable(data->target)) == NULL) {
- ctx->error(ctx, "unknown key table: %s", data->target);
+ tablename = args_get(args, 't');
+ if ((mtab = mode_key_findtable(tablename)) == NULL) {
+ ctx->error(ctx, "unknown key table: %s", tablename);
return (-1);
}
diff --git a/cmd-list-keys.o b/cmd-list-keys.o
new file mode 100644
index 0000000..f2dd227
--- a/dev/null
+++ b/cmd-list-keys.o
Binary files differ
diff --git a/cmd-list-panes.c b/cmd-list-panes.c
index c542aa0..72e8edc 100644
--- a/cmd-list-panes.c
+++ b/cmd-list-panes.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-panes.c,v 1.5 2010/08/11 22:14:23 tcunha Exp $ */
+/* $Id: cmd-list-panes.c,v 1.7 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -30,19 +30,18 @@ int cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
+ "t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_list_panes_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_list_panes_exec
};
int
cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
struct window_pane *wp;
struct grid *gd;
@@ -50,7 +49,7 @@ cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
u_int i, n;
unsigned long long size;
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
n = 0;
@@ -65,9 +64,10 @@ cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
}
size += gd->hsize * sizeof *gd->linedata;
- ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes]%s",
+ ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes]%s%s",
n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size,
- wp == wp->window->active ? " (active)" : "");
+ wp == wp->window->active ? " (active)" : "",
+ wp->fd == -1 ? " (dead)" : "");
n++;
}
diff --git a/cmd-list-panes.o b/cmd-list-panes.o
new file mode 100644
index 0000000..24375db
--- a/dev/null
+++ b/cmd-list-panes.o
Binary files differ
diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c
index 48e294c..183a779 100644
--- a/cmd-list-sessions.c
+++ b/cmd-list-sessions.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-sessions.c,v 1.25 2009/11/28 14:50:36 tcunha Exp $ */
+/* $Id: cmd-list-sessions.c,v 1.27 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,13 +30,13 @@
int cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = {
- "list-sessions", "ls", "",
- 0, "",
+ "list-sessions", "ls",
+ "", 0, 0,
+ "",
+ 0,
NULL,
NULL,
- cmd_list_sessions_exec,
- NULL,
- NULL
+ cmd_list_sessions_exec
};
/* ARGSUSED */
@@ -46,14 +46,10 @@ cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct session_group *sg;
char *tim, tmp[64];
- u_int i, idx;
+ u_int idx;
time_t t;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s == NULL)
- continue;
-
+ RB_FOREACH(s, sessions, &sessions) {
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
diff --git a/cmd-list-sessions.o b/cmd-list-sessions.o
new file mode 100644
index 0000000..b4b8320
--- a/dev/null
+++ b/cmd-list-sessions.o
Binary files differ
diff --git a/cmd-list-windows.c b/cmd-list-windows.c
index b0bcbb7..29feabb 100644
--- a/cmd-list-windows.c
+++ b/cmd-list-windows.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-windows.c,v 1.43 2010/07/02 02:54:52 tcunha Exp $ */
+/* $Id: cmd-list-windows.c,v 1.45 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,31 +30,30 @@ int cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw",
+ "t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_list_windows_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_list_windows_exec
};
int
cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
- struct winlink *wl;
- char *layout;
+ struct args *args = self->args;
+ struct session *s;
+ struct winlink *wl;
+ char *layout;
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL)
return (-1);
RB_FOREACH(wl, winlinks, &s->windows) {
- ctx->print(ctx, "%d: %s [%ux%u]",
- wl->idx, wl->window->name, wl->window->sx, wl->window->sy);
layout = layout_dump(wl->window);
- ctx->print(ctx, " layout: %s", layout);
+ ctx->print(ctx, "%d: %s [%ux%u] [layout %s]%s",
+ wl->idx, wl->window->name, wl->window->sx, wl->window->sy,
+ layout, wl == s->curw ? " (active)" : "");
xfree(layout);
}
diff --git a/cmd-list-windows.o b/cmd-list-windows.o
new file mode 100644
index 0000000..f46de24
--- a/dev/null
+++ b/cmd-list-windows.o
Binary files differ
diff --git a/cmd-list.c b/cmd-list.c
index c1ebd86..ec70ed2 100644
--- a/cmd-list.c
+++ b/cmd-list.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list.c,v 1.9 2010/07/02 02:43:01 tcunha Exp $ */
+/* $Id: cmd-list.c,v 1.10 2010/12/06 21:48:56 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -29,7 +29,9 @@ cmd_list_parse(int argc, char **argv, char **cause)
struct cmd *cmd;
int i, lastsplit;
size_t arglen, new_argc;
- char **new_argv;
+ char **copy_argv, **new_argv;
+
+ copy_argv = cmd_copy_argv(argc, argv);
cmdlist = xmalloc(sizeof *cmdlist);
cmdlist->references = 1;
@@ -37,18 +39,18 @@ cmd_list_parse(int argc, char **argv, char **cause)
lastsplit = 0;
for (i = 0; i < argc; i++) {
- arglen = strlen(argv[i]);
- if (arglen == 0 || argv[i][arglen - 1] != ';')
+ arglen = strlen(copy_argv[i]);
+ if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
continue;
- argv[i][arglen - 1] = '\0';
+ copy_argv[i][arglen - 1] = '\0';
- if (arglen > 1 && argv[i][arglen - 2] == '\\') {
- argv[i][arglen - 2] = ';';
+ if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
+ copy_argv[i][arglen - 2] = ';';
continue;
}
new_argc = i - lastsplit;
- new_argv = argv + lastsplit;
+ new_argv = copy_argv + lastsplit;
if (arglen != 1)
new_argc++;
@@ -61,16 +63,18 @@ cmd_list_parse(int argc, char **argv, char **cause)
}
if (lastsplit != argc) {
- cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
+ cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
}
+ cmd_free_argv(argc, copy_argv);
return (cmdlist);
bad:
cmd_list_free(cmdlist);
+ cmd_free_argv(argc, copy_argv);
return (NULL);
}
diff --git a/cmd-list.o b/cmd-list.o
new file mode 100644
index 0000000..b36e4ee
--- a/dev/null
+++ b/cmd-list.o
Binary files differ
diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c
index 6147555..402edd7 100644
--- a/cmd-load-buffer.c
+++ b/cmd-load-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-load-buffer.c,v 1.17 2010/08/09 21:44:25 tcunha Exp $ */
+/* $Id: cmd-load-buffer.c,v 1.20 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <[email protected]>
@@ -35,54 +35,57 @@ void cmd_load_buffer_callback(struct client *, void *);
const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb",
- CMD_BUFFER_SESSION_USAGE " path",
- CMD_ARG1, "",
- cmd_buffer_init,
- cmd_buffer_parse,
- cmd_load_buffer_exec,
- cmd_buffer_free,
- cmd_buffer_print
-};
-
-struct cmd_load_buffer_cdata {
- struct session *session;
- int buffer;
+ "b:", 1, 1,
+ CMD_BUFFER_USAGE " path",
+ 0,
+ NULL,
+ NULL,
+ cmd_load_buffer_exec
};
int
cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_buffer_data *data = self->data;
- struct cmd_load_buffer_cdata *cdata;
- struct session *s;
- struct client *c = ctx->cmdclient;
- FILE *f;
- char *pdata, *new_pdata;
- size_t psize;
- u_int limit;
- int ch;
-
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
+ struct args *args = self->args;
+ struct client *c = ctx->cmdclient;
+ FILE *f;
+ const char *path;
+ char *pdata, *new_pdata, *cause;
+ size_t psize;
+ u_int limit;
+ int ch, buffer;
+ int *buffer_ptr;
+
+ if (!args_has(args, 'b'))
+ buffer = -1;
+ else {
+ buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "buffer %s", cause);
+ xfree(cause);
+ return (-1);
+ }
+ }
- if (strcmp(data->arg, "-") == 0) {
+ path = args->argv[0];
+ if (strcmp(path, "-") == 0) {
if (c == NULL) {
- ctx->error(ctx, "%s: can't read from stdin", data->arg);
+ ctx->error(ctx, "%s: can't read from stdin", path);
return (-1);
}
if (c->flags & CLIENT_TERMINAL) {
- ctx->error(ctx, "%s: stdin is a tty", data->arg);
+ ctx->error(ctx, "%s: stdin is a tty", path);
return (-1);
}
if (c->stdin_fd == -1) {
- ctx->error(ctx, "%s: can't read from stdin", data->arg);
+ ctx->error(ctx, "%s: can't read from stdin", path);
return (-1);
}
- cdata = xmalloc(sizeof *cdata);
- cdata->session = s;
- cdata->buffer = data->buffer;
- c->stdin_data = cdata;
+ buffer_ptr = xmalloc(sizeof *buffer_ptr);
+ *buffer_ptr = buffer;
+
+ c->stdin_data = buffer_ptr;
c->stdin_callback = cmd_load_buffer_callback;
c->references++;
@@ -90,8 +93,8 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
return (1);
}
- if ((f = fopen(data->arg, "rb")) == NULL) {
- ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
+ if ((f = fopen(path, "rb")) == NULL) {
+ ctx->error(ctx, "%s: %s", path, strerror(errno));
return (-1);
}
@@ -107,22 +110,21 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
pdata[psize++] = ch;
}
if (ferror(f)) {
- ctx->error(ctx, "%s: read error", data->arg);
+ ctx->error(ctx, "%s: read error", path);
goto error;
}
if (pdata != NULL)
pdata[psize] = '\0';
fclose(f);
- f = NULL;
- limit = options_get_number(&s->options, "buffer-limit");
- if (data->buffer == -1) {
- paste_add(&s->buffers, pdata, psize, limit);
+ limit = options_get_number(&global_options, "buffer-limit");
+ if (buffer == -1) {
+ paste_add(&global_buffers, pdata, psize, limit);
return (0);
}
- if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
- ctx->error(ctx, "no buffer %d", data->buffer);
+ if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
+ ctx->error(ctx, "no buffer %d", buffer);
return (-1);
}
@@ -139,12 +141,10 @@ error:
void
cmd_load_buffer_callback(struct client *c, void *data)
{
- struct cmd_load_buffer_cdata *cdata = data;
- struct session *s = cdata->session;
- char *pdata;
- size_t psize;
- u_int limit;
- int idx;
+ int *buffer = data;
+ char *pdata;
+ size_t psize;
+ u_int limit;
/*
* Event callback has already checked client is not dead and reduced
@@ -152,33 +152,23 @@ cmd_load_buffer_callback(struct client *c, void *data)
*/
c->flags |= CLIENT_EXIT;
- /* Does the target session still exist? */
- if (session_index(s, &idx) != 0)
- goto out;
-
psize = EVBUFFER_LENGTH(c->stdin_event->input);
- if (psize == 0)
- goto out;
-
- pdata = malloc(psize + 1);
- if (pdata == NULL)
- goto out;
+ if (psize == 0 || (pdata = malloc(psize + 1)) == NULL) {
+ free(data);
+ return;
+ }
bufferevent_read(c->stdin_event, pdata, psize);
pdata[psize] = '\0';
- limit = options_get_number(&s->options, "buffer-limit");
- if (cdata->buffer == -1) {
- paste_add(&s->buffers, pdata, psize, limit);
- goto out;
- }
- if (paste_replace(&s->buffers, cdata->buffer, pdata, psize) != 0) {
+ limit = options_get_number(&global_options, "buffer-limit");
+ if (*buffer == -1)
+ paste_add(&global_buffers, pdata, psize, limit);
+ else if (paste_replace(&global_buffers, *buffer, pdata, psize) != 0) {
/* No context so can't use server_client_msg_error. */
evbuffer_add_printf(
- c->stderr_event->output, "no buffer %d\n", cdata->buffer);
+ c->stderr_event->output, "no buffer %d\n", *buffer);
bufferevent_enable(c->stderr_event, EV_WRITE);
- goto out;
}
-out:
- xfree(cdata);
+ free (data);
}
diff --git a/cmd-load-buffer.o b/cmd-load-buffer.o
new file mode 100644
index 0000000..7e915ee
--- a/dev/null
+++ b/cmd-load-buffer.o
Binary files differ
diff --git a/cmd-lock-client.o b/cmd-lock-client.o
new file mode 100644
index 0000000..c441484
--- a/dev/null
+++ b/cmd-lock-client.o
Binary files differ
diff --git a/cmd-lock-server.c b/cmd-lock-server.c
index e008fef..da825d5 100644
--- a/cmd-lock-server.c
+++ b/cmd-lock-server.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-lock-server.c,v 1.9 2009/11/28 14:50:36 tcunha Exp $ */
+/* $Id: cmd-lock-server.c,v 1.11 2011/01/07 15:02:38 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -25,27 +25,60 @@
#include "tmux.h"
/*
- * Lock server.
+ * Lock commands.
*/
int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock",
+ "", 0, 0,
"",
- 0, "",
+ 0,
NULL,
NULL,
- cmd_lock_server_exec,
+ cmd_lock_server_exec
+};
+
+const struct cmd_entry cmd_lock_session_entry = {
+ "lock-session", "locks",
+ "t:", 0, 0,
+ CMD_TARGET_SESSION_USAGE,
+ 0,
NULL,
NULL,
+ cmd_lock_server_exec
+};
+
+const struct cmd_entry cmd_lock_client_entry = {
+ "lock-client", "lockc",
+ "t:", 0, 0,
+ CMD_TARGET_CLIENT_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_lock_server_exec
};
/* ARGSUSED */
int
-cmd_lock_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
+cmd_lock_server_exec(struct cmd *self, unused struct cmd_ctx *ctx)
{
- server_lock();
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+
+ if (self->entry == &cmd_lock_server_entry)
+ server_lock();
+ else if (self->entry == &cmd_lock_session_entry) {
+ if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL)
+ return (-1);
+ server_lock_session(s);
+ } else {
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
+ return (-1);
+ server_lock_client(c);
+ }
recalculate_sizes();
return (0);
diff --git a/cmd-lock-server.o b/cmd-lock-server.o
new file mode 100644
index 0000000..8d18f93
--- a/dev/null
+++ b/cmd-lock-server.o
Binary files differ
diff --git a/cmd-lock-session.o b/cmd-lock-session.o
new file mode 100644
index 0000000..b475f9c
--- a/dev/null
+++ b/cmd-lock-session.o
Binary files differ
diff --git a/cmd-move-window.c b/cmd-move-window.c
index 4cc018b..a43d391 100644
--- a/cmd-move-window.c
+++ b/cmd-move-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-move-window.c,v 1.13 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-move-window.c,v 1.14 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -30,31 +30,30 @@ int cmd_move_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew",
+ "dks:t:", 0, 0,
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
- 0, "dk",
- cmd_srcdst_init,
- cmd_srcdst_parse,
- cmd_move_window_exec,
- cmd_srcdst_free,
- cmd_srcdst_print
+ 0,
+ NULL,
+ NULL,
+ cmd_move_window_exec
};
int
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;
- char *cause;
- int idx, kflag, dflag;
+ struct args *args = self->args;
+ struct session *src, *dst;
+ struct winlink *wl;
+ char *cause;
+ int idx, kflag, dflag;
- if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 's'), &src)) == NULL)
return (-1);
- if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
+ if ((idx = cmd_find_index(ctx, args_get(args, 't'), &dst)) == -2)
return (-1);
- kflag = cmd_check_flag(data->chflags, 'k');
- dflag = cmd_check_flag(data->chflags, 'd');
+ kflag = args_has(self->args, 'k');
+ dflag = args_has(self->args, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't move window: %s", cause);
xfree(cause);
diff --git a/cmd-move-window.o b/cmd-move-window.o
new file mode 100644
index 0000000..fe87bee
--- a/dev/null
+++ b/cmd-move-window.o
Binary files differ
diff --git a/cmd-new-session.c b/cmd-new-session.c
index 891fd80..77968ec 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-new-session.c,v 1.78 2010/07/02 02:49:19 tcunha Exp $ */
+/* $Id: cmd-new-session.c,v 1.83 2011/01/21 23:55:26 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <pwd.h>
+#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
@@ -29,119 +30,59 @@
* Create a new session and attach to the current terminal unless -d is given.
*/
-int cmd_new_session_parse(struct cmd *, int, char **, char **);
+int cmd_new_session_check(struct args *);
int cmd_new_session_exec(struct cmd *, struct cmd_ctx *);
-void cmd_new_session_free(struct cmd *);
-void cmd_new_session_init(struct cmd *, int);
-size_t cmd_new_session_print(struct cmd *, char *, size_t);
-
-struct cmd_new_session_data {
- char *target;
- char *newname;
- char *winname;
- char *cmd;
- int flag_detached;
-};
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
- "[-d] [-n window-name] [-s session-name] [-t target-session] [command]",
- CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, "",
- cmd_new_session_init,
- cmd_new_session_parse,
- cmd_new_session_exec,
- cmd_new_session_free,
- cmd_new_session_print
+ "dn:s:t:x:y:", 0, 1,
+ "[-d] [-n window-name] [-s session-name] [-t target-session] "
+ "[-x width] [-y height] [command]",
+ CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON,
+ NULL,
+ cmd_new_session_check,
+ cmd_new_session_exec
};
-/* ARGSUSED */
-void
-cmd_new_session_init(struct cmd *self, unused int arg)
-{
- struct cmd_new_session_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->flag_detached = 0;
- data->target = NULL;
- data->newname = NULL;
- data->winname = NULL;
- data->cmd = NULL;
-}
-
int
-cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
+cmd_new_session_check(struct args *args)
{
- struct cmd_new_session_data *data;
- int opt;
-
- self->entry->init(self, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "ds:t:n:")) != -1) {
- switch (opt) {
- case 'd':
- data->flag_detached = 1;
- break;
- case 's':
- 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);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- 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]);
-
+ if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n')))
+ return (-1);
+ if (!args_has(args, 'd') &&
+ (args_has(args, 'x') || args_has(args, 'y')))
+ return (-1);
return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
}
int
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_new_session_data *data = self->data;
- struct session *s, *groupwith;
- struct window *w;
- struct window_pane *wp;
- struct environ env;
- struct termios tio, *tiop;
- struct passwd *pw;
- const char *update, *cwd;
- char *overrides, *cmd, *cause;
- int detached, idx;
- u_int sx, sy, i;
-
- if (data->newname != NULL && session_find(data->newname) != NULL) {
- ctx->error(ctx, "duplicate session: %s", data->newname);
+ struct args *args = self->args;
+ struct session *s, *old_s, *groupwith;
+ struct window *w;
+ struct window_pane *wp;
+ struct environ env;
+ struct termios tio, *tiop;
+ struct passwd *pw;
+ const char *newname, *target, *update, *cwd, *errstr;
+ char *overrides, *cmd, *cause;
+ int detached, idx;
+ u_int sx, sy, i;
+
+ newname = args_get(args, 's');
+ if (newname != NULL && session_find(newname) != NULL) {
+ ctx->error(ctx, "duplicate session: %s", newname);
return (-1);
}
- groupwith = NULL;
- if (data->target != NULL &&
- (groupwith = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
+ target = args_get(args, 't');
+ if (target != NULL) {
+ groupwith = cmd_find_session(ctx, target);
+ if (groupwith == NULL)
+ return (-1);
+ } else
+ groupwith = NULL;
/*
* There are three cases:
@@ -162,7 +103,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
*/
/* Set -d if no client. */
- detached = data->flag_detached;
+ detached = args_has(args, 'd');
if (ctx->cmdclient == NULL && ctx->curclient == NULL)
detached = 1;
@@ -213,6 +154,22 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if (detached) {
sx = 80;
sy = 24;
+ if (args_has(args, 'x')) {
+ sx = strtonum(
+ args_get(args, 'x'), 1, USHRT_MAX, &errstr);
+ if (errstr != NULL) {
+ ctx->error(ctx, "width %s", errstr);
+ return (-1);
+ }
+ }
+ if (args_has(args, 'y')) {
+ sy = strtonum(
+ args_get(args, 'y'), 1, USHRT_MAX, &errstr);
+ if (errstr != NULL) {
+ ctx->error(ctx, "height %s", errstr);
+ return (-1);
+ }
+ }
} else if (ctx->cmdclient != NULL) {
sx = ctx->cmdclient->tty.sx;
sy = ctx->cmdclient->tty.sy;
@@ -228,10 +185,10 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
sy = 1;
/* Figure out the command for the new window. */
- if (data->target != NULL)
+ if (target != NULL)
cmd = NULL;
- else if (data->cmd != NULL)
- cmd = data->cmd;
+ else if (args->argc != 0)
+ cmd = args->argv[0];
else
cmd = options_get_string(&global_s_options, "default-command");
@@ -243,8 +200,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index");
- s = session_create(
- data->newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
+ s = session_create(newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
if (s == NULL) {
ctx->error(ctx, "create session failed: %s", cause);
xfree(cause);
@@ -253,11 +209,11 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
environ_free(&env);
/* Set the initial window name if one given. */
- if (cmd != NULL && data->winname != NULL) {
+ if (cmd != NULL && args_has(args, 'n')) {
w = s->curw->window;
xfree(w->name);
- w->name = xstrdup(data->winname);
+ w->name = xstrdup(args_get(args, 'n'));
options_set_number(&w->options, "automatic-rename", 0);
}
@@ -279,10 +235,19 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if (!detached) {
if (ctx->cmdclient != NULL) {
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
+
+ old_s = ctx->cmdclient->session;
+ if (old_s != NULL)
+ ctx->cmdclient->last_session = old_s;
ctx->cmdclient->session = s;
+ session_update_activity(s);
server_redraw_client(ctx->cmdclient);
} else {
+ old_s = ctx->curclient->session;
+ if (old_s != NULL)
+ ctx->curclient->last_session = old_s;
ctx->curclient->session = s;
+ session_update_activity(s);
server_redraw_client(ctx->curclient);
}
}
@@ -307,39 +272,3 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (!detached); /* 1 means don't tell command client to exit */
}
-
-void
-cmd_new_session_free(struct cmd *self)
-{
- struct cmd_new_session_data *data = self->data;
-
- if (data->newname != NULL)
- xfree(data->newname);
- if (data->winname != NULL)
- xfree(data->winname);
- if (data->cmd != NULL)
- xfree(data->cmd);
- xfree(data);
-}
-
-size_t
-cmd_new_session_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_new_session_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->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);
-}
diff --git a/cmd-new-session.o b/cmd-new-session.o
new file mode 100644
index 0000000..f08808c
--- a/dev/null
+++ b/cmd-new-session.o
Binary files differ
diff --git a/cmd-new-window.c b/cmd-new-window.c
index c68d1bf..79e301f 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-new-window.c,v 1.47 2010/07/02 02:49:19 tcunha Exp $ */
+/* $Id: cmd-new-window.c,v 1.49 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -26,110 +26,30 @@
* Create a new window.
*/
-int cmd_new_window_parse(struct cmd *, int, char **, char **);
int cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
-void cmd_new_window_free(struct cmd *);
-void cmd_new_window_init(struct cmd *, int);
-size_t cmd_new_window_print(struct cmd *, char *, size_t);
-
-struct cmd_new_window_data {
- char *target;
- char *name;
- char *cmd;
- int flag_insert_after;
- int flag_detached;
- int flag_kill;
-};
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
+ "adkn:Pt:", 0, 1,
"[-adk] [-n window-name] [-t target-window] [command]",
- 0, "",
- cmd_new_window_init,
- cmd_new_window_parse,
- cmd_new_window_exec,
- cmd_new_window_free,
- cmd_new_window_print
+ 0,
+ NULL,
+ NULL,
+ cmd_new_window_exec
};
-/* ARGSUSED */
-void
-cmd_new_window_init(struct cmd *self, unused int arg)
-{
- struct cmd_new_window_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->target = NULL;
- data->name = NULL;
- data->cmd = NULL;
- data->flag_insert_after = 0;
- data->flag_detached = 0;
- data->flag_kill = 0;
-}
-
-int
-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, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "adkt:n:")) != -1) {
- switch (opt) {
- case 'a':
- data->flag_insert_after = 1;
- break;
- case 'd':
- data->flag_detached = 1;
- break;
- case 'k':
- data->flag_kill = 1;
- break;
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- case 'n':
- if (data->name == NULL)
- data->name = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 0 && argc != 1)
- goto usage;
-
- if (argc == 1)
- data->cmd = 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_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_new_window_data *data = self->data;
- struct session *s;
- struct winlink *wl;
- char *cmd, *cwd, *cause;
- int idx, last;
-
- if (data == NULL)
- return (0);
-
- if (data->flag_insert_after) {
- if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
+ struct args *args = self->args;
+ struct session *s;
+ struct winlink *wl;
+ char *cmd, *cwd, *cause;
+ int idx, last, detached;
+
+ if (args_has(args, 'a')) {
+ wl = cmd_find_window(ctx, args_get(args, 't'), &s);
+ if (wl == NULL)
return (-1);
idx = wl->idx + 1;
@@ -150,14 +70,15 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
server_unlink_window(s, wl);
}
} else {
- if ((idx = cmd_find_index(ctx, data->target, &s)) == -2)
+ if ((idx = cmd_find_index(ctx, args_get(args, 't'), &s)) == -2)
return (-1);
}
+ detached = args_has(args, 'd');
wl = NULL;
if (idx != -1)
wl = winlink_find_by_index(&s->windows, idx);
- if (wl != NULL && data->flag_kill) {
+ if (wl != NULL && args_has(args, 'k')) {
/*
* Can't use session_detach as it will destroy session if this
* makes it empty.
@@ -168,14 +89,15 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Force select/redraw if current. */
if (wl == s->curw) {
- data->flag_detached = 0;
+ detached = 0;
s->curw = NULL;
}
}
- cmd = data->cmd;
- if (cmd == NULL)
+ if (args->argc == 0)
cmd = options_get_string(&s->options, "default-command");
+ else
+ cmd = args->argv[0];
cwd = options_get_string(&s->options, "default-path");
if (*cwd == '\0') {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
@@ -186,51 +108,19 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
- wl = session_new(s, data->name, cmd, cwd, idx, &cause);
+ wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause);
if (wl == NULL) {
ctx->error(ctx, "create window failed: %s", cause);
xfree(cause);
return (-1);
}
- if (!data->flag_detached) {
+ if (!detached) {
session_select(s, wl->idx);
server_redraw_session_group(s);
} else
server_status_session_group(s);
+ if (args_has(args, 'P'))
+ ctx->print(ctx, "%s:%u", s->name, wl->idx);
return (0);
}
-
-void
-cmd_new_window_free(struct cmd *self)
-{
- struct cmd_new_window_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- if (data->name != NULL)
- xfree(data->name);
- if (data->cmd != NULL)
- xfree(data->cmd);
- xfree(data);
-}
-
-size_t
-cmd_new_window_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_new_window_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->target != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->target);
- if (off < len && data->name != NULL)
- off += cmd_prarg(buf + off, len - off, " -n ", data->name);
- if (off < len && data->cmd != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->cmd);
- return (off);
-}
diff --git a/cmd-new-window.o b/cmd-new-window.o
new file mode 100644
index 0000000..657b5b2
--- a/dev/null
+++ b/cmd-new-window.o
Binary files differ
diff --git a/cmd-next-layout.c b/cmd-next-layout.c
deleted file mode 100644
index efc931c..0000000
--- a/cmd-next-layout.c
+++ b/dev/null
@@ -1,54 +0,0 @@
-/* $Id: cmd-next-layout.c,v 1.6 2009/11/14 17:56:39 tcunha Exp $ */
-
-/*
- * Copyright (c) 2009 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include "tmux.h"
-
-/*
- * Switch window to next layout.
- */
-
-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, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_next_layout_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-int
-cmd_next_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_target_data *data = self->data;
- struct winlink *wl;
- u_int layout;
-
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
- return (-1);
-
- layout = layout_set_next(wl->window);
- ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
-
- return (0);
-}
diff --git a/cmd-next-layout.o b/cmd-next-layout.o
new file mode 100644
index 0000000..29ad0f1
--- a/dev/null
+++ b/cmd-next-layout.o
Binary files differ
diff --git a/cmd-next-window.c b/cmd-next-window.c
deleted file mode 100644
index 16003f0..0000000
--- a/cmd-next-window.c
+++ b/dev/null
@@ -1,76 +0,0 @@
-/* $Id: cmd-next-window.c,v 1.21 2009/11/14 17:56:39 tcunha Exp $ */
-
-/*
- * Copyright (c) 2007 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include "tmux.h"
-
-/*
- * Move to next window.
- */
-
-void cmd_next_window_init(struct cmd *, int);
-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, "a",
- cmd_next_window_init,
- cmd_target_parse,
- cmd_next_window_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-void
-cmd_next_window_init(struct cmd *self, int key)
-{
- struct cmd_target_data *data;
-
- cmd_target_init(self, key);
- data = self->data;
-
- if (key == ('n' | KEYC_ESCAPE))
- cmd_set_flag(&data->chflags, 'a');
-}
-
-int
-cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_target_data *data = self->data;
- struct session *s;
- int activity;
-
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
-
- activity = 0;
- if (cmd_check_flag(data->chflags, 'a'))
- activity = 1;
-
- if (session_next(s, activity) == 0)
- server_redraw_session(s);
- else {
- ctx->error(ctx, "no next window");
- return (-1);
- }
- recalculate_sizes();
-
- return (0);
-}
diff --git a/cmd-next-window.o b/cmd-next-window.o
new file mode 100644
index 0000000..ef5119f
--- a/dev/null
+++ b/cmd-next-window.o
Binary files differ
diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c
index 49dab3e..1c88023 100644
--- a/cmd-paste-buffer.c
+++ b/cmd-paste-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-paste-buffer.c,v 1.29 2010/08/11 22:17:32 tcunha Exp $ */
+/* $Id: cmd-paste-buffer.c,v 1.31 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -27,131 +27,73 @@
* Paste paste buffer if present.
*/
-struct cmd_paste_buffer_data {
- char *target;
- int buffer;
-
- int flag_delete;
- char *sepstr;
-};
-
-void cmd_paste_buffer_init(struct cmd *, int);
-int cmd_paste_buffer_parse(struct cmd *, int, char **, char **);
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
+
void cmd_paste_buffer_filter(
- struct window_pane *, const char *, size_t, char *);
-void cmd_paste_buffer_free(struct cmd *);
-size_t cmd_paste_buffer_print(struct cmd *, char *, size_t);
+ struct window_pane *, const char *, size_t, const char *);
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
+ "db:rs:t:", 0, 0,
"[-dr] [-s separator] [-b buffer-index] [-t target-pane]",
- 0, "",
- cmd_paste_buffer_init,
- cmd_paste_buffer_parse,
- cmd_paste_buffer_exec,
- cmd_paste_buffer_free,
- cmd_paste_buffer_print
+ 0,
+ NULL,
+ NULL,
+ cmd_paste_buffer_exec
};
-/* ARGSUSED */
-void
-cmd_paste_buffer_init(struct cmd *self, unused int arg)
-{
- struct cmd_paste_buffer_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->target = NULL;
- data->buffer = -1;
- data->flag_delete = 0;
- data->sepstr = xstrdup("\r");
-}
-
-int
-cmd_paste_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_paste_buffer_data *data;
- int opt, n;
- const char *errstr;
-
- cmd_paste_buffer_init(self, 0);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "b:ds:t:r")) != -1) {
- switch (opt) {
- case 'b':
- if (data->buffer == -1) {
- n = strtonum(optarg, 0, INT_MAX, &errstr);
- if (errstr != NULL) {
- xasprintf(cause, "buffer %s", errstr);
- goto error;
- }
- data->buffer = n;
- }
- break;
- case 'd':
- data->flag_delete = 1;
- break;
- case 's':
- if (data->sepstr != NULL)
- xfree(data->sepstr);
- data->sepstr = xstrdup(optarg);
- break;
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- case 'r':
- if (data->sepstr != NULL)
- xfree(data->sepstr);
- data->sepstr = xstrdup("\n");
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
-error:
- self->entry->free(self);
- return (-1);
-}
-
int
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_paste_buffer_data *data = self->data;
- struct window_pane *wp;
- struct session *s;
- struct paste_buffer *pb;
-
- if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
+ struct args *args = self->args;
+ struct window_pane *wp;
+ struct session *s;
+ struct paste_buffer *pb;
+ const char *sepstr;
+ char *cause;
+ int buffer;
+
+ if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL)
return (-1);
- if (data->buffer == -1)
- pb = paste_get_top(&s->buffers);
+ if (!args_has(args, 'b'))
+ buffer = -1;
else {
- if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) {
- ctx->error(ctx, "no buffer %d", data->buffer);
+ buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "buffer %s", cause);
+ xfree(cause);
return (-1);
}
}
- if (pb != NULL)
- cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr);
+ if (buffer == -1)
+ pb = paste_get_top(&global_buffers);
+ else {
+ pb = paste_get_index(&global_buffers, buffer);
+ if (pb == NULL) {
+ ctx->error(ctx, "no buffer %d", buffer);
+ return (-1);
+ }
+ }
+
+ if (pb != NULL) {
+ sepstr = args_get(args, 's');
+ if (sepstr == NULL) {
+ if (args_has(args, 'r'))
+ sepstr = "\n";
+ else
+ sepstr = "\r";
+ }
+ cmd_paste_buffer_filter(wp, pb->data, pb->size, sepstr);
+ }
/* Delete the buffer if -d. */
- if (data->flag_delete) {
- if (data->buffer == -1)
- paste_free_top(&s->buffers);
+ if (args_has(args, 'd')) {
+ if (buffer == -1)
+ paste_free_top(&global_buffers);
else
- paste_free_index(&s->buffers, data->buffer);
+ paste_free_index(&global_buffers, buffer);
}
return (0);
@@ -160,7 +102,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Add bytes to a buffer and filter '\n' according to separator. */
void
cmd_paste_buffer_filter(
- struct window_pane *wp, const char *data, size_t size, char *sep)
+ struct window_pane *wp, const char *data, size_t size, const char *sep)
{
const char *end = data + size;
const char *lf;
@@ -177,46 +119,3 @@ cmd_paste_buffer_filter(
if (end != data)
bufferevent_write(wp->event, data, end - data);
}
-
-void
-cmd_paste_buffer_free(struct cmd *self)
-{
- struct cmd_paste_buffer_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- if (data->sepstr != NULL)
- xfree(data->sepstr);
- xfree(data);
-}
-
-size_t
-cmd_paste_buffer_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_paste_buffer_data *data = self->data;
- size_t off = 0;
- char tmp[BUFSIZ];
- int r_flag;
-
- r_flag = 0;
- if (data->sepstr != NULL)
- r_flag = (data->sepstr[0] == '\n' && data->sepstr[1] == '\0');
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return (off);
- if (off < len && data->flag_delete)
- off += xsnprintf(buf + off, len - off, " -d");
- if (off < len && r_flag)
- off += xsnprintf(buf + off, len - off, " -r");
- if (off < len && data->buffer != -1)
- off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
- if (off < len && data->sepstr != NULL && !r_flag) {
- strnvis(
- tmp, data->sepstr, sizeof tmp, VIS_OCTAL|VIS_TAB|VIS_NL);
- off += cmd_prarg(buf + off, len - off, " -s ", tmp);
- }
- if (off < len && data->target != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->target);
- return (off);
-}
diff --git a/cmd-paste-buffer.o b/cmd-paste-buffer.o
new file mode 100644
index 0000000..b61abe3
--- a/dev/null
+++ b/cmd-paste-buffer.o
Binary files differ
diff --git a/cmd-pipe-pane.c b/cmd-pipe-pane.c
index 16b70b3..2549a6e 100644
--- a/cmd-pipe-pane.c
+++ b/cmd-pipe-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-pipe-pane.c,v 1.14 2010/08/29 14:42:11 tcunha Exp $ */
+/* $Id: cmd-pipe-pane.c,v 1.17 2011/01/21 23:44:13 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -37,28 +37,27 @@ void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
+ "ot:", 0, 1,
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
+ 0,
+ NULL,
+ NULL,
+ cmd_pipe_pane_exec
};
int
cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct client *c;
struct window_pane *wp;
char *command;
- int old_fd, pipe_fd[2], null_fd, mode;
+ int old_fd, pipe_fd[2], null_fd;
if ((c = cmd_find_client(ctx, NULL)) == NULL)
return (-1);
- if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
+ if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (-1);
/* Destroy the old pipe. */
@@ -70,7 +69,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
/* If no pipe command, that is enough. */
- if (data->arg == NULL || *data->arg == '\0')
+ if (args->argc == 0 || *args->argv[0] == '\0')
return (0);
/*
@@ -79,7 +78,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
*
* bind ^p pipep -o 'cat >>~/output'
*/
- if (cmd_check_flag(data->chflags, 'o') && old_fd != -1)
+ if (args_has(self->args, 'o') && old_fd != -1)
return (0);
/* Open the new pipe. */
@@ -111,7 +110,9 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
close(null_fd);
- command = status_replace(c, NULL, data->arg, time(NULL), 0);
+ closefrom(STDERR_FILENO + 1);
+
+ command = status_replace(c, NULL, args->argv[0], time(NULL), 0);
execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
_exit(1);
default:
@@ -125,12 +126,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
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");
+ setblocking(wp->pipe_fd, 0);
return (0);
}
}
diff --git a/cmd-pipe-pane.o b/cmd-pipe-pane.o
new file mode 100644
index 0000000..47d9c34
--- a/dev/null
+++ b/cmd-pipe-pane.o
Binary files differ
diff --git a/cmd-previous-layout.c b/cmd-previous-layout.c
deleted file mode 100644
index 81f49f1..0000000
--- a/cmd-previous-layout.c
+++ b/dev/null
@@ -1,54 +0,0 @@
-/* $Id: cmd-previous-layout.c,v 1.6 2009/12/04 22:14:47 tcunha Exp $ */
-
-/*
- * Copyright (c) 2009 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include "tmux.h"
-
-/*
- * Switch window to previous layout.
- */
-
-int cmd_previous_layout_exec(struct cmd *, struct cmd_ctx *);
-
-const struct cmd_entry cmd_previous_layout_entry = {
- "previous-layout", "prevl",
- CMD_TARGET_WINDOW_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_previous_layout_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-int
-cmd_previous_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_target_data *data = self->data;
- struct winlink *wl;
- u_int layout;
-
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
- return (-1);
-
- layout = layout_set_previous(wl->window);
- ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
-
- return (0);
-}
diff --git a/cmd-previous-layout.o b/cmd-previous-layout.o
new file mode 100644
index 0000000..559e6fc
--- a/dev/null
+++ b/cmd-previous-layout.o
Binary files differ
diff --git a/cmd-previous-window.c b/cmd-previous-window.c
deleted file mode 100644
index 925f35e..0000000
--- a/cmd-previous-window.c
+++ b/dev/null
@@ -1,76 +0,0 @@
-/* $Id: cmd-previous-window.c,v 1.21 2009/11/14 17:56:39 tcunha Exp $ */
-
-/*
- * Copyright (c) 2007 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include "tmux.h"
-
-/*
- * Move to previous window.
- */
-
-void cmd_previous_window_init(struct cmd *, int);
-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, "a",
- cmd_previous_window_init,
- cmd_target_parse,
- cmd_previous_window_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-void
-cmd_previous_window_init(struct cmd *self, int key)
-{
- struct cmd_target_data *data;
-
- cmd_target_init(self, key);
- data = self->data;
-
- if (key == ('p' | KEYC_ESCAPE))
- cmd_set_flag(&data->chflags, 'a');
-}
-
-int
-cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_target_data *data = self->data;
- struct session *s;
- int activity;
-
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
-
- activity = 0;
- if (cmd_check_flag(data->chflags, 'a'))
- activity = 1;
-
- if (session_previous(s, activity) == 0)
- server_redraw_session(s);
- else {
- ctx->error(ctx, "no previous window");
- return (-1);
- }
- recalculate_sizes();
-
- return (0);
-}
diff --git a/cmd-previous-window.o b/cmd-previous-window.o
new file mode 100644
index 0000000..1ba167b
--- a/dev/null
+++ b/cmd-previous-window.o
Binary files differ
diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c
index 44fc6a5..deb1305 100644
--- a/cmd-refresh-client.c
+++ b/cmd-refresh-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-refresh-client.c,v 1.11 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-refresh-client.c,v 1.12 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,22 +28,21 @@ int cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh",
+ "t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_refresh_client_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_refresh_client_exec
};
int
cmd_refresh_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
server_redraw_client(c);
diff --git a/cmd-refresh-client.o b/cmd-refresh-client.o
new file mode 100644
index 0000000..988c886
--- a/dev/null
+++ b/cmd-refresh-client.o
Binary files differ
diff --git a/cmd-rename-session.c b/cmd-rename-session.c
index 6baded1..bbd7c8e 100644
--- a/cmd-rename-session.c
+++ b/cmd-rename-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-rename-session.c,v 1.20 2010/08/11 22:19:03 tcunha Exp $ */
+/* $Id: cmd-rename-session.c,v 1.22 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,31 +30,34 @@ int cmd_rename_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename",
+ "t:", 1, 1,
CMD_TARGET_SESSION_USAGE " new-name",
- CMD_ARG1, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_rename_session_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_rename_session_exec
};
int
cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
+ struct args *args = self->args;
+ struct session *s;
+ const char *newname;
- if (data->arg != NULL && session_find(data->arg) != NULL) {
- ctx->error(ctx, "duplicate session: %s", data->arg);
+ newname = args->argv[0];
+ if (session_find(newname) != NULL) {
+ ctx->error(ctx, "duplicate session: %s", newname);
return (-1);
}
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL)
return (-1);
+ RB_REMOVE(sessions, &sessions, s);
xfree(s->name);
- s->name = xstrdup(data->arg);
+ s->name = xstrdup(newname);
+ RB_INSERT(sessions, &sessions, s);
server_status_session(s);
diff --git a/cmd-rename-session.o b/cmd-rename-session.o
new file mode 100644
index 0000000..5a927c5
--- a/dev/null
+++ b/cmd-rename-session.o
Binary files differ
diff --git a/cmd-rename-window.c b/cmd-rename-window.c
index 5d9dbf8..ea47dd9 100644
--- a/cmd-rename-window.c
+++ b/cmd-rename-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-rename-window.c,v 1.31 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-rename-window.c,v 1.32 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,27 +30,26 @@ int cmd_rename_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew",
+ "t:", 1, 1,
CMD_TARGET_WINDOW_USAGE " new-name",
- CMD_ARG1, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_rename_window_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_rename_window_exec
};
int
cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
- struct winlink *wl;
+ struct args *args = self->args;
+ struct session *s;
+ struct winlink *wl;
- if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL)
return (-1);
xfree(wl->window->name);
- wl->window->name = xstrdup(data->arg);
+ wl->window->name = xstrdup(args->argv[0]);
options_set_number(&wl->window->options, "automatic-rename", 0);
server_status_window(wl->window);
diff --git a/cmd-rename-window.o b/cmd-rename-window.o
new file mode 100644
index 0000000..3e3ce4c
--- a/dev/null
+++ b/cmd-rename-window.o
Binary files differ
diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c
index 606a5e7..23584f0 100644
--- a/cmd-resize-pane.c
+++ b/cmd-resize-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-resize-pane.c,v 1.14 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-resize-pane.c,v 1.15 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -26,84 +26,90 @@
* Increase or decrease pane size.
*/
-void cmd_resize_pane_init(struct cmd *, int);
+void cmd_resize_pane_key_binding(struct cmd *, int);
int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
+ "DLRt:U", 0, 1,
"[-DLRU] " CMD_TARGET_PANE_USAGE " [adjustment]",
- CMD_ARG01, "DLRU",
- cmd_resize_pane_init,
- cmd_target_parse,
- cmd_resize_pane_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ cmd_resize_pane_key_binding,
+ NULL,
+ cmd_resize_pane_exec
};
void
-cmd_resize_pane_init(struct cmd *self, int key)
+cmd_resize_pane_key_binding(struct cmd *self, int key)
{
- struct cmd_target_data *data;
-
- cmd_target_init(self, key);
- data = self->data;
-
- if (key == (KEYC_UP | KEYC_CTRL))
- cmd_set_flag(&data->chflags, 'U');
- if (key == (KEYC_DOWN | KEYC_CTRL))
- cmd_set_flag(&data->chflags, 'D');
- if (key == (KEYC_LEFT | KEYC_CTRL))
- cmd_set_flag(&data->chflags, 'L');
- if (key == (KEYC_RIGHT | KEYC_CTRL))
- cmd_set_flag(&data->chflags, 'R');
-
- if (key == (KEYC_UP | KEYC_ESCAPE)) {
- cmd_set_flag(&data->chflags, 'U');
- data->arg = xstrdup("5");
- }
- if (key == (KEYC_DOWN | KEYC_ESCAPE)) {
- cmd_set_flag(&data->chflags, 'D');
- data->arg = xstrdup("5");
- }
- if (key == (KEYC_LEFT | KEYC_ESCAPE)) {
- cmd_set_flag(&data->chflags, 'L');
- data->arg = xstrdup("5");
- }
- if (key == (KEYC_RIGHT | KEYC_ESCAPE)) {
- cmd_set_flag(&data->chflags, 'R');
- data->arg = xstrdup("5");
+ switch (key) {
+ case KEYC_UP | KEYC_CTRL:
+ self->args = args_create(0);
+ args_set(self->args, 'U', NULL);
+ break;
+ case KEYC_DOWN | KEYC_CTRL:
+ self->args = args_create(0);
+ args_set(self->args, 'D', NULL);
+ break;
+ case KEYC_LEFT | KEYC_CTRL:
+ self->args = args_create(0);
+ args_set(self->args, 'L', NULL);
+ break;
+ case KEYC_RIGHT | KEYC_CTRL:
+ self->args = args_create(0);
+ args_set(self->args, 'R', NULL);
+ break;
+ case KEYC_UP | KEYC_ESCAPE:
+ self->args = args_create(1, "5");
+ args_set(self->args, 'U', NULL);
+ break;
+ case KEYC_DOWN | KEYC_ESCAPE:
+ self->args = args_create(1, "5");
+ args_set(self->args, 'D', NULL);
+ break;
+ case KEYC_LEFT | KEYC_ESCAPE:
+ self->args = args_create(1, "5");
+ args_set(self->args, 'L', NULL);
+ break;
+ case KEYC_RIGHT | KEYC_ESCAPE:
+ self->args = args_create(1, "5");
+ args_set(self->args, 'R', NULL);
+ break;
+ default:
+ self->args = args_create(0);
+ break;
}
}
int
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
const char *errstr;
struct window_pane *wp;
u_int adjust;
- if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
+ if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL)
return (-1);
- if (data->arg == NULL)
+ if (args->argc == 0)
adjust = 1;
else {
- adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
+ adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
if (errstr != NULL) {
- ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
+ ctx->error(ctx, "adjustment %s", errstr);
return (-1);
}
}
- if (cmd_check_flag(data->chflags, 'L'))
+ if (args_has(self->args, 'L'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
- else if (cmd_check_flag(data->chflags, 'R'))
+ else if (args_has(self->args, 'R'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
- else if (cmd_check_flag(data->chflags, 'U'))
+ else if (args_has(self->args, 'U'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust);
- else if (cmd_check_flag(data->chflags, 'D'))
+ else if (args_has(self->args, 'D'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
server_redraw_window(wl->window);
diff --git a/cmd-resize-pane.o b/cmd-resize-pane.o
new file mode 100644
index 0000000..bd4841f
--- a/dev/null
+++ b/cmd-resize-pane.o
Binary files differ
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index f889fc2..e7a1f91 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-respawn-window.c,v 1.25 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-respawn-window.c,v 1.26 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -30,31 +30,31 @@ int cmd_respawn_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw",
+ "kt:", 0, 1,
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
- CMD_ARG01, "k",
- cmd_target_init,
- cmd_target_parse,
- cmd_respawn_window_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_respawn_window_exec
};
int
cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct session *s;
struct environ env;
+ const char *cmd;
char *cause;
- if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL)
return (-1);
w = wl->window;
- if (!cmd_check_flag(data->chflags, 'k')) {
+ if (!args_has(self->args, 'k')) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1)
continue;
@@ -75,8 +75,11 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
window_destroy_panes(w);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy);
- if (window_pane_spawn(
- wp, data->arg, NULL, NULL, &env, s->tio, &cause) != 0) {
+ if (args->argc != 0)
+ cmd = args->argv[0];
+ else
+ cmd = NULL;
+ if (window_pane_spawn(wp, cmd, NULL, NULL, &env, s->tio, &cause) != 0) {
ctx->error(ctx, "respawn window failed: %s", cause);
xfree(cause);
environ_free(&env);
diff --git a/cmd-respawn-window.o b/cmd-respawn-window.o
new file mode 100644
index 0000000..d67141e
--- a/dev/null
+++ b/cmd-respawn-window.o
Binary files differ
diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c
index 44426e7..941e127 100644
--- a/cmd-rotate-window.c
+++ b/cmd-rotate-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-rotate-window.c,v 1.10 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-rotate-window.c,v 1.11 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -24,47 +24,42 @@
* Rotate the panes in a window.
*/
-void cmd_rotate_window_init(struct cmd *, int);
+void cmd_rotate_window_key_binding(struct cmd *, int);
int cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew",
+ "Dt:U", 0, 0,
"[-DU] " CMD_TARGET_WINDOW_USAGE,
- 0, "DU",
- cmd_rotate_window_init,
- cmd_target_parse,
- cmd_rotate_window_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ cmd_rotate_window_key_binding,
+ NULL,
+ cmd_rotate_window_exec
};
void
-cmd_rotate_window_init(struct cmd *self, int key)
+cmd_rotate_window_key_binding(struct cmd *self, int key)
{
- struct cmd_target_data *data;
-
- cmd_target_init(self, key);
- data = self->data;
-
+ self->args = args_create(0);
if (key == ('o' | KEYC_ESCAPE))
- cmd_set_flag(&data->chflags, 'D');
+ args_set(self->args, 'D', NULL);
}
int
cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct window_pane *wp, *wp2;
struct layout_cell *lc;
u_int sx, sy, xoff, yoff;
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
w = wl->window;
- if (cmd_check_flag(data->chflags, 'D')) {
+ if (args_has(self->args, 'D')) {
wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
diff --git a/cmd-rotate-window.o b/cmd-rotate-window.o
new file mode 100644
index 0000000..f42e27e
--- a/dev/null
+++ b/cmd-rotate-window.o
Binary files differ
diff --git a/cmd-run-shell.c b/cmd-run-shell.c
index 0f5ca73..c8da7a0 100644
--- a/cmd-run-shell.c
+++ b/cmd-run-shell.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-run-shell.c,v 1.9 2010/08/09 21:44:25 tcunha Exp $ */
+/* $Id: cmd-run-shell.c,v 1.10 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <[email protected]>
@@ -35,13 +35,12 @@ void cmd_run_shell_free(void *);
const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run",
+ "", 1, 1,
"command",
- CMD_ARG1, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_run_shell_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_run_shell_exec
};
struct cmd_run_shell_data {
@@ -52,12 +51,12 @@ struct cmd_run_shell_data {
int
cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct cmd_run_shell_data *cdata;
struct job *job;
cdata = xmalloc(sizeof *cdata);
- cdata->cmd = xstrdup(data->arg);
+ cdata->cmd = xstrdup(args->argv[0]);
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
@@ -66,7 +65,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->curclient->references++;
job = job_add(NULL, 0, NULL,
- data->arg, cmd_run_shell_callback, cmd_run_shell_free, cdata);
+ args->argv[0], cmd_run_shell_callback, cmd_run_shell_free, cdata);
job_run(job);
return (1); /* don't let client exit */
diff --git a/cmd-run-shell.o b/cmd-run-shell.o
new file mode 100644
index 0000000..9962aee
--- a/dev/null
+++ b/cmd-run-shell.o
Binary files differ
diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c
index a101984..d7b7738 100644
--- a/cmd-save-buffer.c
+++ b/cmd-save-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-save-buffer.c,v 1.12 2010/08/09 21:44:25 tcunha Exp $ */
+/* $Id: cmd-save-buffer.c,v 1.14 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <[email protected]>
@@ -32,59 +32,66 @@ 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, "a",
- cmd_buffer_init,
- cmd_buffer_parse,
- cmd_save_buffer_exec,
- cmd_buffer_free,
- cmd_buffer_print
+ "ab:", 1, 1,
+ "[-a] " CMD_BUFFER_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_save_buffer_exec
};
int
cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_buffer_data *data = self->data;
- struct session *s;
+ struct args *args = self->args;
+ struct client *c = ctx->cmdclient;
struct paste_buffer *pb;
+ const char *path;
+ char *cause;
+ int buffer;
mode_t mask;
FILE *f;
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
-
- if (data->buffer == -1) {
- if ((pb = paste_get_top(&s->buffers)) == NULL) {
+ if (!args_has(args, 'b')) {
+ if ((pb = paste_get_top(&global_buffers)) == NULL) {
ctx->error(ctx, "no buffers");
return (-1);
}
} else {
- if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) {
- ctx->error(ctx, "no buffer %d", data->buffer);
+ buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "buffer %s", cause);
+ xfree(cause);
+ return (-1);
+ }
+
+ pb = paste_get_index(&global_buffers, buffer);
+ if (pb == NULL) {
+ ctx->error(ctx, "no buffer %d", buffer);
return (-1);
}
}
- if (strcmp(data->arg, "-") == 0) {
- if (ctx->cmdclient == NULL) {
- ctx->error(ctx, "%s: can't write to stdout", data->arg);
+ path = args->argv[0];
+ if (strcmp(path, "-") == 0) {
+ if (c == NULL) {
+ ctx->error(ctx, "%s: can't write to stdout", path);
return (-1);
}
- bufferevent_write(
- ctx->cmdclient->stdout_event, pb->data, pb->size);
+ bufferevent_write(c->stdout_event, pb->data, pb->size);
} else {
mask = umask(S_IRWXG | S_IRWXO);
- if (cmd_check_flag(data->chflags, 'a'))
- f = fopen(data->arg, "ab");
+ if (args_has(self->args, 'a'))
+ f = fopen(path, "ab");
else
- f = fopen(data->arg, "wb");
+ f = fopen(path, "wb");
umask(mask);
if (f == NULL) {
- ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
+ ctx->error(ctx, "%s: %s", path, strerror(errno));
return (-1);
}
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
- ctx->error(ctx, "%s: fwrite error", data->arg);
+ ctx->error(ctx, "%s: fwrite error", path);
fclose(f);
return (-1);
}
diff --git a/cmd-save-buffer.o b/cmd-save-buffer.o
new file mode 100644
index 0000000..65d944d
--- a/dev/null
+++ b/cmd-save-buffer.o
Binary files differ
diff --git a/cmd-select-layout.c b/cmd-select-layout.c
index 4450a02..733247f 100644
--- a/cmd-select-layout.c
+++ b/cmd-select-layout.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-select-layout.c,v 1.12 2010/07/02 02:54:52 tcunha Exp $ */
+/* $Id: cmd-select-layout.c,v 1.14 2011/01/07 15:02:38 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -24,43 +24,60 @@
* Switch window to selected layout.
*/
-void cmd_select_layout_init(struct cmd *, int);
+void cmd_select_layout_key_binding(struct cmd *, int);
int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
- CMD_TARGET_WINDOW_USAGE " [layout-name]",
- CMD_ARG01, "",
- cmd_select_layout_init,
- cmd_target_parse,
- cmd_select_layout_exec,
- cmd_target_free,
- cmd_target_print
+ "npt:", 0, 1,
+ "[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
+ 0,
+ cmd_select_layout_key_binding,
+ NULL,
+ cmd_select_layout_exec
};
-void
-cmd_select_layout_init(struct cmd *self, int key)
-{
- struct cmd_target_data *data;
+const struct cmd_entry cmd_next_layout_entry = {
+ "next-layout", "nextl",
+ "t:", 0, 0,
+ CMD_TARGET_WINDOW_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_select_layout_exec
+};
- cmd_target_init(self, key);
- data = self->data;
+const struct cmd_entry cmd_previous_layout_entry = {
+ "previous-layout", "prevl",
+ "t:", 0, 0,
+ CMD_TARGET_WINDOW_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_select_layout_exec
+};
+void
+cmd_select_layout_key_binding(struct cmd *self, int key)
+{
switch (key) {
- case ('1' | KEYC_ESCAPE):
- data->arg = xstrdup("even-horizontal");
+ case '1' | KEYC_ESCAPE:
+ self->args = args_create(1, "even-horizontal");
+ break;
+ case '2' | KEYC_ESCAPE:
+ self->args = args_create(1, "even-vertical");
break;
- case ('2' | KEYC_ESCAPE):
- data->arg = xstrdup("even-vertical");
+ case '3' | KEYC_ESCAPE:
+ self->args = args_create(1, "main-horizontal");
break;
- case ('3' | KEYC_ESCAPE):
- data->arg = xstrdup("main-horizontal");
+ case '4' | KEYC_ESCAPE:
+ self->args = args_create(1, "main-vertical");
break;
- case ('4' | KEYC_ESCAPE):
- data->arg = xstrdup("main-vertical");
+ case '5' | KEYC_ESCAPE:
+ self->args = args_create(1, "tiled");
break;
- case ('5' | KEYC_ESCAPE):
- data->arg = xstrdup("tiled");
+ default:
+ self->args = args_create(0);
break;
}
}
@@ -68,26 +85,48 @@ cmd_select_layout_init(struct cmd *self, int key)
int
cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct winlink *wl;
- int layout;
+ struct args *args = self->args;
+ struct winlink *wl;
+ const char *layoutname;
+ int next, previous, layout;
- if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (-1);
- if (data->arg == NULL) {
+ next = self->entry == &cmd_next_layout_entry;
+ if (args_has(self->args, 'n'))
+ next = 1;
+ previous = self->entry == &cmd_previous_layout_entry;
+ if (args_has(self->args, 'p'))
+ previous = 1;
+
+ if (next || previous) {
+ if (next)
+ layout = layout_set_next(wl->window);
+ else
+ layout = layout_set_previous(wl->window);
+ ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
+ return (0);
+ }
+
+ if (args->argc == 0)
layout = wl->window->lastlayout;
- if (layout == -1)
- return (0);
- } else if ((layout = layout_set_lookup(data->arg)) != -1) {
+ else
+ layout = layout_set_lookup(args->argv[0]);
+ if (layout != -1) {
layout = layout_set_select(wl->window, layout);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
- } else {
- if (layout_parse(wl->window, data->arg) == -1) {
- ctx->error(ctx, "can't set layout: %s", data->arg);
+ return (0);
+ }
+
+ if (args->argc != 0) {
+ layoutname = args->argv[0];
+ if (layout_parse(wl->window, layoutname) == -1) {
+ ctx->error(ctx, "can't set layout: %s", layoutname);
return (-1);
}
- ctx->info(ctx, "arranging in: %s", data->arg);
+ ctx->info(ctx, "arranging in: %s", layoutname);
+ return (0);
}
return (0);
diff --git a/cmd-select-layout.o b/cmd-select-layout.o
new file mode 100644
index 0000000..fa58815
--- a/dev/null
+++ b/cmd-select-layout.o
Binary files differ
diff --git a/cmd-select-pane.c b/cmd-select-pane.c
index 14ab877..f5499af 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-select-pane.c,v 1.13 2010/03/15 22:03:38 nicm Exp $ */
+/* $Id: cmd-select-pane.c,v 1.15 2011/01/07 15:02:38 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -24,62 +24,80 @@
* Select pane.
*/
-void cmd_select_pane_init(struct cmd *, int);
+void cmd_select_pane_key_binding(struct cmd *, int);
int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
- "[-DLRU] " CMD_TARGET_PANE_USAGE,
- 0, "DLRU",
- cmd_select_pane_init,
- cmd_target_parse,
- cmd_select_pane_exec,
- cmd_target_free,
- cmd_target_print
+ "lDLRt:U", 0, 0,
+ "[-lDLRU] " CMD_TARGET_PANE_USAGE,
+ 0,
+ cmd_select_pane_key_binding,
+ NULL,
+ cmd_select_pane_exec
+};
+
+const struct cmd_entry cmd_last_pane_entry = {
+ "last-pane", "lastp",
+ "t:", 0, 0,
+ CMD_TARGET_WINDOW_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_select_pane_exec
};
void
-cmd_select_pane_init(struct cmd *self, int key)
+cmd_select_pane_key_binding(struct cmd *self, int key)
{
- struct cmd_target_data *data;
-
- cmd_target_init(self, key);
- data = self->data;
-
+ self->args = args_create(0);
if (key == KEYC_UP)
- cmd_set_flag(&data->chflags, 'U');
+ args_set(self->args, 'U', NULL);
if (key == KEYC_DOWN)
- cmd_set_flag(&data->chflags, 'D');
+ args_set(self->args, 'D', NULL);
if (key == KEYC_LEFT)
- cmd_set_flag(&data->chflags, 'L');
+ args_set(self->args, 'L', NULL);
if (key == KEYC_RIGHT)
- cmd_set_flag(&data->chflags, 'R');
+ args_set(self->args, 'R', NULL);
if (key == 'o')
- data->target = xstrdup(":.+");
+ args_set(self->args, 't', ":.+");
}
int
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
struct window_pane *wp;
- if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
+ if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
+ wl = cmd_find_window(ctx, args_get(args, 't'), NULL);
+ if (wl == NULL)
+ return (-1);
+
+ if (wl->window->last == NULL) {
+ ctx->error(ctx, "no last pane");
+ return (-1);
+ }
+ window_set_active_pane(wl->window, wl->window->last);
+ return (0);
+ }
+
+ if ((wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp)) == NULL)
return (-1);
if (!window_pane_visible(wp)) {
- ctx->error(ctx, "pane not visible: %s", data->target);
+ ctx->error(ctx, "pane not visible");
return (-1);
}
- if (cmd_check_flag(data->chflags, 'L'))
+ if (args_has(self->args, 'L'))
wp = window_pane_find_left(wp);
- else if (cmd_check_flag(data->chflags, 'R'))
+ else if (args_has(self->args, 'R'))
wp = window_pane_find_right(wp);
- else if (cmd_check_flag(data->chflags, 'U'))
+ else if (args_has(self->args, 'U'))
wp = window_pane_find_up(wp);
- else if (cmd_check_flag(data->chflags, 'D'))
+ else if (args_has(self->args, 'D'))
wp = window_pane_find_down(wp);
if (wp == NULL) {
ctx->error(ctx, "pane not found");
diff --git a/cmd-select-pane.o b/cmd-select-pane.o
new file mode 100644
index 0000000..d93088a
--- a/dev/null
+++ b/cmd-select-pane.o
Binary files differ
diff --git a/cmd-select-window.c b/cmd-select-window.c
index 11a4b43..e379e49 100644
--- a/cmd-select-window.c
+++ b/cmd-select-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-select-window.c,v 1.24 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-select-window.c,v 1.26 2011/01/07 15:02:38 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -26,43 +26,113 @@
* Select window by index.
*/
-void cmd_select_window_init(struct cmd *, int);
+void cmd_select_window_key_binding(struct cmd *, int);
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, "",
- cmd_select_window_init,
- cmd_target_parse,
- cmd_select_window_exec,
- cmd_target_free,
- cmd_target_print
+ "lnpt:", 0, 0,
+ "[-lnp] " CMD_TARGET_WINDOW_USAGE,
+ 0,
+ cmd_select_window_key_binding,
+ NULL,
+ cmd_select_window_exec
+};
+
+const struct cmd_entry cmd_next_window_entry = {
+ "next-window", "next",
+ "at:", 0, 0,
+ "[-a] " CMD_TARGET_SESSION_USAGE,
+ 0,
+ cmd_select_window_key_binding,
+ NULL,
+ cmd_select_window_exec
+};
+
+const struct cmd_entry cmd_previous_window_entry = {
+ "previous-window", "prev",
+ "at:", 0, 0,
+ "[-a] " CMD_TARGET_SESSION_USAGE,
+ 0,
+ cmd_select_window_key_binding,
+ NULL,
+ cmd_select_window_exec
+};
+
+const struct cmd_entry cmd_last_window_entry = {
+ "last-window", "last",
+ "t:", 0, 0,
+ CMD_TARGET_SESSION_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_select_window_exec
};
void
-cmd_select_window_init(struct cmd *self, int key)
+cmd_select_window_key_binding(struct cmd *self, int key)
{
- struct cmd_target_data *data;
-
- cmd_target_init(self, key);
- data = self->data;
+ char tmp[16];
- xasprintf(&data->target, ":%d", key - '0');
+ self->args = args_create(0);
+ if (key >= '0' && key <= '9') {
+ xsnprintf(tmp, sizeof tmp, ":%d", key - '0');
+ args_set(self->args, 't', tmp);
+ }
+ if (key == ('n' | KEYC_ESCAPE) || key == ('p' | KEYC_ESCAPE))
+ args_set(self->args, 'a', NULL);
}
int
cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct winlink *wl;
- struct session *s;
+ struct args *args = self->args;
+ struct winlink *wl;
+ struct session *s;
+ int next, previous, last, activity;
+
+ next = self->entry == &cmd_next_window_entry;
+ if (args_has(self->args, 'n'))
+ next = 1;
+ previous = self->entry == &cmd_previous_window_entry;
+ if (args_has(self->args, 'p'))
+ previous = 1;
+ last = self->entry == &cmd_last_window_entry;
+ if (args_has(self->args, 'l'))
+ last = 1;
- if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
- return (-1);
+ if (next || previous || last) {
+ s = cmd_find_session(ctx, args_get(args, 't'));
+ if (s == NULL)
+ return (-1);
+
+ activity = args_has(self->args, 'a');
+ if (next) {
+ if (session_next(s, activity) != 0) {
+ ctx->error(ctx, "no next window");
+ return (-1);
+ }
+ } else if (previous) {
+ if (session_previous(s, activity) != 0) {
+ ctx->error(ctx, "no previous window");
+ return (-1);
+ }
+ } else {
+ if (session_last(s) != 0) {
+ ctx->error(ctx, "no last window");
+ return (-1);
+ }
+ }
- if (session_select(s, wl->idx) == 0)
server_redraw_session(s);
+ } else {
+ wl = cmd_find_window(ctx, args_get(args, 't'), &s);
+ if (wl == NULL)
+ return (-1);
+
+ if (session_select(s, wl->idx) == 0)
+ server_redraw_session(s);
+ }
recalculate_sizes();
return (0);
diff --git a/cmd-select-window.o b/cmd-select-window.o
new file mode 100644
index 0000000..1f2eb93
--- a/dev/null
+++ b/cmd-select-window.o
Binary files differ
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index 464547f..07c25ad 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-send-keys.c,v 1.25 2010/05/22 21:56:04 micahcowan Exp $ */
+/* $Id: cmd-send-keys.c,v 1.26 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -26,128 +26,40 @@
* Send keys to client.
*/
-int cmd_send_keys_parse(struct cmd *, int, char **, char **);
int cmd_send_keys_exec(struct cmd *, struct cmd_ctx *);
-void cmd_send_keys_free(struct cmd *);
-size_t cmd_send_keys_print(struct cmd *, char *, size_t);
-
-struct cmd_send_keys_data {
- char *target;
- u_int nkeys;
- int *keys;
-};
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
+ "t:", 0, -1,
"[-t target-pane] key ...",
- 0, "",
+ 0,
NULL,
- cmd_send_keys_parse,
- cmd_send_keys_exec,
- cmd_send_keys_free,
- cmd_send_keys_print
+ NULL,
+ cmd_send_keys_exec
};
int
-cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause)
+cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_send_keys_data *data;
- int opt, key;
- char *s;
+ struct args *args = self->args;
+ struct window_pane *wp;
+ struct session *s;
+ const char *str;
+ int i, key;
- self->data = data = xmalloc(sizeof *data);
- data->target = NULL;
- data->nkeys = 0;
- data->keys = NULL;
+ if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL)
+ return (-1);
- while ((opt = getopt(argc, argv, "t:")) != -1) {
- switch (opt) {
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc == 0)
- goto usage;
+ for (i = 0; i < args->argc; i++) {
+ str = args->argv[i];
- while (argc-- != 0) {
- if ((key = key_string_lookup_string(*argv)) != KEYC_NONE) {
- data->keys = xrealloc(
- data->keys, data->nkeys + 1, sizeof *data->keys);
- data->keys[data->nkeys++] = key;
+ if ((key = key_string_lookup_string(str)) != KEYC_NONE) {
+ window_pane_key(wp, s, key);
} else {
- for (s = *argv; *s != '\0'; s++) {
- data->keys = xrealloc(data->keys,
- data->nkeys + 1, sizeof *data->keys);
- data->keys[data->nkeys++] = *s;
- }
+ for (; *str != '\0'; str++)
+ window_pane_key(wp, s, *str);
}
-
- argv++;
}
return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
-}
-
-int
-cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_send_keys_data *data = self->data;
- struct window_pane *wp;
- struct session *s;
- u_int i;
-
- if (data == NULL)
- return (-1);
-
- if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
- return (-1);
-
- for (i = 0; i < data->nkeys; i++)
- window_pane_key(wp, s, data->keys[i]);
-
- return (0);
-}
-
-void
-cmd_send_keys_free(struct cmd *self)
-{
- struct cmd_send_keys_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- xfree(data);
-}
-
-size_t
-cmd_send_keys_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_send_keys_data *data = self->data;
- size_t off = 0;
- u_int i;
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return (off);
- if (off < len && data->target != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->target);
-
- for (i = 0; i < data->nkeys; i++) {
- if (off >= len)
- break;
- off += xsnprintf(buf + off,
- len - off, " %s", key_string_lookup_key(data->keys[i]));
- }
- return (off);
}
diff --git a/cmd-send-keys.o b/cmd-send-keys.o
new file mode 100644
index 0000000..fcf1f16
--- a/dev/null
+++ b/cmd-send-keys.o
Binary files differ
diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c
index fa14018..08e5a31 100644
--- a/cmd-send-prefix.c
+++ b/cmd-send-prefix.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-send-prefix.c,v 1.29 2010/05/22 21:56:04 micahcowan Exp $ */
+/* $Id: cmd-send-prefix.c,v 1.30 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,24 +28,23 @@ int cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
+ "t:", 0, 0,
CMD_TARGET_PANE_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_send_prefix_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_send_prefix_exec
};
int
cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct session *s;
struct window_pane *wp;
struct keylist *keylist;
- if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
+ if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL)
return (-1);
keylist = options_get_data(&s->options, "prefix");
diff --git a/cmd-send-prefix.o b/cmd-send-prefix.o
new file mode 100644
index 0000000..af943d3
--- a/dev/null
+++ b/cmd-send-prefix.o
Binary files differ
diff --git a/cmd-server-info.c b/cmd-server-info.c
index b8d4bc3..9954153 100644
--- a/cmd-server-info.c
+++ b/cmd-server-info.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-server-info.c,v 1.37 2009/12/10 16:59:02 tcunha Exp $ */
+/* $Id: cmd-server-info.c,v 1.42 2011/01/21 23:51:36 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -34,42 +34,41 @@ int cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
+ "", 0, 0,
"",
- 0, "",
+ 0,
NULL,
NULL,
- cmd_server_info_exec,
- NULL,
- NULL
+ cmd_server_info_exec
};
/* ARGSUSED */
int
cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
- struct tty_term *term;
- struct client *c;
- struct session *s;
- struct winlink *wl;
- struct window *w;
- struct window_pane *wp;
- struct tty_code *code;
- struct tty_term_code_entry *ent;
- struct utsname un;
- struct job *job;
- struct grid *gd;
- struct grid_line *gl;
- u_int i, j, k;
- char out[80];
- char *tim;
- time_t t;
- u_int lines, ulines;
- size_t size, usize;
+ struct tty_term *term;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window *w;
+ struct window_pane *wp;
+ struct tty_code *code;
+ const struct tty_term_code_entry *ent;
+ struct utsname un;
+ struct job *job;
+ struct grid *gd;
+ struct grid_line *gl;
+ u_int i, j, k;
+ char out[80];
+ char *tim;
+ time_t t;
+ u_int lines, ulines;
+ size_t size, usize;
tim = ctime(&start_time);
*strchr(tim, '\n') = '\0';
ctx->print(ctx,
- "tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim);
+ "tmux " VERSION ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(
ctx, "socket path %s, debug level %d", socket_path, debug_level);
if (uname(&un) == 0) {
@@ -81,8 +80,6 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
else
ctx->print(ctx, "configuration file not specified");
ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION);
- ctx->print(ctx, "%u clients, %u sessions",
- ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions));
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Clients:");
@@ -91,29 +88,25 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
if (c == NULL || c->session == NULL)
continue;
- ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
+ ctx->print(ctx,"%2d: %s (%d, %d): %s [%ux%u %s bs=%hho] "
"[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->tty.tio.c_cc[VERASE], c->flags,
c->tty.flags, c->references);
}
ctx->print(ctx, "%s", "");
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;
-
+ RB_FOREACH(s, sessions, &sessions) {
t = s->creation_time.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
- "[flags=0x%x, references=%u]", i, s->name,
- winlink_count(&s->windows), tim, s->sx, s->sy, s->flags,
- s->references);
+ "[flags=0x%x]", s->idx, s->name,
+ winlink_count(&s->windows), tim, s->sx, s->sy, s->flags);
RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, "
diff --git a/cmd-server-info.o b/cmd-server-info.o
new file mode 100644
index 0000000..088a42b
--- a/dev/null
+++ b/cmd-server-info.o
Binary files differ
diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c
index 0a741f1..585ee28 100644
--- a/cmd-set-buffer.c
+++ b/cmd-set-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-set-buffer.c,v 1.12 2009/11/28 14:54:12 tcunha Exp $ */
+/* $Id: cmd-set-buffer.c,v 1.14 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,39 +30,45 @@ int cmd_set_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb",
- CMD_BUFFER_SESSION_USAGE " data",
- CMD_ARG1, "",
- cmd_buffer_init,
- cmd_buffer_parse,
- cmd_set_buffer_exec,
- cmd_buffer_free,
- cmd_buffer_print
+ "b:", 1, 1,
+ CMD_BUFFER_USAGE " data",
+ 0,
+ NULL,
+ NULL,
+ cmd_set_buffer_exec
};
int
cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_buffer_data *data = self->data;
- struct session *s;
- u_int limit;
- char *pdata;
- size_t psize;
+ struct args *args = self->args;
+ u_int limit;
+ char *pdata, *cause;
+ size_t psize;
+ int buffer;
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
- limit = options_get_number(&s->options, "buffer-limit");
+ limit = options_get_number(&global_options, "buffer-limit");
- pdata = xstrdup(data->arg);
+ pdata = xstrdup(args->argv[0]);
psize = strlen(pdata);
- if (data->buffer == -1) {
- paste_add(&s->buffers, pdata, psize, limit);
+ if (!args_has(args, 'b')) {
+ paste_add(&global_buffers, pdata, psize, limit);
return (0);
}
- if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
- ctx->error(ctx, "no buffer %d", data->buffer);
+
+ buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "buffer %s", cause);
+ xfree(cause);
+ return (-1);
+ }
+
+ if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
+ ctx->error(ctx, "no buffer %d", buffer);
xfree(pdata);
return (-1);
}
+
return (0);
}
diff --git a/cmd-set-buffer.o b/cmd-set-buffer.o
new file mode 100644
index 0000000..75ba5c2
--- a/dev/null
+++ b/cmd-set-buffer.o
Binary files differ
diff --git a/cmd-set-environment.c b/cmd-set-environment.c
index b95f1e7..c363945 100644
--- a/cmd-set-environment.c
+++ b/cmd-set-environment.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-set-environment.c,v 1.3 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-set-environment.c,v 1.4 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -31,57 +31,63 @@ int cmd_set_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv",
+ "grt:u", 1, 2,
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
- CMD_ARG12, "gru",
+ 0,
NULL,
- cmd_target_parse,
- cmd_set_environment_exec,
- cmd_target_free,
- cmd_target_print
+ NULL,
+ cmd_set_environment_exec
};
int
cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
- struct environ *env;
+ struct args *args = self->args;
+ struct session *s;
+ struct environ *env;
+ const char *name, *value;
- if (*data->arg == '\0') {
+ name = args->argv[0];
+ if (*name == '\0') {
ctx->error(ctx, "empty variable name");
return (-1);
}
- if (strchr(data->arg, '=') != NULL) {
+ if (strchr(name, '=') != NULL) {
ctx->error(ctx, "variable name contains =");
return (-1);
}
- if (cmd_check_flag(data->chflags, 'g'))
+ if (args->argc < 1)
+ value = NULL;
+ else
+ value = args->argv[1];
+
+ if (args_has(self->args, 'g'))
env = &global_environ;
else {
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL)
return (-1);
env = &s->environ;
}
- if (cmd_check_flag(data->chflags, 'u')) {
- if (data->arg2 != NULL) {
+ if (args_has(self->args, 'u')) {
+ if (value != NULL) {
ctx->error(ctx, "can't specify a value with -u");
return (-1);
}
- environ_unset(env, data->arg);
- } else if (cmd_check_flag(data->chflags, 'r')) {
- if (data->arg2 != NULL) {
+ environ_unset(env, name);
+ } else if (args_has(self->args, 'r')) {
+ if (value != NULL) {
ctx->error(ctx, "can't specify a value with -r");
return (-1);
}
- environ_set(env, data->arg, NULL);
+ environ_set(env, name, NULL);
} else {
- if (data->arg2 == NULL) {
+ if (value == NULL) {
ctx->error(ctx, "no value specified");
return (-1);
}
- environ_set(env, data->arg, data->arg2);
+ environ_set(env, name, value);
}
return (0);
diff --git a/cmd-set-environment.o b/cmd-set-environment.o
new file mode 100644
index 0000000..b3d44d7
--- a/dev/null
+++ b/cmd-set-environment.o
Binary files differ
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 9fb9a03..392bc86 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-set-option.c,v 1.99 2010/09/07 13:20:28 tcunha Exp $ */
+/* $Id: cmd-set-option.c,v 1.107 2011/01/07 15:02:38 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -29,256 +29,139 @@
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 *);
+int cmd_set_option_unset(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+int cmd_set_option_set(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+
+struct options_entry *cmd_set_option_string(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+struct options_entry *cmd_set_option_number(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+struct options_entry *cmd_set_option_keys(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+struct options_entry *cmd_set_option_colour(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+struct options_entry *cmd_set_option_attributes(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
+struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_ctx *,
+ const struct options_table_entry *, struct options *,
+ const char *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
+ "agst:uw", 1, 2,
"[-agsuw] [-t target-session|target-window] option [value]",
- CMD_ARG12, "agsuw",
+ 0,
NULL,
- cmd_target_parse,
- cmd_set_option_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-const char *set_option_mode_keys_list[] = {
- "emacs", "vi", NULL
-};
-const char *set_option_clock_mode_style_list[] = {
- "12", "24", NULL
-};
-const char *set_option_status_keys_list[] = {
- "emacs", "vi", NULL
-};
-const char *set_option_status_justify_list[] = {
- "left", "centre", "right", NULL
-};
-const char *set_option_bell_action_list[] = {
- "none", "any", "current", NULL
-};
-
-const struct set_option_entry set_option_table[] = {
- { "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 },
- { "default-command", SET_OPTION_STRING, 0, 0, NULL },
- { "default-path", SET_OPTION_STRING, 0, 0, NULL },
- { "default-shell", SET_OPTION_STRING, 0, 0, NULL },
- { "default-terminal", SET_OPTION_STRING, 0, 0, NULL },
- { "detach-on-destroy", SET_OPTION_FLAG, 0, 0, NULL },
- { "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL },
- { "display-panes-active-colour", SET_OPTION_COLOUR, 0, 0, NULL },
- { "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
- { "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
- { "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
- { "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
- { "lock-command", SET_OPTION_STRING, 0, 0, NULL },
- { "lock-server", SET_OPTION_FLAG, 0, 0, NULL },
- { "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "message-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
- { "mouse-select-pane", SET_OPTION_FLAG, 0, 0, NULL },
- { "pane-active-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "pane-active-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "pane-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "pane-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "prefix", SET_OPTION_KEYS, 0, 0, NULL },
- { "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
- { "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
- { "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
- { "set-titles-string", SET_OPTION_STRING, 0, 0, NULL },
- { "status", SET_OPTION_FLAG, 0, 0, NULL },
- { "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
- { "status-justify",
- SET_OPTION_CHOICE, 0, 0, set_option_status_justify_list },
- { "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list },
- { "status-left", SET_OPTION_STRING, 0, 0, NULL },
- { "status-left-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "status-left-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "status-left-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
- { "status-right", SET_OPTION_STRING, 0, 0, NULL },
- { "status-right-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "status-right-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "status-right-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
- { "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
- { "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL },
- { "update-environment", SET_OPTION_STRING, 0, 0, NULL },
- { "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
- { "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
- { "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
- { NULL, 0, 0, 0, NULL }
+ NULL,
+ cmd_set_option_exec
};
-const struct set_option_entry set_window_option_table[] = {
- { "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
- { "alternate-screen", SET_OPTION_FLAG, 0, 0, NULL },
- { "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
- { "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
- { "clock-mode-style",
- SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
- { "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
- { "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
- { "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
- { "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
- { "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
- { "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
- { "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
- { "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
- { "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
- { "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
- { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
- { "window-status-alert-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "window-status-alert-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "window-status-alert-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
- { "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
- { "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
- { "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
- { "word-separators", SET_OPTION_STRING, 0, 0, NULL },
- { "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
- { NULL, 0, 0, 0, NULL }
+const struct cmd_entry cmd_set_window_option_entry = {
+ "set-window-option", "setw",
+ "agt:u", 1, 2,
+ "[-agu] " CMD_TARGET_WINDOW_USAGE " option [value]",
+ 0,
+ NULL,
+ NULL,
+ cmd_set_option_exec
};
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 (cmd_check_flag(data->chflags, 's')) {
+ struct args *args = self->args;
+ const struct options_table_entry *table, *oe, *oe_loop;
+ struct session *s;
+ struct winlink *wl;
+ struct client *c;
+ struct options *oo;
+ struct jobs *jobs;
+ struct job *job, *nextjob;
+ const char *optstr, *valstr;
+ u_int i;
+ int try_again;
+
+ /* Work out the options tree and table to use. */
+ if (args_has(self->args, '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'))
+ table = server_options_table;
+ } else if (args_has(self->args, 'w') ||
+ self->entry == &cmd_set_window_option_entry) {
+ table = window_options_table;
+ if (args_has(self->args, 'g'))
oo = &global_w_options;
else {
- wl = cmd_find_window(ctx, data->target, NULL);
+ wl = cmd_find_window(ctx, args_get(args, 't'), NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
- table = set_session_option_table;
- if (cmd_check_flag(data->chflags, 'g'))
+ table = session_options_table;
+ if (args_has(self->args, 'g'))
oo = &global_s_options;
else {
- s = cmd_find_session(ctx, data->target);
+ s = cmd_find_session(ctx, args_get(args, 't'));
if (s == NULL)
return (-1);
oo = &s->options;
}
}
- if (*data->arg == '\0') {
+ /* Get the option name and value. */
+ optstr = args->argv[0];
+ if (*optstr == '\0') {
ctx->error(ctx, "invalid option");
return (-1);
}
-
- entry = NULL;
- for (opt = table; opt->name != NULL; opt++) {
- if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
+ if (args->argc < 2)
+ valstr = NULL;
+ else
+ valstr = args->argv[1];
+
+ /* Find the option table entry. */
+ oe = NULL;
+ for (oe_loop = table; oe_loop->name != NULL; oe_loop++) {
+ if (strncmp(oe_loop->name, optstr, strlen(optstr)) != 0)
continue;
- if (entry != NULL) {
- ctx->error(ctx, "ambiguous option: %s", data->arg);
+
+ if (oe != NULL) {
+ ctx->error(ctx, "ambiguous option: %s", optstr);
return (-1);
}
- entry = opt;
+ oe = oe_loop;
/* Bail now if an exact match. */
- if (strcmp(entry->name, data->arg) == 0)
+ if (strcmp(oe->name, optstr) == 0)
break;
}
- if (entry == NULL) {
- ctx->error(ctx, "unknown option: %s", data->arg);
+ if (oe == NULL) {
+ ctx->error(ctx, "unknown option: %s", optstr);
return (-1);
}
- 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);
+ /* Unset or set the option. */
+ if (args_has(args, 'u')) {
+ if (cmd_set_option_unset(self, ctx, oe, oo, valstr) != 0)
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:
- cmd_set_option_string(ctx, oo, entry,
- data->arg2, cmd_check_flag(data->chflags, 'a'));
- break;
- case SET_OPTION_NUMBER:
- cmd_set_option_number(ctx, oo, entry, data->arg2);
- break;
- case SET_OPTION_KEYS:
- cmd_set_option_keys(ctx, oo, entry, data->arg2);
- break;
- case SET_OPTION_COLOUR:
- cmd_set_option_colour(ctx, oo, entry, data->arg2);
- break;
- case SET_OPTION_ATTRIBUTES:
- cmd_set_option_attributes(ctx, oo, entry, data->arg2);
- break;
- case SET_OPTION_FLAG:
- cmd_set_option_flag(ctx, oo, entry, data->arg2);
- break;
- case SET_OPTION_CHOICE:
- cmd_set_option_choice(ctx, oo, entry, data->arg2);
- break;
- }
+ if (cmd_set_option_set(self, ctx, oe, oo, valstr) != 0)
+ return (-1);
}
+ /* Update sizes and redraw. May not need it but meh. */
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
@@ -291,11 +174,11 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
* or set-titles-string have changed. Persistent jobs are only used by
* the status line at the moment so this works XXX.
*/
- if (strcmp(entry->name, "status-left") == 0 ||
- strcmp(entry->name, "status-right") == 0 ||
- strcmp(entry->name, "status") == 0 ||
- strcmp(entry->name, "set-titles-string") == 0 ||
- strcmp(entry->name, "window-status-format") == 0) {
+ if (strcmp(oe->name, "status-left") == 0 ||
+ strcmp(oe->name, "status-right") == 0 ||
+ strcmp(oe->name, "status") == 0 ||
+ strcmp(oe->name, "set-titles-string") == 0 ||
+ strcmp(oe->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
@@ -322,191 +205,176 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
}
-const char *
-cmd_set_option_print(
- const struct set_option_entry *entry, struct options_entry *o)
+/* Unset an option. */
+int
+cmd_set_option_unset(struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
- 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;
+ struct args *args = self->args;
+
+ if (args_has(args, 'g')) {
+ ctx->error(ctx, "can't unset global option: %s", oe->name);
+ return (-1);
+ }
+ if (value != NULL) {
+ ctx->error(ctx, "value passed to unset option: %s", oe->name);
+ return (-1);
}
- return (out);
+
+ options_remove(oo, oe->name);
+ ctx->info(ctx, "unset option: %s", oe->name);
+ return (0);
}
-void
-cmd_set_option_string(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value, int append)
+/* Set an option. */
+int
+cmd_set_option_set(struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
struct options_entry *o;
- char *oldvalue, *newvalue;
+ const char *s;
- if (value == NULL) {
+ if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
ctx->error(ctx, "empty value");
- return;
+ return (-1);
}
- 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));
+ o = NULL;
+ switch (oe->type) {
+ case OPTIONS_TABLE_STRING:
+ o = cmd_set_option_string(self, ctx, oe, oo, value);
+ break;
+ case OPTIONS_TABLE_NUMBER:
+ o = cmd_set_option_number(self, ctx, oe, oo, value);
+ break;
+ case OPTIONS_TABLE_KEYS:
+ o = cmd_set_option_keys(self, ctx, oe, oo, value);
+ break;
+ case OPTIONS_TABLE_COLOUR:
+ o = cmd_set_option_colour(self, ctx, oe, oo, value);
+ break;
+ case OPTIONS_TABLE_ATTRIBUTES:
+ o = cmd_set_option_attributes(self, ctx, oe, oo, value);
+ break;
+ case OPTIONS_TABLE_FLAG:
+ o = cmd_set_option_flag(self, ctx, oe, oo, value);
+ break;
+ case OPTIONS_TABLE_CHOICE:
+ o = cmd_set_option_choice(self, ctx, oe, oo, value);
+ break;
+ }
+ if (o == NULL)
+ return (-1);
- if (newvalue != value)
- xfree(newvalue);
+ s = options_table_print_entry(oe, o);
+ ctx->info(ctx, "set option: %s -> %s", oe->name, s);
+ return (0);
}
-void
-cmd_set_option_number(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
+/* Set a string option. */
+struct options_entry *
+cmd_set_option_string(struct cmd *self, unused struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
+ struct args *args = self->args;
struct options_entry *o;
- long long number;
- const char *errstr;
+ char *oldval, *newval;
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
+ if (args_has(args, 'a')) {
+ oldval = options_get_string(oo, oe->name);
+ xasprintf(&newval, "%s%s", oldval, value);
+ } else
+ newval = xstrdup(value);
- number = strtonum(value, entry->minimum, entry->maximum, &errstr);
+ o = options_set_string(oo, oe->name, "%s", newval);
+
+ xfree(newval);
+ return (o);
+}
+
+/* Set a number option. */
+struct options_entry *
+cmd_set_option_number(unused struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
+{
+ long long ll;
+ const char *errstr;
+
+ ll = strtonum(value, oe->minimum, oe->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
- return;
+ return (NULL);
}
- o = options_set_number(oo, entry->name, number);
- ctx->info(ctx,
- "set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
+ return (options_set_number(oo, oe->name, ll));
}
-void
-cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
+/* Set a keys option. */
+struct options_entry *
+cmd_set_option_keys(unused struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
- struct options_entry *o;
- struct keylist *keylist;
- char *copyvalue, *ptr, *str;
- int key;
-
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
+ struct keylist *keylist;
+ char *copy, *ptr, *s;
+ int key;
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) {
+ ptr = copy = xstrdup(value);
+ while ((s = strsep(&ptr, ",")) != NULL) {
+ if ((key = key_string_lookup_string(s)) == KEYC_NONE) {
+ ctx->error(ctx, "unknown key: %s", s);
+ xfree(copy);
xfree(keylist);
- ctx->error(ctx, "unknown key: %s", str);
- xfree(copyvalue);
- return;
+ return (NULL);
}
ARRAY_ADD(keylist, key);
}
- xfree(copyvalue);
+ xfree(copy);
- o = options_set_data(oo, entry->name, keylist, xfree);
- ctx->info(ctx,
- "set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
+ return (options_set_data(oo, oe->name, keylist, xfree));
}
-void
-cmd_set_option_colour(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
+/* Set a colour option. */
+struct options_entry *
+cmd_set_option_colour(unused struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
- struct options_entry *o;
- int colour;
-
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
+ int colour;
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
- return;
+ return (NULL);
}
- o = options_set_number(oo, entry->name, colour);
- ctx->info(ctx,
- "set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
+ return (options_set_number(oo, oe->name, colour));
}
-void
-cmd_set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
+/* Set an attributes option. */
+struct options_entry *
+cmd_set_option_attributes(unused struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
- struct options_entry *o;
- int attr;
-
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
+ int attr;
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
- return;
+ return (NULL);
}
- o = options_set_number(oo, entry->name, attr);
- ctx->info(ctx,
- "set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
+ return (options_set_number(oo, oe->name, attr));
}
-void
-cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
+/* Set a flag option. */
+struct options_entry *
+cmd_set_option_flag(unused struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
- struct options_entry *o;
- int flag;
+ int flag;
if (value == NULL || *value == '\0')
- flag = !options_get_number(oo, entry->name);
+ flag = !options_get_number(oo, oe->name);
else {
if ((value[0] == '1' && value[1] == '\0') ||
strcasecmp(value, "on") == 0 ||
@@ -518,46 +386,37 @@ cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
- return;
+ return (NULL);
}
}
- o = options_set_number(oo, entry->name, flag);
- ctx->info(ctx,
- "set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
+ return (options_set_number(oo, oe->name, flag));
}
-void
-cmd_set_option_choice(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
+/* Set a choice option. */
+struct options_entry *
+cmd_set_option_choice(unused struct cmd *self, struct cmd_ctx *ctx,
+ const struct options_table_entry *oe, struct options *oo, const char *value)
{
- struct options_entry *o;
- const char **choicep;
- int n, choice = -1;
-
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
+ const char **choicep;
+ int n, choice = -1;
n = 0;
- for (choicep = entry->choices; *choicep != NULL; choicep++) {
+ for (choicep = oe->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;
+ ctx->error(ctx, "ambiguous value: %s", value);
+ return (NULL);
}
choice = n - 1;
}
if (choice == -1) {
- ctx->error(ctx, "unknown option value: %s", value);
- return;
+ ctx->error(ctx, "unknown value: %s", value);
+ return (NULL);
}
- o = options_set_number(oo, entry->name, choice);
- ctx->info(ctx,
- "set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
+ return (options_set_number(oo, oe->name, choice));
}
diff --git a/cmd-set-option.o b/cmd-set-option.o
new file mode 100644
index 0000000..ded0e95
--- a/dev/null
+++ b/cmd-set-option.o
Binary files differ
diff --git a/cmd-set-window-option.c b/cmd-set-window-option.c
deleted file mode 100644
index 6fbcdb3..0000000
--- a/cmd-set-window-option.c
+++ b/dev/null
@@ -1,47 +0,0 @@
-/* $Id: cmd-set-window-option.c,v 1.43 2009/12/04 22:11:23 tcunha Exp $ */
-
-/*
- * Copyright (c) 2008 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include "tmux.h"
-
-/*
- * Set a window option. This is just an alias for set-option -w.
- */
-
-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, "agu",
- NULL,
- cmd_target_parse,
- cmd_set_window_option_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-int
-cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_target_data *data = self->data;
-
- cmd_set_flag(&data->chflags, 'w');
- return (cmd_set_option_entry.exec(self, ctx));
-}
diff --git a/cmd-set-window-option.o b/cmd-set-window-option.o
new file mode 100644
index 0000000..73b524c
--- a/dev/null
+++ b/cmd-set-window-option.o
Binary files differ
diff --git a/cmd-show-buffer.c b/cmd-show-buffer.c
index 0d9d9b5..4222697 100644
--- a/cmd-show-buffer.c
+++ b/cmd-show-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-show-buffer.c,v 1.12 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-show-buffer.c,v 1.14 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,39 +28,47 @@ 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, "",
- cmd_buffer_init,
- cmd_buffer_parse,
- cmd_show_buffer_exec,
- cmd_buffer_free,
- cmd_buffer_print
+ "b:", 0, 0,
+ CMD_BUFFER_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_show_buffer_exec
};
int
cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_buffer_data *data = self->data;
+ struct args *args = self->args;
struct session *s;
struct paste_buffer *pb;
- char *in, *buf, *ptr;
+ int buffer;
+ char *in, *buf, *ptr, *cause;
size_t size, len;
u_int width;
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ if ((s = cmd_find_session(ctx, NULL)) == NULL)
return (-1);
- if (data->buffer == -1) {
- if ((pb = paste_get_top(&s->buffers)) == NULL) {
+ if (!args_has(args, 'b')) {
+ if ((pb = paste_get_top(&global_buffers)) == NULL) {
ctx->error(ctx, "no buffers");
return (-1);
}
- } else if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) {
- ctx->error(ctx, "no buffer %d", data->buffer);
- return (-1);
+ } else {
+ buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "buffer %s", cause);
+ xfree(cause);
+ return (-1);
+ }
+
+ pb = paste_get_index(&global_buffers, buffer);
+ if (pb == NULL) {
+ ctx->error(ctx, "no buffer %d", buffer);
+ return (-1);
+ }
}
- if (pb == NULL)
- return (0);
size = pb->size;
if (size > SIZE_MAX / 4 - 1)
diff --git a/cmd-show-buffer.o b/cmd-show-buffer.o
new file mode 100644
index 0000000..41ef87a
--- a/dev/null
+++ b/cmd-show-buffer.o
Binary files differ
diff --git a/cmd-show-environment.c b/cmd-show-environment.c
index ed12f27..007ffbe 100644
--- a/cmd-show-environment.c
+++ b/cmd-show-environment.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-show-environment.c,v 1.2 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-show-environment.c,v 1.3 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -31,27 +31,26 @@ int cmd_show_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv",
+ "gt:", 0, 0,
"[-g] " CMD_TARGET_SESSION_USAGE,
- 0, "g",
- cmd_target_init,
- cmd_target_parse,
- cmd_show_environment_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_show_environment_exec
};
int
cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
- struct environ *env;
- struct environ_entry *envent;
+ struct args *args = self->args;
+ struct session *s;
+ struct environ *env;
+ struct environ_entry *envent;
- if (cmd_check_flag(data->chflags, 'g'))
+ if (args_has(self->args, 'g'))
env = &global_environ;
else {
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ if ((s = cmd_find_session(ctx, args_get(args, 't'))) == NULL)
return (-1);
env = &s->environ;
}
diff --git a/cmd-show-environment.o b/cmd-show-environment.o
new file mode 100644
index 0000000..57bb7d9
--- a/dev/null
+++ b/cmd-show-environment.o
Binary files differ
diff --git a/cmd-show-messages.c b/cmd-show-messages.c
index 8b3f689..50120f9 100644
--- a/cmd-show-messages.c
+++ b/cmd-show-messages.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-show-messages.c,v 1.2 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-show-messages.c,v 1.3 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -31,25 +31,24 @@ int cmd_show_messages_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
+ "t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_show_messages_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_show_messages_exec
};
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;
+ struct args *args = self->args;
+ struct client *c;
+ struct message_entry *msg;
+ char *tim;
+ u_int i;
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
diff --git a/cmd-show-messages.o b/cmd-show-messages.o
new file mode 100644
index 0000000..cfe0320
--- a/dev/null
+++ b/cmd-show-messages.o
Binary files differ
diff --git a/cmd-show-options.c b/cmd-show-options.c
index d3f00a3..b8ec23b 100644
--- a/cmd-show-options.c
+++ b/cmd-show-options.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-show-options.c,v 1.21 2009/12/10 16:59:02 tcunha Exp $ */
+/* $Id: cmd-show-options.c,v 1.24 2011/01/07 15:02:38 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -31,57 +31,66 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_options_entry = {
"show-options", "show",
+ "gst:w", 0, 0,
"[-gsw] [-t target-session|target-window]",
- 0, "gsw",
- cmd_target_init,
- cmd_target_parse,
- cmd_show_options_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_show_options_exec
+};
+
+const struct cmd_entry cmd_show_window_options_entry = {
+ "show-window-options", "showw",
+ "gt:", 0, 0,
+ "[-g] " CMD_TARGET_WINDOW_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_show_options_exec
};
int
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- const struct set_option_entry *table;
- struct session *s;
- struct winlink *wl;
- struct options *oo;
- struct options_entry *o;
- const struct set_option_entry *entry;
- const char *optval;
+ struct args *args = self->args;
+ const struct options_table_entry *table, *oe;
+ struct session *s;
+ struct winlink *wl;
+ struct options *oo;
+ struct options_entry *o;
+ const char *optval;
- if (cmd_check_flag(data->chflags, 's')) {
+ if (args_has(self->args, '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'))
+ table = server_options_table;
+ } else if (args_has(self->args, 'w') ||
+ self->entry == &cmd_show_window_options_entry) {
+ table = window_options_table;
+ if (args_has(self->args, 'g'))
oo = &global_w_options;
else {
- wl = cmd_find_window(ctx, data->target, NULL);
+ wl = cmd_find_window(ctx, args_get(args, 't'), NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
- table = set_session_option_table;
- if (cmd_check_flag(data->chflags, 'g'))
+ table = session_options_table;
+ if (args_has(self->args, 'g'))
oo = &global_s_options;
else {
- s = cmd_find_session(ctx, data->target);
+ s = cmd_find_session(ctx, args_get(args, 't'));
if (s == NULL)
return (-1);
oo = &s->options;
}
}
- for (entry = table; entry->name != NULL; entry++) {
- if ((o = options_find1(oo, entry->name)) == NULL)
+ for (oe = table; oe->name != NULL; oe++) {
+ if ((o = options_find1(oo, oe->name)) == NULL)
continue;
- optval = cmd_set_option_print(entry, o);
- ctx->print(ctx, "%s %s", entry->name, optval);
+ optval = options_table_print_entry(oe, o);
+ ctx->print(ctx, "%s %s", oe->name, optval);
}
return (0);
diff --git a/cmd-show-options.o b/cmd-show-options.o
new file mode 100644
index 0000000..877d84a
--- a/dev/null
+++ b/cmd-show-options.o
Binary files differ
diff --git a/cmd-show-window-options.c b/cmd-show-window-options.c
deleted file mode 100644
index 78de972..0000000
--- a/cmd-show-window-options.c
+++ b/dev/null
@@ -1,50 +0,0 @@
-/* $Id: cmd-show-window-options.c,v 1.15 2009/12/04 22:11:23 tcunha Exp $ */
-
-/*
- * Copyright (c) 2008 Nicholas Marriott <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "tmux.h"
-
-/*
- * Show window options. This is an alias for show-options -w.
- */
-
-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, "g",
- cmd_target_init,
- cmd_target_parse,
- cmd_show_window_options_exec,
- cmd_target_free,
- cmd_target_print
-};
-
-int
-cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
-{
- struct cmd_target_data *data = self->data;
-
- cmd_set_flag(&data->chflags, 'w');
- return (cmd_show_options_entry.exec(self, ctx));
-}
diff --git a/cmd-show-window-options.o b/cmd-show-window-options.o
new file mode 100644
index 0000000..9e16adb
--- a/dev/null
+++ b/cmd-show-window-options.o
Binary files differ
diff --git a/cmd-source-file.c b/cmd-source-file.c
index e44c974..aa8c953 100644
--- a/cmd-source-file.c
+++ b/cmd-source-file.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-source-file.c,v 1.13 2010/02/08 18:29:32 tcunha Exp $ */
+/* $Id: cmd-source-file.c,v 1.15 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2008 Tiago Cunha <[email protected]>
@@ -24,108 +24,51 @@
* Sources a configuration file.
*/
-int cmd_source_file_parse(struct cmd *, int, char **, char **);
int cmd_source_file_exec(struct cmd *, struct cmd_ctx *);
-void cmd_source_file_free(struct cmd *);
-void cmd_source_file_init(struct cmd *, int);
-size_t cmd_source_file_print(struct cmd *, char *, size_t);
-
-struct cmd_source_file_data {
- char *path;
-};
const struct cmd_entry cmd_source_file_entry = {
"source-file", "source",
+ "", 1, 1,
"path",
- 0, "",
- cmd_source_file_init,
- cmd_source_file_parse,
- cmd_source_file_exec,
- cmd_source_file_free,
- cmd_source_file_print
+ 0,
+ NULL,
+ NULL,
+ cmd_source_file_exec
};
-/* ARGSUSED */
-void
-cmd_source_file_init(struct cmd *self, unused int arg)
-{
- struct cmd_source_file_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->path = NULL;
-}
-
-int
-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, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "")) != -1) {
- switch (opt) {
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 1)
- goto usage;
-
- data->path = 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_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;
+ struct args *args = self->args;
+ struct causelist causes;
+ char *cause;
+ struct window_pane *wp;
+ int retval;
+ u_int i;
ARRAY_INIT(&causes);
- if (load_cfg(data->path, ctx, &causes) != 0) {
+
+ retval = load_cfg(args->argv[0], ctx, &causes);
+ if (ARRAY_EMPTY(&causes))
+ return (retval);
+
+ if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) {
+ wp = RB_MIN(sessions, &sessions)->curw->window->active;
+ window_pane_set_mode(wp, &window_copy_mode);
+ window_copy_init_for_output(wp);
+ for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
+ cause = ARRAY_ITEM(&causes, i);
+ window_copy_add(wp, "%s", cause);
+ xfree(cause);
+ }
+ } else {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
xfree(cause);
}
- ARRAY_FREE(&causes);
}
+ ARRAY_FREE(&causes);
- return (0);
-}
-
-void
-cmd_source_file_free(struct cmd *self)
-{
- struct cmd_source_file_data *data = self->data;
-
- if (data->path != NULL)
- xfree(data->path);
- xfree(data);
-}
-
-size_t
-cmd_source_file_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_source_file_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->path != NULL)
- off += cmd_prarg(buf + off, len - off, " ", data->path);
- return (off);
+ return (retval);
}
diff --git a/cmd-source-file.o b/cmd-source-file.o
new file mode 100644
index 0000000..cdc7c69
--- a/dev/null
+++ b/cmd-source-file.o
Binary files differ
diff --git a/cmd-split-window.c b/cmd-split-window.c
index 01cb193..be35e94 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-split-window.c,v 1.35 2010/07/02 02:49:19 tcunha Exp $ */
+/* $Id: cmd-split-window.c,v 1.37 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -27,137 +27,44 @@
* Split a window (add a new pane).
*/
-int cmd_split_window_parse(struct cmd *, int, char **, char **);
+void cmd_split_window_key_binding(struct cmd *, int);
int cmd_split_window_exec(struct cmd *, struct cmd_ctx *);
-void cmd_split_window_free(struct cmd *);
-void cmd_split_window_init(struct cmd *, int);
-size_t cmd_split_window_print(struct cmd *, char *, size_t);
-
-struct cmd_split_window_data {
- char *target;
- char *cmd;
- int flag_detached;
- int flag_horizontal;
- int percentage;
- int size;
-};
const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
- "[-dhv] [-p percentage|-l size] [-t target-pane] [command]",
- 0, "",
- cmd_split_window_init,
- cmd_split_window_parse,
- cmd_split_window_exec,
- cmd_split_window_free,
- cmd_split_window_print
+ "dl:hp:Pt:v", 0, 1,
+ "[-dhvP] [-p percentage|-l size] [-t target-pane] [command]",
+ 0,
+ cmd_split_window_key_binding,
+ NULL,
+ cmd_split_window_exec
};
void
-cmd_split_window_init(struct cmd *self, int key)
+cmd_split_window_key_binding(struct cmd *self, int key)
{
- struct cmd_split_window_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->target = NULL;
- data->cmd = 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_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_split_window_data *data;
- int opt;
- const char *errstr;
-
- self->entry->init(self, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "dhl:p:t:v")) != -1) {
- switch (opt) {
- case 'd':
- data->flag_detached = 1;
- break;
- case 'h':
- data->flag_horizontal = 1;
- break;
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- case 'l':
- if (data->percentage != -1 || data->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 && argc != 1)
- goto usage;
-
- if (argc == 1)
- data->cmd = xstrdup(argv[0]);
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
-error:
- self->entry->free(self);
- return (-1);
+ self->args = args_create(0);
+ if (key == '%')
+ args_set(self->args, 'h', NULL);
}
int
cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_split_window_data *data = self->data;
- struct session *s;
- struct winlink *wl;
- struct window *w;
- 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_pane(ctx, data->target, &s, &wp)) == NULL)
+ struct args *args = self->args;
+ struct session *s;
+ struct winlink *wl;
+ struct window *w;
+ struct window_pane *wp, *new_wp = NULL;
+ struct environ env;
+ char *cmd, *cwd, *cause;
+ const char *shell;
+ u_int hlimit, paneidx;
+ int size, percentage;
+ enum layout_type type;
+ struct layout_cell *lc;
+
+ if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
return (-1);
w = wl->window;
@@ -166,9 +73,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
- cmd = data->cmd;
- if (cmd == NULL)
+ if (args->argc == 0)
cmd = options_get_string(&s->options, "default-command");
+ else
+ cmd = args->argv[0];
cwd = options_get_string(&s->options, "default-path");
if (*cwd == '\0') {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
@@ -178,17 +86,28 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
type = LAYOUT_TOPBOTTOM;
- if (data->flag_horizontal)
+ if (args_has(args, 'h'))
type = LAYOUT_LEFTRIGHT;
size = -1;
- if (data->size != -1)
- size = data->size;
- else if (data->percentage != -1) {
+ if (args_has(args, 's')) {
+ size = args_strtonum(args, 's', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "size %s", cause);
+ xfree(cause);
+ return (-1);
+ }
+ } else if (args_has(args, 'p')) {
+ percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
+ if (cause != NULL) {
+ ctx->error(ctx, "percentage %s", cause);
+ xfree(cause);
+ return (-1);
+ }
if (type == LAYOUT_TOPBOTTOM)
- size = (wp->sy * data->percentage) / 100;
+ size = (wp->sy * percentage) / 100;
else
- size = (wp->sx * data->percentage) / 100;
+ size = (wp->sx * percentage) / 100;
}
hlimit = options_get_number(&s->options, "history-limit");
@@ -208,7 +127,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_window(w);
- if (!data->flag_detached) {
+ if (!args_has(args, 'd')) {
window_set_active_pane(w, new_wp);
session_select(s, wl->idx);
server_redraw_session(s);
@@ -216,6 +135,11 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
server_status_session(s);
environ_free(&env);
+
+ if (args_has(args, 'P')) {
+ paneidx = window_pane_index(wl->window, new_wp);
+ ctx->print(ctx, "%s:%u.%u", s->name, wl->idx, paneidx);
+ }
return (0);
error:
@@ -226,41 +150,3 @@ error:
xfree(cause);
return (-1);
}
-
-void
-cmd_split_window_free(struct cmd *self)
-{
- struct cmd_split_window_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- if (data->cmd != NULL)
- xfree(data->cmd);
- xfree(data);
-}
-
-size_t
-cmd_split_window_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_split_window_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->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);
-}
diff --git a/cmd-split-window.o b/cmd-split-window.o
new file mode 100644
index 0000000..c170400
--- a/dev/null
+++ b/cmd-split-window.o
Binary files differ
diff --git a/cmd-start-server.c b/cmd-start-server.c
index 9d94c83..399e8e1 100644
--- a/cmd-start-server.c
+++ b/cmd-start-server.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-start-server.c,v 1.10 2009/11/28 14:50:36 tcunha Exp $ */
+/* $Id: cmd-start-server.c,v 1.11 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,13 +28,12 @@ int cmd_start_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_start_server_entry = {
"start-server", "start",
+ "", 0, 0,
"",
- CMD_STARTSERVER, "",
+ CMD_STARTSERVER,
NULL,
NULL,
- cmd_start_server_exec,
- NULL,
- NULL
+ cmd_start_server_exec
};
/* ARGSUSED */
diff --git a/cmd-start-server.o b/cmd-start-server.o
new file mode 100644
index 0000000..8a11f73
--- a/dev/null
+++ b/cmd-start-server.o
Binary files differ
diff --git a/cmd-string.c b/cmd-string.c
index 533e0dd..9e58974 100644
--- a/cmd-string.c
+++ b/cmd-string.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-string.c,v 1.31 2010/02/26 13:27:38 tcunha Exp $ */
+/* $Id: cmd-string.c,v 1.32 2010/12/13 22:53:56 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -247,9 +247,10 @@ error:
char *
cmd_string_variable(const char *s, size_t *p)
{
- int ch, fch;
- char *buf, *t;
- size_t len;
+ int ch, fch;
+ char *buf, *t;
+ size_t len;
+ struct environ_entry *envent;
#define cmd_string_first(ch) ((ch) == '_' || \
((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z'))
@@ -301,12 +302,11 @@ cmd_string_variable(const char *s, size_t *p)
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
- if ((t = getenv(buf)) == NULL) {
- xfree(buf);
- return (xstrdup(""));
- }
+ envent = environ_find(&global_environ, buf);
xfree(buf);
- return (xstrdup(t));
+ if (envent == NULL)
+ return (xstrdup(""));
+ return (xstrdup(envent->value));
error:
if (buf != NULL)
@@ -317,15 +317,17 @@ error:
char *
cmd_string_expand_tilde(const char *s, size_t *p)
{
- struct passwd *pw;
- char *home, *path, *username;
+ struct passwd *pw;
+ struct environ_entry *envent;
+ char *home, *path, *username;
home = NULL;
if (cmd_string_getc(s, p) == '/') {
- if ((home = getenv("HOME")) == NULL || *home == '\0') {
- if ((pw = getpwuid(getuid())) != NULL)
- home = pw->pw_dir;
- }
+ envent = environ_find(&global_environ, "HOME");
+ if (envent != NULL && *envent->value != '\0')
+ home = envent->value;
+ else if ((pw = getpwuid(getuid())) != NULL)
+ home = pw->pw_dir;
} else {
cmd_string_ungetc(p);
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
diff --git a/cmd-string.o b/cmd-string.o
new file mode 100644
index 0000000..dbcdf01
--- a/dev/null
+++ b/cmd-string.o
Binary files differ
diff --git a/cmd-suspend-client.c b/cmd-suspend-client.c
index 1bfadb0..2289607 100644
--- a/cmd-suspend-client.c
+++ b/cmd-suspend-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-suspend-client.c,v 1.5 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-suspend-client.c,v 1.7 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -29,29 +29,23 @@
int cmd_suspend_client_exec(struct cmd *, struct cmd_ctx *);
-struct cmd_suspend_client_data {
- char *name;
- char *target;
-};
-
const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
- "[-c target-client]",
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_suspend_client_exec,
- cmd_target_free,
- cmd_target_print
+ "t:", 0, 0,
+ CMD_TARGET_CLIENT_USAGE,
+ 0,
+ NULL,
+ NULL,
+ cmd_suspend_client_exec
};
int
cmd_suspend_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 't'))) == NULL)
return (-1);
tty_stop_tty(&c->tty);
diff --git a/cmd-suspend-client.o b/cmd-suspend-client.o
new file mode 100644
index 0000000..e18dc41
--- a/dev/null
+++ b/cmd-suspend-client.o
Binary files differ
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
index 8fb6d55..19b9755 100644
--- a/cmd-swap-pane.c
+++ b/cmd-swap-pane.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-swap-pane.c,v 1.15 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-swap-pane.c,v 1.16 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -26,66 +26,58 @@
* Swap two panes.
*/
-void cmd_swap_pane_init(struct cmd *, int);
+void cmd_swap_pane_key_binding(struct cmd *, int);
int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp",
+ "dDs:t:U", 0, 0,
"[-dDU] " CMD_SRCDST_PANE_USAGE,
- 0, "dDU",
- cmd_swap_pane_init,
- cmd_srcdst_parse,
- cmd_swap_pane_exec,
- cmd_srcdst_free,
- cmd_srcdst_print
+ 0,
+ cmd_swap_pane_key_binding,
+ NULL,
+ cmd_swap_pane_exec
};
void
-cmd_swap_pane_init(struct cmd *self, int key)
+cmd_swap_pane_key_binding(struct cmd *self, int key)
{
- struct cmd_target_data *data;
-
- cmd_srcdst_init(self, key);
- data = self->data;
-
+ self->args = args_create(0);
if (key == '{')
- cmd_set_flag(&data->chflags, 'U');
+ args_set(self->args, 'U', NULL);
else if (key == '}')
- cmd_set_flag(&data->chflags, 'D');
+ args_set(self->args, 'D', NULL);
}
-
int
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_srcdst_data *data = self->data;
+ struct args *args = self->args;
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w;
struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *src_lc, *dst_lc;
u_int sx, sy, xoff, yoff;
- if (data == NULL)
- return (0);
-
- if ((dst_wl = cmd_find_pane(ctx, data->dst, NULL, &dst_wp)) == NULL)
+ dst_wl = cmd_find_pane(ctx, args_get(args, 't'), NULL, &dst_wp);
+ if (dst_wl == NULL)
return (-1);
dst_w = dst_wl->window;
- if (data->src == NULL) {
+ if (!args_has(args, 's')) {
src_w = dst_w;
- if (cmd_check_flag(data->chflags, 'D')) {
+ if (args_has(self->args, 'D')) {
src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes);
- } else if (cmd_check_flag(data->chflags, 'U')) {
+ } else if (args_has(self->args, 'U')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
} else
return (0);
} else {
- src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp);
+ src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp);
if (src_wl == NULL)
return (-1);
src_w = src_wl->window;
@@ -121,7 +113,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 (!cmd_check_flag(data->chflags, 'd')) {
+ if (!args_has(self->args, 'd')) {
if (src_w != dst_w) {
window_set_active_pane(src_w, dst_wp);
window_set_active_pane(dst_w, src_wp);
diff --git a/cmd-swap-pane.o b/cmd-swap-pane.o
new file mode 100644
index 0000000..f553975
--- a/dev/null
+++ b/cmd-swap-pane.o
Binary files differ
diff --git a/cmd-swap-window.c b/cmd-swap-window.c
index e12c29e..f9b832d 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-swap-window.c,v 1.19 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: cmd-swap-window.c,v 1.20 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,27 +30,29 @@ int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw",
+ "ds:t:", 0, 0,
"[-d] " CMD_SRCDST_WINDOW_USAGE,
- 0, "d",
- cmd_srcdst_init,
- cmd_srcdst_parse,
- cmd_swap_window_exec,
- cmd_srcdst_free,
- cmd_srcdst_print
+ 0,
+ NULL,
+ NULL,
+ cmd_swap_window_exec
};
int
cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_srcdst_data *data = self->data;
+ struct args *args = self->args;
+ const char *target_src, *target_dst;
struct session *src, *dst;
struct session_group *sg_src, *sg_dst;
struct winlink *wl_src, *wl_dst;
struct window *w;
- if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
+ target_src = args_get(args, 's');
+ if ((wl_src = cmd_find_window(ctx, target_src, &src)) == NULL)
return (-1);
- if ((wl_dst = cmd_find_window(ctx, data->dst, &dst)) == NULL)
+ target_dst = args_get(args, 't');
+ if ((wl_dst = cmd_find_window(ctx, target_dst, &dst)) == NULL)
return (-1);
sg_src = session_group_find(src);
@@ -68,7 +70,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl_dst->window = wl_src->window;
wl_src->window = w;
- if (!cmd_check_flag(data->chflags, 'd')) {
+ if (!args_has(self->args, 'd')) {
session_select(dst, wl_dst->idx);
if (src != dst)
session_select(src, wl_src->idx);
diff --git a/cmd-swap-window.o b/cmd-swap-window.o
new file mode 100644
index 0000000..02ab835
--- a/dev/null
+++ b/cmd-swap-window.o
Binary files differ
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index dd34643..486533e 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-switch-client.c,v 1.20 2010/09/10 13:36:17 tcunha Exp $ */
+/* $Id: cmd-switch-client.c,v 1.25 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -27,164 +27,77 @@
* Switch client to a different session.
*/
-void cmd_switch_client_init(struct cmd *, int);
-int cmd_switch_client_parse(struct cmd *, int, char **, char **);
+void cmd_switch_client_key_binding(struct cmd *, int);
int cmd_switch_client_exec(struct cmd *, struct cmd_ctx *);
-void cmd_switch_client_free(struct cmd *);
-size_t cmd_switch_client_print(struct cmd *, char *, size_t);
-
-struct cmd_switch_client_data {
- char *name;
- char *target;
- int flag_next;
- int flag_previous;
-};
const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc",
- "[-np] [-c target-client] [-t target-session]",
- 0, "",
- cmd_switch_client_init,
- cmd_switch_client_parse,
- cmd_switch_client_exec,
- cmd_switch_client_free,
- cmd_switch_client_print
+ "lc:npt:", 0, 0,
+ "[-lnp] [-c target-client] [-t target-session]",
+ 0,
+ cmd_switch_client_key_binding,
+ NULL,
+ cmd_switch_client_exec
};
void
-cmd_switch_client_init(struct cmd *self, int key)
+cmd_switch_client_key_binding(struct cmd *self, int key)
{
- struct cmd_switch_client_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- data->name = NULL;
- data->target = NULL;
- data->flag_next = 0;
- data->flag_previous = 0;
-
+ self->args = args_create(0);
switch (key) {
case '(':
- data->flag_previous = 1;
+ args_set(self->args, 'p', NULL);
break;
case ')':
- data->flag_next = 1;
+ args_set(self->args, 'n', NULL);
+ break;
+ case 'L':
+ args_set(self->args, 'l', NULL);
break;
}
}
int
-cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_switch_client_data *data;
- int opt;
-
- self->entry->init(self, KEYC_NONE);
- data = self->data;
-
- while ((opt = getopt(argc, argv, "c:t:")) != -1) {
- switch (opt) {
- case 'c':
- if (data->name == NULL)
- data->name = xstrdup(optarg);
- break;
- case 't':
- if (data->flag_next || data->flag_previous)
- goto usage;
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- case 'n':
- if (data->flag_previous || data->target != NULL)
- goto usage;
- data->flag_next = 1;
- break;
- case 'p':
- if (data->flag_next || data->target != NULL)
- goto usage;
- data->flag_next = 1;
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 0)
- goto usage;
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
-}
-
-int
cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_switch_client_data *data = self->data;
- struct client *c;
- struct session *s;
-
- if (data == NULL)
- return (0);
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
- if ((c = cmd_find_client(ctx, data->name)) == NULL)
+ if ((c = cmd_find_client(ctx, args_get(args, 'c'))) == NULL)
return (-1);
- if (data->flag_next) {
+ s = NULL;
+ if (args_has(args, 'n')) {
if ((s = session_next_session(c->session)) == NULL) {
ctx->error(ctx, "can't find next session");
return (-1);
}
- } else if (data->flag_previous) {
+ } else if (args_has(args, 'p')) {
if ((s = session_previous_session(c->session)) == NULL) {
ctx->error(ctx, "can't find previous session");
return (-1);
}
+ } else if (args_has(args, 'l')) {
+ if (c->last_session != NULL && session_alive(c->last_session))
+ s = c->last_session;
+ if (s == NULL) {
+ ctx->error(ctx, "can't find last session");
+ return (-1);
+ }
} else
- s = cmd_find_session(ctx, data->target);
-
+ s = cmd_find_session(ctx, args_get(args, 't'));
if (s == NULL)
return (-1);
+
+ if (c->session != NULL)
+ c->last_session = c->session;
c->session = s;
+ session_update_activity(s);
recalculate_sizes();
+ server_check_unattached();
server_redraw_client(c);
return (0);
}
-
-void
-cmd_switch_client_free(struct cmd *self)
-{
- struct cmd_switch_client_data *data = self->data;
-
- if (data->name != NULL)
- xfree(data->name);
- if (data->target != NULL)
- xfree(data->target);
- xfree(data);
-}
-
-size_t
-cmd_switch_client_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_switch_client_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_next)
- off += xsnprintf(buf + off, len - off, "%s", " -n");
- if (off < len && data->flag_previous)
- off += xsnprintf(buf + off, len - off, "%s", " -p");
- if (off < len && data->name != NULL)
- off += cmd_prarg(buf + off, len - off, " -c ", data->name);
- if (off < len && data->target != NULL)
- off += cmd_prarg(buf + off, len - off, " -t ", data->target);
- return (off);
-}
diff --git a/cmd-switch-client.o b/cmd-switch-client.o
new file mode 100644
index 0000000..c06b314
--- a/dev/null
+++ b/cmd-switch-client.o
Binary files differ
diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c
index 2aa51f5..8bf0fc6 100644
--- a/cmd-unbind-key.c
+++ b/cmd-unbind-key.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-unbind-key.c,v 1.22 2010/01/25 17:12:44 tcunha Exp $ */
+/* $Id: cmd-unbind-key.c,v 1.25 2011/01/21 23:46:09 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -24,120 +24,82 @@
* Unbind key from command.
*/
-int cmd_unbind_key_parse(struct cmd *, int, char **, char **);
+int cmd_unbind_key_check(struct args *);
int cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *);
-void cmd_unbind_key_free(struct cmd *);
-int cmd_unbind_key_table(struct cmd *, struct cmd_ctx *);
-
-struct cmd_unbind_key_data {
- int key;
-
- int command_key;
- char *tablename;
-};
+int cmd_unbind_key_table(struct cmd *, struct cmd_ctx *, int);
const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind",
- "[-cn] [-t key-table] key",
- 0, "",
+ "acnt:", 0, 1,
+ "[-acn] [-t key-table] key",
+ 0,
NULL,
- cmd_unbind_key_parse,
- cmd_unbind_key_exec,
- cmd_unbind_key_free,
- NULL
+ cmd_unbind_key_check,
+ cmd_unbind_key_exec
};
int
-cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
+cmd_unbind_key_check(struct args *args)
{
- struct cmd_unbind_key_data *data;
- int opt, no_prefix = 0;
-
- self->data = data = xmalloc(sizeof *data);
- data->command_key = 0;
- data->tablename = NULL;
-
- while ((opt = getopt(argc, argv, "cnt:")) != -1) {
- switch (opt) {
- case 'c':
- data->command_key = 1;
- break;
- case 'n':
- no_prefix = 1;
- break;
- case 't':
- if (data->tablename == NULL)
- data->tablename = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 1)
- goto usage;
-
- if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) {
- xasprintf(cause, "unknown key: %s", argv[0]);
- goto error;
- }
- if (!no_prefix)
- data->key |= KEYC_PREFIX;
-
+ if (args_has(args, 'a') && (args->argc != 0 || args_has(args, 't')))
+ return (-1);
+ if (!args_has(args, 'a') && args->argc != 1)
+ return (-1);
return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
-error:
- xfree(data);
- return (-1);
}
int
cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
{
- struct cmd_unbind_key_data *data = self->data;
-
- if (data == NULL)
+ struct args *args = self->args;
+ struct key_binding *bd;
+ int key;
+
+ if (args_has(args, 'a')) {
+ while (!SPLAY_EMPTY(&key_bindings)) {
+ bd = SPLAY_ROOT(&key_bindings);
+ SPLAY_REMOVE(key_bindings, &key_bindings, bd);
+ cmd_list_free(bd->cmdlist);
+ xfree(bd);
+ }
return (0);
- if (data->tablename != NULL)
- return (cmd_unbind_key_table(self, ctx));
+ }
+
+ key = key_string_lookup_string(args->argv[0]);
+ if (key == KEYC_NONE) {
+ ctx->error(ctx, "unknown key: %s", args->argv[0]);
+ return (-1);
+ }
- key_bindings_remove(data->key);
+ if (args_has(args, 't'))
+ return (cmd_unbind_key_table(self, ctx, key));
+ if (!args_has(args, 'n'))
+ key |= KEYC_PREFIX;
+ key_bindings_remove(key);
return (0);
}
int
-cmd_unbind_key_table(struct cmd *self, struct cmd_ctx *ctx)
+cmd_unbind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
{
- struct cmd_unbind_key_data *data = self->data;
+ struct args *args = self->args;
+ const char *tablename;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind, mtmp;
- if ((mtab = mode_key_findtable(data->tablename)) == NULL) {
- ctx->error(ctx, "unknown key table: %s", data->tablename);
+ tablename = args_get(args, 't');
+ if ((mtab = mode_key_findtable(tablename)) == NULL) {
+ ctx->error(ctx, "unknown key table: %s", tablename);
return (-1);
}
- mtmp.key = data->key & ~KEYC_PREFIX;
- mtmp.mode = data->command_key ? 1 : 0;
+ mtmp.key = key;
+ mtmp.mode = !!args_has(args, 'c');
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
SPLAY_REMOVE(mode_key_tree, mtab->tree, mbind);
xfree(mbind);
}
return (0);
}
-
-void
-cmd_unbind_key_free(struct cmd *self)
-{
- struct cmd_unbind_key_data *data = self->data;
-
- if (data->tablename != NULL)
- xfree(data->tablename);
- xfree(data);
-}
diff --git a/cmd-unbind-key.o b/cmd-unbind-key.o
new file mode 100644
index 0000000..0b10f7c
--- a/dev/null
+++ b/cmd-unbind-key.o
Binary files differ
diff --git a/cmd-unlink-window.c b/cmd-unlink-window.c
index 784461f..c966d89 100644
--- a/cmd-unlink-window.c
+++ b/cmd-unlink-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-unlink-window.c,v 1.21 2009/12/04 22:14:47 tcunha Exp $ */
+/* $Id: cmd-unlink-window.c,v 1.22 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,26 +28,25 @@ int cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
+ "kt:", 0, 0,
"[-k] " CMD_TARGET_WINDOW_USAGE,
- 0, "k",
- cmd_target_init,
- cmd_target_parse,
- cmd_unlink_window_exec,
- cmd_target_free,
- cmd_target_print
+ 0,
+ NULL,
+ NULL,
+ cmd_unlink_window_exec
};
int
cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
+ struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct session *s, *s2;
struct session_group *sg;
u_int references;
- if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
+ if ((wl = cmd_find_window(ctx, args_get(args, 't'), &s)) == NULL)
return (-1);
w = wl->window;
@@ -59,7 +58,7 @@ cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
} else
references = 1;
- if (!cmd_check_flag(data->chflags, 'k') && w->references == references) {
+ if (!args_has(self->args, 'k') && w->references == references) {
ctx->error(ctx, "window is only linked to one session");
return (-1);
}
diff --git a/cmd-unlink-window.o b/cmd-unlink-window.o
new file mode 100644
index 0000000..a62f668
--- a/dev/null
+++ b/cmd-unlink-window.o
Binary files differ
diff --git a/cmd.c b/cmd.c
index 9856715..71be67c 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,4 +1,4 @@
-/* $Id: cmd.c,v 1.142 2010/07/17 14:38:13 tcunha Exp $ */
+/* $Id: cmd.c,v 1.148 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -39,7 +39,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_clock_mode_entry,
&cmd_command_prompt_entry,
&cmd_confirm_before_entry,
- &cmd_copy_buffer_entry,
&cmd_copy_mode_entry,
&cmd_delete_buffer_entry,
&cmd_detach_client_entry,
@@ -53,6 +52,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_kill_server_entry,
&cmd_kill_session_entry,
&cmd_kill_window_entry,
+ &cmd_last_pane_entry,
&cmd_last_window_entry,
&cmd_link_window_entry,
&cmd_list_buffers_entry,
@@ -110,7 +110,8 @@ const struct cmd_entry *cmd_table[] = {
NULL
};
-struct session *cmd_choose_session(struct sessions *);
+struct session *cmd_choose_session_list(struct sessionslist *);
+struct session *cmd_choose_session(void);
struct client *cmd_choose_client(struct clients *);
struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(const char *, int *);
@@ -164,6 +165,22 @@ cmd_unpack_argv(char *buf, size_t len, int argc, char ***argv)
return (0);
}
+char **
+cmd_copy_argv(int argc, char *const *argv)
+{
+ char **new_argv;
+ int i;
+
+ if (argc == 0)
+ return (NULL);
+ new_argv = xcalloc(argc, sizeof *new_argv);
+ for (i = 0; i < argc; i++) {
+ if (argv[i] != NULL)
+ new_argv[i] = xstrdup(argv[i]);
+ }
+ return (new_argv);
+}
+
void
cmd_free_argv(int argc, char **argv)
{
@@ -183,8 +200,9 @@ cmd_parse(int argc, char **argv, char **cause)
{
const struct cmd_entry **entryp, *entry;
struct cmd *cmd;
+ struct args *args;
char s[BUFSIZ];
- int opt, ambiguous = 0;
+ int ambiguous = 0;
*cause = NULL;
if (argc == 0) {
@@ -218,30 +236,19 @@ cmd_parse(int argc, char **argv, char **cause)
return (NULL);
}
- optreset = 1;
- optind = 1;
- if (entry->parse == NULL) {
- while ((opt = getopt(argc, argv, "")) != -1) {
- switch (opt) {
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 0)
- goto usage;
- }
+ args = args_parse(entry->args_template, argc, argv);
+ if (args == NULL)
+ goto usage;
+ if (entry->args_lower != -1 && args->argc < entry->args_lower)
+ goto usage;
+ if (entry->args_upper != -1 && args->argc > entry->args_upper)
+ goto usage;
+ if (entry->check != NULL && entry->check(args) != 0)
+ goto usage;
cmd = xmalloc(sizeof *cmd);
cmd->entry = entry;
- cmd->data = NULL;
- if (entry->parse != NULL) {
- if (entry->parse(cmd, argc, argv, cause) != 0) {
- xfree(cmd);
- return (NULL);
- }
- }
+ cmd->args = args;
return (cmd);
ambiguous:
@@ -259,6 +266,8 @@ ambiguous:
return (NULL);
usage:
+ if (args != NULL)
+ args_free(args);
xasprintf(cause, "usage: %s %s", entry->name, entry->usage);
return (NULL);
}
@@ -272,17 +281,27 @@ cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
void
cmd_free(struct cmd *cmd)
{
- if (cmd->data != NULL && cmd->entry->free != NULL)
- cmd->entry->free(cmd);
+ if (cmd->args != NULL)
+ args_free(cmd->args);
xfree(cmd);
}
size_t
cmd_print(struct cmd *cmd, char *buf, size_t len)
{
- if (cmd->entry->print == NULL)
- return (xsnprintf(buf, len, "%s", cmd->entry->name));
- return (cmd->entry->print(cmd, buf, len));
+ size_t off, used;
+
+ off = xsnprintf(buf, len, "%s ", cmd->entry->name);
+ if (off < len) {
+ used = args_print(cmd->args, buf + off, len - off);
+ if (used == 0)
+ buf[off - 1] = '\0';
+ else {
+ off += used;
+ buf[off] = '\0';
+ }
+ }
+ return (off);
}
/*
@@ -298,10 +317,9 @@ cmd_current_session(struct cmd_ctx *ctx)
struct msg_command_data *data = ctx->msgdata;
struct client *c = ctx->cmdclient;
struct session *s;
- struct sessions ss;
+ struct sessionslist ss;
struct winlink *wl;
struct window_pane *wp;
- u_int i;
int found;
if (ctx->curclient != NULL && ctx->curclient->session != NULL)
@@ -314,9 +332,7 @@ cmd_current_session(struct cmd_ctx *ctx)
*/
if (c != NULL && c->tty.path != NULL) {
ARRAY_INIT(&ss);
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
- continue;
+ RB_FOREACH(s, sessions, &sessions) {
found = 0;
RB_FOREACH(wl, winlinks, &s->windows) {
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
@@ -332,29 +348,43 @@ cmd_current_session(struct cmd_ctx *ctx)
ARRAY_ADD(&ss, s);
}
- s = cmd_choose_session(&ss);
+ s = cmd_choose_session_list(&ss);
ARRAY_FREE(&ss);
if (s != NULL)
return (s);
}
/* Use the session from the TMUX environment variable. */
- if (data != NULL && data->pid != -1) {
- if (data->pid != getpid())
- return (NULL);
- if (data->idx > ARRAY_LENGTH(&sessions))
- return (NULL);
- if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL)
- return (NULL);
- return (s);
+ if (data != NULL && data->pid == getpid()) {
+ s = session_find_by_index(data->idx);
+ if (s != NULL)
+ return (s);
}
- return (cmd_choose_session(&sessions));
+ return (cmd_choose_session());
+}
+
+/* Find the most recently used session. */
+struct session *
+cmd_choose_session(void)
+{
+ struct session *s, *sbest;
+ struct timeval *tv = NULL;
+
+ sbest = NULL;
+ RB_FOREACH(s, sessions, &sessions) {
+ if (tv == NULL || timercmp(&s->activity_time, tv, >)) {
+ sbest = s;
+ tv = &s->activity_time;
+ }
+ }
+
+ return (sbest);
}
/* Find the most recently used session from a list. */
struct session *
-cmd_choose_session(struct sessions *ss)
+cmd_choose_session_list(struct sessionslist *ss)
{
struct session *s, *sbest;
struct timeval *tv = NULL;
@@ -502,7 +532,6 @@ struct session *
cmd_lookup_session(const char *name, int *ambiguous)
{
struct session *s, *sfound;
- u_int i;
*ambiguous = 0;
@@ -511,21 +540,15 @@ cmd_lookup_session(const char *name, int *ambiguous)
* be unique so an exact match can't be ambigious and can just be
* returned.
*/
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
- continue;
- if (strcmp(name, s->name) == 0)
- return (s);
- }
+ if ((s = session_find(name)) != NULL)
+ return (s);
/*
* 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;
+ RB_FOREACH(s, sessions, &sessions) {
if (strncmp(name, s->name, strlen(name)) == 0 ||
fnmatch(name, s->name, 0) == 0) {
if (sfound != NULL) {
diff --git a/cmd.o b/cmd.o
new file mode 100644
index 0000000..2a1ffd8
--- a/dev/null
+++ b/cmd.o
Binary files differ
diff --git a/colour.c b/colour.c
index db5e4f4..b10a612 100644
--- a/colour.c
+++ b/colour.c
@@ -1,4 +1,4 @@
-/* $Id: colour.c,v 1.7 2009/09/11 14:13:52 tcunha Exp $ */
+/* $Id: colour.c,v 1.8 2011/01/21 23:42:14 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -18,6 +18,8 @@
#include <sys/types.h>
+#include <ctype.h>
+#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -28,6 +30,101 @@
* of the 256 colour palette.
*/
+/* An RGB colour. */
+struct colour_rgb {
+ u_char r;
+ u_char g;
+ u_char b;
+};
+
+/* 256 colour RGB table, generated on first use. */
+struct colour_rgb *colour_rgb_256;
+
+void colour_rgb_generate256(void);
+double colour_rgb_distance(struct colour_rgb *, struct colour_rgb *);
+int colour_rgb_find(struct colour_rgb *);
+
+/* Generate 256 colour RGB table. */
+void
+colour_rgb_generate256(void)
+{
+ struct colour_rgb *rgb;
+ u_int i, r, g, b;
+
+ /*
+ * Allocate the table. The first 16 colours are often changed by users
+ * and terminals so don't include them.
+ */
+ colour_rgb_256 = xcalloc(240, sizeof *colour_rgb_256);
+
+ /* Add the colours first. */
+ r = g = b = 0;
+ for (i = 240; i > 24; i--) {
+ rgb = &colour_rgb_256[240 - i];
+
+ if (r != 0)
+ rgb->r = (r * 40) + 55;
+ if (g != 0)
+ rgb->g = (g * 40) + 55;
+ if (b != 0)
+ rgb->b = (b * 40) + 55;
+
+ b++;
+ if (b > 5) {
+ b = 0;
+ g++;
+ }
+ if (g > 5) {
+ g = 0;
+ r++;
+ }
+ }
+
+ /* Then add the greys. */
+ for (i = 24; i > 0; i--) {
+ rgb = &colour_rgb_256[240 - i];
+
+ rgb->r = 8 + (24 - i) * 10;
+ rgb->g = 8 + (24 - i) * 10;
+ rgb->b = 8 + (24 - i) * 10;
+ }
+}
+
+/* Get colour RGB distance. */
+double
+colour_rgb_distance(struct colour_rgb *rgb1, struct colour_rgb *rgb2)
+{
+ int r, g, b;
+
+ r = rgb1->r - rgb2->r;
+ g = rgb1->g - rgb2->g;
+ b = rgb1->b - rgb2->b;
+ return (sqrt(r * r + g * g + b * b));
+}
+
+/* Work out the nearest colour from the 256 colour set. */
+int
+colour_rgb_find(struct colour_rgb *rgb)
+{
+ double distance, lowest;
+ u_int colour, i;
+
+ if (colour_rgb_256 == NULL)
+ colour_rgb_generate256();
+
+ colour = 16;
+ lowest = INFINITY;
+ for (i = 0; i < 240; i++) {
+ distance = colour_rgb_distance(&colour_rgb_256[i], rgb);
+ if (distance < lowest) {
+ lowest = distance;
+ colour = 16 + i;
+ }
+ }
+ return (colour);
+}
+
+/* Set grid cell foreground colour. */
void
colour_set_fg(struct grid_cell *gc, int c)
{
@@ -36,6 +133,7 @@ colour_set_fg(struct grid_cell *gc, int c)
gc->fg = c;
}
+/* Set grid cell background colour. */
void
colour_set_bg(struct grid_cell *gc, int c)
{
@@ -44,6 +142,7 @@ colour_set_bg(struct grid_cell *gc, int c)
gc->bg = c;
}
+/* Convert colour to a string. */
const char *
colour_tostring(int c)
{
@@ -77,11 +176,25 @@ colour_tostring(int c)
return (NULL);
}
+/* Convert colour from string. */
int
colour_fromstring(const char *s)
{
- const char *errstr;
- int n;
+ const char *errstr;
+ const char *cp;
+ struct colour_rgb rgb;
+ int n;
+
+ if (*s == '#' && strlen(s) == 7) {
+ for (cp = s + 1; isxdigit((u_char) *cp); cp++)
+ ;
+ if (*cp != '\0')
+ return (-1);
+ n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b);
+ if (n != 3)
+ return (-1);
+ return (colour_rgb_find(&rgb) | 0x100);
+ }
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
n = strtonum(s + (sizeof "colour") - 1, 0, 255, &errstr);
@@ -111,6 +224,7 @@ colour_fromstring(const char *s)
return (-1);
}
+/* Convert 256 colour palette to 16. */
u_char
colour_256to16(u_char c)
{
@@ -136,6 +250,7 @@ colour_256to16(u_char c)
return (table[c]);
}
+/* Convert 256 colour palette to 88. */
u_char
colour_256to88(u_char c)
{
diff --git a/colour.o b/colour.o
new file mode 100644
index 0000000..64264a9
--- a/dev/null
+++ b/colour.o
Binary files differ
diff --git a/compat.h b/compat.h
index 6db22fa..19ab248 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,4 @@
-/* $Id: compat.h,v 1.26 2010/09/07 19:32:58 nicm Exp $ */
+/* $Id: compat.h,v 1.32 2010/12/31 22:12:33 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -16,7 +16,21 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef HAVE_U_INT
+#ifndef COMPAT_H
+#define COMPAT_H
+
+#ifndef __GNUC__
+#define __attribute__(a)
+#endif
+
+#ifndef __dead
+#define __dead __attribute__ ((__noreturn__))
+#endif
+#ifndef __packed
+#define __packed __attribute__ ((__packed__))
+#endif
+
+#ifndef HAVE_BSD_TYPES
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
@@ -49,14 +63,6 @@ typedef uint64_t u_int64_t;
#include "compat/bitstring.h"
#endif
-#ifdef HAVE_GETOPT
-#include <getopt.h>
-#endif
-
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif
-
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
@@ -79,10 +85,10 @@ typedef uint64_t u_int64_t;
#include "compat/vis.h"
#endif
-#ifndef HAVE_IMSG
-#include "compat/imsg.h"
-#else
+#ifdef HAVE_IMSG
#include <imsg.h>
+#else
+#include "compat/imsg.h"
#endif
#ifdef HAVE_STDINT_H
@@ -91,8 +97,7 @@ typedef uint64_t u_int64_t;
#include <inttypes.h>
#endif
-#ifdef HAVE_BROKEN_CMSG_FIRSTHDR
-/* CMSG_FIRSTHDR broken on OS X. */
+#ifdef BROKEN_CMSG_FIRSTHDR
#undef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(mhdr) \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
@@ -100,9 +105,8 @@ typedef uint64_t u_int64_t;
(struct cmsghdr *)NULL)
#endif
-/* CMSG_ALIGN, CMSG_SPACE, CMSG_LEN missing from Solaris 9. */
#ifndef CMSG_ALIGN
-#ifdef __sun
+#ifdef _CMSG_DATA_ALIGN
#define CMSG_ALIGN _CMSG_DATA_ALIGN
#else
#define CMSG_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1))
@@ -129,13 +133,6 @@ typedef uint64_t u_int64_t;
#define SUN_LEN(sun) (sizeof (sun)->sun_path)
#endif
-#ifndef __dead
-#define __dead __attribute__ ((__noreturn__))
-#endif
-#ifndef __packed
-#define __packed __attribute__ ((__packed__))
-#endif
-
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
@@ -160,9 +157,15 @@ typedef uint64_t u_int64_t;
#endif
#ifndef HAVE_BZERO
+#undef bzero
#define bzero(buf, len) memset(buf, 0, len);
#endif
+#ifndef HAVE_CLOSEFROM
+/* closefrom.c */
+void closefrom(int);
+#endif
+
#ifndef HAVE_STRCASESTR
/* strcasestr.c */
char *strcasestr(const char *, const char *);
@@ -195,6 +198,7 @@ int daemon(int, int);
#ifndef HAVE_FORKPTY
/* forkpty.c */
+#include <sys/ioctl.h>
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
@@ -215,7 +219,9 @@ int setenv(const char *, const char *, int);
int unsetenv(const char *);
#endif
-#ifndef HAVE_GETOPT
+#ifdef HAVE_GETOPT
+#include <getopt.h>
+#else
/* getopt.c */
extern int BSDopterr;
extern int BSDoptind;
@@ -230,3 +236,5 @@ int BSDgetopt(int, char *const *, const char *);
#define optreset BSDoptreset
#define optarg BSDoptarg
#endif
+
+#endif /* COMPAT_H */
diff --git a/compat/asprintf.c b/compat/asprintf.c
index ef08f49..dac845c 100644
--- a/compat/asprintf.c
+++ b/compat/asprintf.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: asprintf.c,v 1.6 2011/01/21 20:03:18 nicm Exp $ */
/*
* Copyright (c) 2006 Nicholas Marriott <[email protected]>
@@ -18,7 +18,11 @@
#include <stdarg.h>
#include <stdio.h>
+#ifdef HAVE_STDINT_H
#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
#include <string.h>
#include "tmux.h"
@@ -36,28 +40,6 @@ asprintf(char **ret, const char *format, ...)
return (n);
}
-#ifndef BROKEN_VSNPRINTF
-int
-vasprintf(char **ret, const char *format, va_list ap)
-{
- int n;
-
- if ((n = vsnprintf(NULL, 0, format, ap)) < 0)
- goto error;
-
- *ret = xmalloc(n + 1);
- if ((n = vsnprintf(*ret, n + 1, format, ap)) < 0) {
- xfree(*ret);
- goto error;
- }
-
- return (n);
-
-error:
- *ret = NULL;
- return (-1);
-}
-#else
int
vasprintf(char **ret, const char *fmt, va_list ap)
{
@@ -86,4 +68,3 @@ vasprintf(char **ret, const char *fmt, va_list ap)
len *= 2;
}
}
-#endif
diff --git a/compat/closefrom.c b/compat/closefrom.c
new file mode 100644
index 0000000..981958e
--- a/dev/null
+++ b/compat/closefrom.c
@@ -0,0 +1,111 @@
+/* $Id: closefrom.c,v 1.1 2010/10/27 20:21:01 nicm Exp $ */
+
+/*
+ * Copyright (c) 2004-2005 Todd C. Miller <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "tmux.h"
+
+#ifndef HAVE_CLOSEFROM
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <stdio.h>
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#include <limits.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#ifndef OPEN_MAX
+# define OPEN_MAX 256
+#endif
+
+#if 0
+__unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $";
+#endif /* lint */
+
+/*
+ * Close all file descriptors greater than or equal to lowfd.
+ */
+#ifdef HAVE_FCNTL_CLOSEM
+void
+closefrom(int lowfd)
+{
+ (void) fcntl(lowfd, F_CLOSEM, 0);
+}
+#else
+void
+closefrom(int lowfd)
+{
+ long fd, maxfd;
+#if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID)
+ char fdpath[PATH_MAX], *endp;
+ struct dirent *dent;
+ DIR *dirp;
+ int len;
+
+ /* Check for a /proc/$$/fd directory. */
+ len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid());
+ if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) {
+ while ((dent = readdir(dirp)) != NULL) {
+ fd = strtol(dent->d_name, &endp, 10);
+ if (dent->d_name != endp && *endp == '\0' &&
+ fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
+ (void) close((int) fd);
+ }
+ (void) closedir(dirp);
+ } else
+#endif
+ {
+ /*
+ * Fall back on sysconf() or getdtablesize(). We avoid checking
+ * resource limits since it is possible to open a file descriptor
+ * and then drop the rlimit such that it is below the open fd.
+ */
+#ifdef HAVE_SYSCONF
+ maxfd = sysconf(_SC_OPEN_MAX);
+#else
+ maxfd = getdtablesize();
+#endif /* HAVE_SYSCONF */
+ if (maxfd < 0)
+ maxfd = OPEN_MAX;
+
+ for (fd = lowfd; fd < maxfd; fd++)
+ (void) close((int) fd);
+ }
+}
+#endif /* !HAVE_FCNTL_CLOSEM */
+#endif /* HAVE_CLOSEFROM */
diff --git a/compat/closefrom.o b/compat/closefrom.o
new file mode 100644
index 0000000..80f75ad
--- a/dev/null
+++ b/compat/closefrom.o
Binary files differ
diff --git a/compat/daemon.c b/compat/daemon.c
index 56dc46a..3e87874 100644
--- a/compat/daemon.c
+++ b/compat/daemon.c
@@ -32,10 +32,6 @@
#include <unistd.h>
#include <stdlib.h>
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
#include "tmux.h"
int
diff --git a/compat/fgetln.o b/compat/fgetln.o
new file mode 100644
index 0000000..b9b8a5f
--- a/dev/null
+++ b/compat/fgetln.o
Binary files differ
diff --git a/compat/forkpty-aix.c b/compat/forkpty-aix.c
index 9bca142..cff4e69 100644
--- a/compat/forkpty-aix.c
+++ b/compat/forkpty-aix.c
@@ -1,4 +1,4 @@
-/* $Id: forkpty-aix.c,v 1.4 2009/09/20 18:31:16 nicm Exp $ */
+/* $Id: forkpty-aix.c,v 1.5 2011/01/10 22:45:09 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -52,10 +52,10 @@ forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws)
ioctl(fd, TIOCNOTTY, NULL);
close(fd);
}
-
+
if (setsid() < 0)
fatal("setsid");
-
+
fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
if (fd >= 0)
fatalx("open succeeded (failed to disconnect)");
diff --git a/compat/forkpty-hpux.c b/compat/forkpty-hpux.c
new file mode 100644
index 0000000..600a491
--- a/dev/null
+++ b/compat/forkpty-hpux.c
@@ -0,0 +1,89 @@
+/* $Id: forkpty-hpux.c,v 1.1 2011/01/21 20:35:20 nicm Exp $ */
+
+/*
+ * Copyright (c) 2008 Nicholas Marriott <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stropts.h>
+#include <unistd.h>
+
+#include "tmux.h"
+
+pid_t
+forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
+{
+ int slave;
+ char *path;
+ pid_t pid;
+
+ if ((*master = open("/dev/ptmx", O_RDWR|O_NOCTTY)) == -1)
+ return (-1);
+ if (grantpt(*master) != 0)
+ goto out;
+ if (unlockpt(*master) != 0)
+ goto out;
+
+ if ((path = ptsname(*master)) == NULL)
+ goto out;
+ if (name != NULL)
+ strlcpy(name, path, TTY_NAME_MAX);
+ if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
+ goto out;
+
+ switch (pid = fork()) {
+ case -1:
+ goto out;
+ case 0:
+ close(*master);
+
+ setsid();
+#ifdef TIOCSCTTY
+ if (ioctl(slave, TIOCSCTTY, NULL) == -1)
+ fatal("ioctl failed");
+#endif
+
+ if (ioctl(slave, I_PUSH, "ptem") == -1)
+ fatal("ioctl failed");
+ if (ioctl(slave, I_PUSH, "ldterm") == -1)
+ fatal("ioctl failed");
+
+ if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
+ fatal("tcsetattr failed");
+ if (ioctl(slave, TIOCSWINSZ, ws) == -1)
+ fatal("ioctl failed");
+
+ dup2(slave, 0);
+ dup2(slave, 1);
+ dup2(slave, 2);
+ if (slave > 2)
+ close(slave);
+ return (0);
+ }
+
+ close(slave);
+ return (pid);
+
+out:
+ if (*master != -1)
+ close(*master);
+ if (slave != -1)
+ close(slave);
+ return (-1);
+}
diff --git a/compat/forkpty-sunos.c b/compat/forkpty-sunos.c
index 0d5bc91..474f82e 100644
--- a/compat/forkpty-sunos.c
+++ b/compat/forkpty-sunos.c
@@ -1,4 +1,4 @@
-/* $Id: forkpty-sunos.c,v 1.9 2009/10/15 07:11:25 nicm Exp $ */
+/* $Id: forkpty-sunos.c,v 1.10 2011/01/10 22:45:10 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -73,7 +73,7 @@ forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
dup2(slave, 1);
dup2(slave, 2);
if (slave > 2)
- close(slave);
+ close(slave);
return (0);
}
diff --git a/compat/getopt.o b/compat/getopt.o
new file mode 100644
index 0000000..e0b7bde
--- a/dev/null
+++ b/compat/getopt.o
Binary files differ
diff --git a/compat/imsg-buffer.o b/compat/imsg-buffer.o
new file mode 100644
index 0000000..e536817
--- a/dev/null
+++ b/compat/imsg-buffer.o
Binary files differ
diff --git a/compat/imsg.c b/compat/imsg.c
index 987d8fd..e826043 100644
--- a/compat/imsg.c
+++ b/compat/imsg.c
@@ -1,4 +1,4 @@
-/* $Id: imsg.c,v 1.5 2010/06/06 00:08:28 tcunha Exp $ */
+/* $Id: imsg.c,v 1.7 2010/11/13 16:29:05 nicm Exp $ */
/* $OpenBSD: imsg.c,v 1.3 2010/05/26 13:56:07 nicm Exp $ */
/*
@@ -111,7 +111,7 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
return (0);
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
- if ((imsg->data = malloc(datalen)) == NULL)
+ if ((imsg->data = malloc(datalen)) == NULL && datalen != 0)
return (-1);
if (imsg->hdr.flags & IMSGF_HASFD)
diff --git a/compat/imsg.o b/compat/imsg.o
new file mode 100644
index 0000000..057373d
--- a/dev/null
+++ b/compat/imsg.o
Binary files differ
diff --git a/compat/strlcat.o b/compat/strlcat.o
new file mode 100644
index 0000000..8f97211
--- a/dev/null
+++ b/compat/strlcat.o
Binary files differ
diff --git a/compat/strlcpy.o b/compat/strlcpy.o
new file mode 100644
index 0000000..54275ee
--- a/dev/null
+++ b/compat/strlcpy.o
Binary files differ
diff --git a/compat/strsep.c b/compat/strsep.c
index 3c59219..d962a6b 100644
--- a/compat/strsep.c
+++ b/compat/strsep.c
@@ -1,4 +1,4 @@
-/* $Id: strsep.c,v 1.1 2009/08/16 16:15:53 nicm Exp $ */
+/* $Id: strsep.c,v 1.2 2011/01/10 22:45:10 nicm Exp $ */
/* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
/*-
@@ -35,7 +35,7 @@
/*
* Get next token from string *stringp, where tokens are possibly-empty
- * strings separated by characters from delim.
+ * strings separated by characters from delim.
*
* Writes NULs into the string at *stringp to end tokens.
* delim need not remain constant from call to call.
diff --git a/compat/strtonum.o b/compat/strtonum.o
new file mode 100644
index 0000000..6a047a4
--- a/dev/null
+++ b/compat/strtonum.o
Binary files differ
diff --git a/compat/unvis.c b/compat/unvis.c
index 7071764..e1f09ec 100644
--- a/compat/unvis.c
+++ b/compat/unvis.c
@@ -57,7 +57,7 @@ unvis(char *cp, char c, int *astate, int flag)
if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
*astate = S_GROUND;
return (UNVIS_VALID);
- }
+ }
return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
}
@@ -68,7 +68,7 @@ unvis(char *cp, char c, int *astate, int flag)
if (c == '\\') {
*astate = S_START;
return (0);
- }
+ }
*cp = c;
return (UNVIS_VALID);
@@ -141,7 +141,7 @@ unvis(char *cp, char c, int *astate, int flag)
}
*astate = S_GROUND;
return (UNVIS_SYNBAD);
-
+
case S_META:
if (c == '-')
*astate = S_META1;
@@ -152,12 +152,12 @@ unvis(char *cp, char c, int *astate, int flag)
return (UNVIS_SYNBAD);
}
return (0);
-
+
case S_META1:
*astate = S_GROUND;
*cp |= c;
return (UNVIS_VALID);
-
+
case S_CTRL:
if (c == '?')
*cp |= 0177;
@@ -168,15 +168,15 @@ unvis(char *cp, char c, int *astate, int flag)
case S_OCTAL2: /* second possible octal digit */
if (isoctal(c)) {
- /*
- * yes - and maybe a third
+ /*
+ * yes - and maybe a third
*/
*cp = (*cp << 3) + (c - '0');
- *astate = S_OCTAL3;
+ *astate = S_OCTAL3;
return (0);
- }
- /*
- * no - done with current sequence, push back passed char
+ }
+ /*
+ * no - done with current sequence, push back passed char
*/
*astate = S_GROUND;
return (UNVIS_VALIDPUSH);
@@ -191,10 +191,10 @@ unvis(char *cp, char c, int *astate, int flag)
* we were done, push back passed char
*/
return (UNVIS_VALIDPUSH);
-
- default:
- /*
- * decoder in unknown state - (probably uninitialized)
+
+ default:
+ /*
+ * decoder in unknown state - (probably uninitialized)
*/
*astate = S_GROUND;
return (UNVIS_SYNBAD);
@@ -202,7 +202,7 @@ unvis(char *cp, char c, int *astate, int flag)
}
/*
- * strunvis - decode src into dst
+ * strunvis - decode src into dst
*
* Number of chars decoded into dst is returned, -1 on error.
* Dst is null terminated.
diff --git a/compat/unvis.o b/compat/unvis.o
new file mode 100644
index 0000000..328a857
--- a/dev/null
+++ b/compat/unvis.o
Binary files differ
diff --git a/compat/vis.c b/compat/vis.c
index 5aca58c..97eb527 100644
--- a/compat/vis.c
+++ b/compat/vis.c
@@ -136,10 +136,10 @@ done:
/*
* strvis, strnvis, strvisx - visually encode characters from src into dst
- *
+ *
* Dst must be 4 times the size of src to account for possible
* expansion. The length of dst, not including the trailing NULL,
- * is returned.
+ * is returned.
*
* Strnvis will write no more than siz-1 bytes (and will NULL terminate).
* The number of bytes needed to fully encode the string is returned.
diff --git a/compat/vis.o b/compat/vis.o
new file mode 100644
index 0000000..1742a60
--- a/dev/null
+++ b/compat/vis.o
Binary files differ
diff --git a/configure b/configure
deleted file mode 100755
index 7a9af9f..0000000
--- a/configure
+++ b/dev/null
@@ -1,297 +0,0 @@
-#!/bin/sh
-# $Id: configure,v 1.54 2010/09/07 19:32:58 nicm Exp $
-#
-# Copyright (c) 2009 Nicholas Marriott <[email protected]>
-#
-# 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.
-#
-
-TMUX_PLATFORM=${TMUX_PLATFORM:-`uname -s`}
-
-CONFIG_H=config.h
-rm -f $CONFIG_H
-echo "/* $TMUX_PLATFORM */" >$CONFIG_H
-
-CONFIG_MK=config.mk
-rm -f $CONFIG_MK
-echo "# $TMUX_PLATFORM" >$CONFIG_MK
-
-cat <<EOF >>$CONFIG_H
-#undef HAVE_ASPRINTF
-#undef HAVE_BROKEN_CMSG_FIRSTHDR
-#undef HAVE_BROKEN_CURSES_H
-#undef HAVE_BROKEN_KQUEUE
-#undef HAVE_BROKEN_POLL
-#undef HAVE_BZERO
-#undef HAVE_CRYPT_H
-#undef HAVE_DAEMON
-#undef HAVE_FGETLN
-#undef HAVE_FORKPTY
-#undef HAVE_GETOPT
-#undef HAVE_IMSG
-#undef HAVE_LIBUTIL_H
-#undef HAVE_PATHS_H
-#undef HAVE_PROGNAME
-#undef HAVE_PTY_H
-#undef HAVE_QUEUE_H
-#undef HAVE_SETPROCTITLE
-#undef HAVE_STDINT_H
-#undef HAVE_STRCASESTR
-#undef HAVE_STRLCAT
-#undef HAVE_STRLCPY
-#undef HAVE_STRSEP
-#undef HAVE_STRTONUM
-#undef HAVE_TREE_H
-#undef HAVE_UTIL_H
-#undef HAVE_U_INT
-#undef HAVE_VIS
-EOF
-
-case $TMUX_PLATFORM in
-# ------------------------------------------------------------------------------
- OpenBSD)
- cat <<EOF >>$CONFIG_H
-#define HAVE_ASPRINTF
-#define HAVE_BITSTRING_H
-#define HAVE_BZERO
-#define HAVE_DAEMON
-#define HAVE_FGETLN
-#define HAVE_FORKPTY
-#define HAVE_GETOPT
-#define HAVE_IMSG
-#define HAVE_PATHS_H
-#define HAVE_PROGNAME
-#define HAVE_QUEUE_H
-#define HAVE_SETENV
-#define HAVE_SETPROCTITLE
-#define HAVE_STDINT_H
-#define HAVE_STRCASESTR
-#define HAVE_STRLCAT
-#define HAVE_STRLCPY
-#define HAVE_STRSEP
-#define HAVE_STRTONUM
-#define HAVE_TREE_H
-#define HAVE_UTIL_H
-#define HAVE_U_INT
-#define HAVE_VIS
-EOF
- cat <<EOF >>$CONFIG_MK
-LIBS+= -lcurses -lutil -levent
-SRCS+= osdep-openbsd.c
-EOF
- ;;
-# ------------------------------------------------------------------------------
- Linux)
- cat <<EOF >>$CONFIG_H
-#define HAVE_ASPRINTF
-#define HAVE_BZERO
-#define HAVE_DAEMON
-#define HAVE_FORKPTY
-#define HAVE_PATHS_H
-#define HAVE_PROGNAME
-#define HAVE_PTY_H
-#define HAVE_SETENV
-#define HAVE_STDINT_H
-#define HAVE_STRCASESTR
-#define HAVE_STRSEP
-#define HAVE_U_INT
-EOF
- cat <<EOF >>$CONFIG_MK
-CFLAGS+= -std=c99 -D_GNU_SOURCE -D_POSIX_SOURCE
-LIBS+= -lncurses -lcrypt -lutil -levent -lrt
-SRCS+= osdep-linux.c \
- compat/fgetln.c \
- compat/strlcat.c \
- compat/strlcpy.c \
- compat/strtonum.c \
- compat/getopt.c \
- compat/vis.c \
- compat/unvis.c \
- compat/imsg-buffer.c \
- compat/imsg.c
-EOF
- ;;
-# ------------------------------------------------------------------------------
- AIX)
- cat <<EOF >>$CONFIG_H
-#define HAVE_BZERO
-#define HAVE_DAEMON
-#define HAVE_SETENV
-#define HAVE_STDINT_H
-EOF
- cat <<EOF >>$CONFIG_MK
-LIBS+= -lcurses -levent
-SRCS+= osdep-unknown.c \
- compat/asprintf.c \
- compat/daemon.c \
- compat/forkpty-aix.c \
- compat/strcasestr.c \
- compat/strlcat.c \
- compat/strlcpy.c \
- compat/strsep.c \
- compat/strtonum.c \
- compat/fgetln.c \
- compat/getopt.c \
- compat/vis.c \
- compat/unvis.c \
- compat/imsg-buffer.c \
- compat/imsg.c
-EOF
- ;;
-# ------------------------------------------------------------------------------
- SunOS)
- cat <<EOF >>$CONFIG_H
-#define HAVE_CRYPT_H
-#define HAVE_STRLCAT
-#define HAVE_STRLCPY
-EOF
- cat <<EOF >>$CONFIG_MK
-CFLAGS+= -D_XPG4_2 -D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS
-LIBS+= -lcurses -lsocket -lnsl -levent
-SRCS+= osdep-sunos.c \
- compat/asprintf.c \
- compat/daemon.c \
- compat/fgetln.c \
- compat/forkpty-sunos.c \
- compat/getopt.c \
- compat/setenv.c \
- compat/strcasestr.c \
- compat/strsep.c \
- compat/strtonum.c \
- compat/vis.c \
- compat/unvis.c \
- compat/imsg-buffer.c \
- compat/imsg.c
-EOF
- ;;
-# ------------------------------------------------------------------------------
- Darwin)
- cat <<EOF >>$CONFIG_H
-#define HAVE_ASPRINTF
-#define HAVE_BROKEN_CMSG_FIRSTHDR
-#define HAVE_BROKEN_KQUEUE
-#define HAVE_BROKEN_POLL
-#define HAVE_BZERO
-#define HAVE_DAEMON
-#define HAVE_FGETLN
-#define HAVE_FORKPTY
-#define HAVE_GETOPT
-#define HAVE_PATHS_H
-#define HAVE_PROGNAME
-#define HAVE_STDINT_H
-#define HAVE_SETENV
-#define HAVE_STRCASESTR
-#define HAVE_STRLCAT
-#define HAVE_STRLCPY
-#define HAVE_STRSEP
-#define HAVE_UTIL_H
-#define HAVE_U_INT
-EOF
- cat <<EOF >>$CONFIG_MK
-CPPFLAGS+= -I/opt/local/include
-LDFLAGS+= -L/opt/local/lib
-LIBS+= -lcurses -levent
-SRCS+= osdep-darwin.c \
- compat/strtonum.c \
- compat/vis.c \
- compat/unvis.c \
- compat/imsg-buffer.c \
- compat/imsg.c
-EOF
- ;;
-# ------------------------------------------------------------------------------
- FreeBSD|DragonFly)
- cat <<EOF >>$CONFIG_H
-#define HAVE_ASPRINTF
-#define HAVE_BROKEN_KQUEUE
-#define HAVE_BZERO
-#define HAVE_DAEMON
-#define HAVE_FGETLN
-#define HAVE_FORKPTY
-#define HAVE_GETOPT
-#define HAVE_LIBUTIL_H
-#define HAVE_PATHS_H
-#define HAVE_PROGNAME
-#define HAVE_SETENV
-#define HAVE_SETPROCTITLE
-#define HAVE_STDINT_H
-#define HAVE_STRCASESTR
-#define HAVE_STRLCAT
-#define HAVE_STRLCPY
-#define HAVE_STRTONUM
-#define HAVE_STRSEP
-#define HAVE_U_INT
-EOF
- cat <<EOF >>$CONFIG_MK
-LIBS+= -lcurses -lcrypt -lutil -levent
-SRCS+= osdep-freebsd.c \
- compat/vis.c \
- compat/unvis.c \
- compat/imsg-buffer.c \
- compat/imsg.c
-EOF
- ;;
-# ------------------------------------------------------------------------------
- NetBSD)
- cat <<EOF >>$CONFIG_H
-#define HAVE_ASPRINTF
-#define HAVE_BZERO
-#define HAVE_DAEMON
-#define HAVE_FGETLN
-#define HAVE_FORKPTY
-#define HAVE_GETOPT
-#define HAVE_PATHS_H
-#define HAVE_PROGNAME
-#define HAVE_SETPROCTITLE
-#define HAVE_SETENV
-#define HAVE_STDINT_H
-#define HAVE_STRCASESTR
-#define HAVE_STRLCAT
-#define HAVE_STRLCPY
-#define HAVE_STRSEP
-#define HAVE_UTIL_H
-#define HAVE_U_INT
-EOF
- # NetBSD-6 has its own terminfo implementation
- if test -f /lib/libterminfo.so; then
- cat <<EOF >>$CONFIG_MK
-LIBS+= -lterminfo
-EOF
- else
- cat <<EOF >>$CONFIG_MK
-CPPFLAGS+= -I/usr/pkg/include
-LDFLAGS+= -L/usr/pkg/lib
-LIBS+= -lncurses
-EOF
- cat <<EOF >>$CONFIG_H
-#define HAVE_BROKEN_CURSES_H
-EOF
- fi
- cat <<EOF >>$CONFIG_MK
-LIBS+= -lcrypt -lutil -levent
-SRCS+= osdep-netbsd.c \
- compat/strtonum.c \
- compat/vis.c \
- compat/unvis.c \
- compat/imsg-buffer.c \
- compat/imsg.c
-EOF
- ;;
-# ------------------------------------------------------------------------------
- *)
- echo Unable to configure for $TMUX_PLATFORM
- exit 1
-esac
-
-echo Configured for $TMUX_PLATFORM
-exit 0
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..001d4ca
--- a/dev/null
+++ b/configure.ac
@@ -0,0 +1,423 @@
+# $Id: configure.ac,v 1.14 2011/01/21 23:40:30 tcunha Exp $
+
+# Miscellaneous autofoo bullshit.
+AC_INIT(tmux, 1.5)
+
+AC_CONFIG_AUX_DIR(etc)
+AM_INIT_AUTOMAKE([foreign])
+
+AC_CANONICAL_HOST
+
+# Set up the compiler in two different ways and say yes we may want to install.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_INSTALL
+
+# Check for various headers. Alternatives included from compat.h.
+AC_CHECK_HEADERS(
+ [ \
+ bitstring.h \
+ curses.h \
+ dirent.h \
+ fcntl.h \
+ inttypes.h \
+ libutil.h \
+ ncurses.h \
+ ndir.h \
+ paths.h \
+ pty.h \
+ stdint.h \
+ sys/dir.h \
+ sys/ndir.h \
+ sys/tree.h \
+ term.h \
+ util.h \
+ ]
+)
+
+# Is this a debug build?
+found_debug=yes
+AC_ARG_ENABLE(
+ debug,
+ AC_HELP_STRING(--enable-debug, create a debug build),
+ found_debug=$enable_debug
+)
+AM_CONDITIONAL(IS_DEBUG, test "x$found_debug" = xyes)
+
+# Is this a static build?
+AC_ARG_ENABLE(
+ static,
+ AC_HELP_STRING(--enable-static, create a static build),
+ [found_static=$enable_static]
+)
+AM_CONDITIONAL(IS_STATIC, test "x" = xyes)
+
+# Is this gcc?
+AM_CONDITIONAL(IS_GCC, test "x$GCC" = xyes)
+AC_MSG_CHECKING(for gcc that whines about -I)
+AC_EGREP_CPP(
+ yes,
+ [
+ #if __GNUC__ > 3
+ yes
+ #endif
+ ],
+ found_gcc4=yes,
+ found_gcc4=no
+)
+AM_CONDITIONAL(IS_GCC4, test "x$found_gcc4" = xyes)
+AC_MSG_RESULT($found_gcc4)
+
+# Is this Sun CC?
+AC_EGREP_CPP(
+ yes,
+ [
+ #ifdef __SUNPRO_C
+ yes
+ #endif
+ ],
+ found_suncc=yes,
+ found_suncc=no
+)
+AM_CONDITIONAL(IS_SUNCC, test "x$found_suncc" = xyes)
+
+# Is this glibc?
+AC_MSG_CHECKING(for glibc)
+AC_EGREP_CPP(
+ yes,
+ [
+ #include <features.h>
+ #ifdef __GLIBC__
+ yes
+ #endif
+ ],
+ found_glibc=yes,
+ found_glibc=no
+)
+AM_CONDITIONAL(IS_GLIBC, test "x$found_glibc" = xyes)
+AC_MSG_RESULT($found_glibc)
+
+# Look for clock_gettime. Must come before event_init.
+AC_CHECK_LIB(rt, clock_gettime)
+
+# Look for libevent.
+AC_SEARCH_LIBS(event_init, event, found_libevent=yes, found_libevent=no)
+if test "x$found_libevent" = xno; then
+ AC_MSG_ERROR("libevent not found")
+fi
+
+# Look for curses.
+AC_SEARCH_LIBS(
+ setupterm,
+ [terminfo curses ncurses],
+ found_curses=yes,
+ found_curses=no
+)
+if test "x$found_curses" = xno; then
+ AC_MSG_ERROR("curses not found")
+fi
+
+# Look for networking libraries.
+AC_SEARCH_LIBS(inet_ntoa, nsl)
+AC_SEARCH_LIBS(socket, socket)
+AC_CHECK_LIB(xnet, socket)
+
+# Look for sqrt.
+AC_SEARCH_LIBS(sqrt, m)
+
+# Check for CMSG_DATA. Some platforms require _XOPEN_SOURCE_EXTENDED (for
+# example see xopen_networking(7) on HP-UX).
+XOPEN_DEFINES=
+AC_MSG_CHECKING(for CMSG_DATA)
+AC_EGREP_CPP(
+ yes,
+ [
+ #include <sys/socket.h>
+ #ifdef CMSG_DATA
+ yes
+ #endif
+ ],
+ found_cmsg_data=yes,
+ found_cmsg_data=no
+)
+AC_MSG_RESULT($found_cmsg_data)
+if test "x$found_cmsg_data" = xno; then
+ AC_MSG_CHECKING(if CMSG_DATA needs _XOPEN_SOURCE_EXTENDED)
+ AC_EGREP_CPP(
+ yes,
+ [
+ #define _XOPEN_SOURCE 1
+ #define _XOPEN_SOURCE_EXTENDED 1
+ #include <sys/socket.h>
+ #ifdef CMSG_DATA
+ yes
+ #endif
+ ],
+ found_cmsg_data=yes,
+ found_cmsg_data=no
+ )
+ AC_MSG_RESULT($found_cmsg_data)
+ if test "x$found_cmsg_data" = xyes; then
+ XOPEN_DEFINES="-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED"
+ else
+ AC_MSG_ERROR("CMSG_DATA not found")
+ fi
+fi
+AC_SUBST(XOPEN_DEFINES)
+
+# Look for imsg in libutil. compat/imsg.c is linked by Makefile.am if missing.
+AC_SEARCH_LIBS(imsg_init, util, found_imsg_init=yes, found_imsg_init=no)
+if test "x$found_imsg_init" = xyes; then
+ AC_DEFINE(HAVE_IMSG)
+fi
+AM_CONDITIONAL(NO_IMSG, [test "x$found_imsg_init" = xno])
+
+# Look for forkpty in libutil. compat/forkpty-*.c is linked if not found.
+AC_SEARCH_LIBS(forkpty, util, found_forkpty=yes, found_forkpty=no)
+if test "x$found_forkpty" = xyes; then
+ AC_DEFINE(HAVE_FORKPTY)
+fi
+AM_CONDITIONAL(NO_FORKPTY, [test "x$found_forkpty" = xno])
+
+# Look for closefrom, compat/closefrom.c used if missing.
+AC_CHECK_FUNC(closefrom, found_closefrom=yes, found_closefrom=no)
+if test "x$found_closefrom" = xyes; then
+ AC_DEFINE(HAVE_CLOSEFROM)
+fi
+AM_CONDITIONAL(NO_CLOSEFROM, [test "x$found_closefrom" = xno])
+
+# Look for daemon, compat/daemon.c used if missing.
+AC_CHECK_FUNC(daemon, found_daemon=yes, found_daemon=no)
+if test "x$found_daemon" = xyes; then
+ AC_DEFINE(HAVE_DAEMON)
+fi
+AM_CONDITIONAL(NO_DAEMON, [test "x$found_daemon" = xno])
+
+# Look for setenv, compat/setenv.c used if missing.
+AC_CHECK_FUNC(setenv, found_setenv=yes, found_setenv=no)
+if test "x$found_setenv" = xyes; then
+ AC_DEFINE(HAVE_SETENV)
+fi
+AM_CONDITIONAL(NO_SETENV, [test "x$found_setenv" = xno])
+
+# Look for strlcpy, compat/strlcpy.c used if missing.
+AC_CHECK_FUNC(strlcpy, found_strlcpy=yes, found_strlcpy=no)
+if test "x$found_strlcpy" = xyes; then
+ AC_DEFINE(HAVE_STRLCPY)
+fi
+AM_CONDITIONAL(NO_STRLCPY, [test "x$found_strlcpy" = xno])
+
+# Look for strlcat, compat/strlcat.c used if missing.
+AC_CHECK_FUNC(strlcat, found_strlcat=yes, found_strlcat=no)
+if test "x$found_strlcat" = xyes; then
+ AC_DEFINE(HAVE_STRLCAT)
+fi
+AM_CONDITIONAL(NO_STRLCAT, [test "x$found_strlcat" = xno])
+
+# Look for asprintf, compat/asprintf.c used if missing.
+AC_CHECK_FUNC(asprintf, found_asprintf=yes, found_asprintf=no)
+if test "x$found_asprintf" = xyes; then
+ AC_DEFINE(HAVE_ASPRINTF)
+fi
+AM_CONDITIONAL(NO_ASPRINTF, [test "x$found_asprintf" = xno])
+
+# Look for fgetln, compat/fgetln.c used if missing.
+AC_CHECK_FUNC(fgetln, found_fgetln=yes, found_fgetln=no)
+if test "x$found_fgetln" = xyes; then
+ AC_DEFINE(HAVE_FGETLN)
+fi
+AM_CONDITIONAL(NO_FGETLN, [test "x$found_fgetln" = xno])
+
+# Look for strcasestr, compat/strcasestr.c used if missing.
+AC_CHECK_FUNC(strcasestr, found_strcasestr=yes, found_strcasestr=no)
+if test "x$found_strcasestr" = xyes; then
+ AC_DEFINE(HAVE_STRCASESTR)
+fi
+AM_CONDITIONAL(NO_STRCASESTR, [test "x$found_strcasestr" = xno])
+
+# Look for strsep, compat/strsep.c used if missing.
+AC_CHECK_FUNC(strsep, found_strsep=yes, found_strsep=no)
+if test "x$found_strsep" = xyes; then
+ AC_DEFINE(HAVE_STRSEP)
+fi
+AM_CONDITIONAL(NO_STRSEP, [test "x$found_strsep" = xno])
+
+# Look for strtonum, compat/strtonum.c used if missing.
+AC_CHECK_FUNC(strtonum, found_strtonum=yes, found_strtonum=no)
+if test "x$found_strtonum" = xyes; then
+ AC_DEFINE(HAVE_STRTONUM)
+fi
+AM_CONDITIONAL(NO_STRTONUM, [test "x$found_strtonum" = xno])
+
+# Look for strnvis, compat/{vis,unvis}.c used if missing.
+AC_CHECK_FUNC(strnvis, found_strnvis=yes, found_strnvis=no)
+if test "x$found_strnvis" = xyes; then
+ AC_DEFINE(HAVE_VIS)
+fi
+AM_CONDITIONAL(NO_VIS, [test "x$found_strnvis" = xno])
+
+# Look for getopt. glibc's getopt does not enforce argument order and the ways
+# of making it do so are stupid, so just use our own instead.
+AC_CHECK_FUNC(getopt, found_getopt=yes, found_getopt=no)
+if test "x$found_getopt" != xno; then
+ AC_CHECK_DECLS(
+ [optarg, optind, optreset],
+ ,
+ found_getopt=no,
+ [
+ #include <unistd.h>
+ ]
+ )
+ if test "x$found_getopt" != xno; then
+ AC_MSG_CHECKING(if system getopt should be avoided)
+ if test "x$found_glibc" = xyes; then
+ found_getopt=no
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(HAVE_GETOPT)
+ fi
+ fi
+fi
+AM_CONDITIONAL(NO_GETOPT, [test "x$found_getopt" = xno])
+
+# Check for some functions that are replaced or omitted.
+AC_CHECK_FUNCS(
+ [ \
+ bzero \
+ setproctitle \
+ sysconf \
+ ]
+)
+
+# Check for BSD-style integer types.
+AC_MSG_CHECKING(for BSD-style unsigned types)
+AC_COMPILE_IFELSE(
+ [
+ #include <sys/types.h>
+ #ifdef HAVE_STDINT_H
+ #include <stdint.h>
+ #else
+ #include <inttypes.h>
+ #endif
+ int main(void)
+ { u_int8_t u8; u_int16_t u16; u_int32_t u32; u_int64_t u64; }
+ ],
+ [AC_DEFINE(HAVE_BSD_TYPES) AC_MSG_RESULT(yes)],
+ AC_MSG_RESULT(no)
+)
+
+# Look for a suitable queue.h.
+AC_CHECK_DECL(
+ TAILQ_PREV,
+ found_queue_h=yes,
+ found_queue_h=no,
+ [#include <sys/queue.h>]
+)
+AC_CHECK_DECL(
+ TAILQ_REPLACE,
+ ,
+ found_queue_h=no,
+ [#include <sys/queue.h>]
+)
+if test "x$found_queue_h" = xyes; then
+ AC_DEFINE(HAVE_QUEUE_H)
+fi
+
+# Look for __progname.
+AC_MSG_CHECKING(for __progname)
+AC_LINK_IFELSE(
+ [
+ #include <stdio.h>
+ #include <stdlib.h>
+ extern char *__progname;
+ int main(void) {
+ const char *cp = __progname;
+ printf("%s\n", cp);
+ exit(0);
+ }
+ ],
+ [AC_DEFINE(HAVE___PROGNAME) AC_MSG_RESULT(yes)],
+ AC_MSG_RESULT(no)
+)
+
+# Look for fcntl(F_CLOSEM).
+AC_CHECK_DECL(
+ F_CLOSEM,
+ AC_DEFINE(HAVE_FCNTL_CLOSEM),
+ ,
+ [#include <fcntl.h>]
+)
+
+# Look for /proc/$$.
+AC_MSG_CHECKING(for /proc/\$\$)
+if test -d /proc/$$; then
+ AC_DEFINE(HAVE_PROC_PID)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+# Look for /proc/$$/fd.
+AC_MSG_CHECKING(for /proc/\$\$/fd)
+if test -d /proc/$$/fd; then
+ AC_DEFINE(HAVE_DIRFD)
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+# Figure out the platform for osdep-*.c and forkpty-*.c.
+AC_MSG_CHECKING(platform)
+case "$host_os" in
+ *aix*)
+ AC_MSG_RESULT(aix)
+ PLATFORM=aix
+ ;;
+ *darwin*)
+ AC_MSG_RESULT(darwin)
+ AC_DEFINE(BROKEN_CMSG_FIRSTHDR)
+ PLATFORM=darwin
+ ;;
+ *linux*)
+ AC_MSG_RESULT(linux)
+ PLATFORM=linux
+ ;;
+ *freebsd*|*dragonfly*)
+ AC_MSG_RESULT(freebsd)
+ PLATFORM=freebsd
+ ;;
+ *netbsd*)
+ AC_MSG_RESULT(netbsd)
+ PLATFORM=netbsd
+ ;;
+ *openbsd*)
+ AC_MSG_RESULT(openbsd)
+ PLATFORM=openbsd
+ ;;
+ *sunos*)
+ AC_MSG_RESULT(sunos)
+ PLATFORM=sunos
+ ;;
+ *hpux*)
+ AC_MSG_RESULT(hpux)
+ PLATFORM=hpux
+ ;;
+ *)
+ AC_MSG_RESULT(unknown)
+ PLATFORM=unknown
+ ;;
+esac
+AC_SUBST(PLATFORM)
+AM_CONDITIONAL(IS_AIX, test "x$PLATFORM" = xaix)
+AM_CONDITIONAL(IS_DARWIN, test "x$PLATFORM" = xdarwin)
+AM_CONDITIONAL(IS_LINUX, test "x$PLATFORM" = xlinux)
+AM_CONDITIONAL(IS_FREEBSD, test "x$PLATFORM" = xfreebsd)
+AM_CONDITIONAL(IS_NETBSD, test "x$PLATFORM" = xnetbsd)
+AM_CONDITIONAL(IS_OPENBSD, test "x$PLATFORM" = xopenbsd)
+AM_CONDITIONAL(IS_SUNOS, test "x$PLATFORM" = xsunos)
+AM_CONDITIONAL(IS_HPUX, test "x$PLATFORM" = xhpux)
+AM_CONDITIONAL(IS_UNKNOWN, test "x$PLATFORM" = xunknown)
+
+# autoconf should create a Makefile. A shock!
+AC_OUTPUT(Makefile)
diff --git a/environ.o b/environ.o
new file mode 100644
index 0000000..8fcb02f
--- a/dev/null
+++ b/environ.o
Binary files differ
diff --git a/grid-utf8.o b/grid-utf8.o
new file mode 100644
index 0000000..2bbcfa8
--- a/dev/null
+++ b/grid-utf8.o
Binary files differ
diff --git a/grid-view.o b/grid-view.o
new file mode 100644
index 0000000..e0721e5
--- a/dev/null
+++ b/grid-view.o
Binary files differ
diff --git a/grid.o b/grid.o
new file mode 100644
index 0000000..6c0cf4b
--- a/dev/null
+++ b/grid.o
Binary files differ
diff --git a/input-keys.c b/input-keys.c
index f51d3d4..bd6c869 100644
--- a/input-keys.c
+++ b/input-keys.c
@@ -1,4 +1,4 @@
-/* $Id: input-keys.c,v 1.45 2010/09/07 19:32:58 nicm Exp $ */
+/* $Id: input-keys.c,v 1.48 2011/01/07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -39,7 +39,7 @@ struct input_key_ent {
#define INPUTKEY_CURSOR 0x2 /* cursor key */
};
-struct input_key_ent input_keys[] = {
+const struct input_key_ent input_keys[] = {
/* Backspace key. */
{ KEYC_BSPACE, "\177", 0 },
@@ -136,11 +136,11 @@ struct input_key_ent input_keys[] = {
void
input_key(struct window_pane *wp, int key)
{
- struct input_key_ent *ike;
- u_int i;
- size_t dlen;
- char *out;
- u_char ch;
+ const struct input_key_ent *ike;
+ u_int i;
+ size_t dlen;
+ char *out;
+ u_char ch;
log_debug2("writing key 0x%x", key);
@@ -201,11 +201,23 @@ input_key(struct window_pane *wp, int key)
void
input_mouse(struct window_pane *wp, struct mouse_event *m)
{
- char out[8];
-
- if (wp->screen->mode & MODE_MOUSE) {
- xsnprintf(out, sizeof out,
- "\033[M%c%c%c", m->b + 32, m->x + 33, m->y + 33);
- bufferevent_write(wp->event, out, strlen(out));
+ char buf[10];
+ size_t len;
+
+ if (wp->screen->mode & ALL_MOUSE_MODES) {
+ if (wp->screen->mode & MODE_MOUSE_UTF8) {
+ len = xsnprintf(buf, sizeof buf, "\033[M");
+ len += utf8_split2(m->b + 32, &buf[len]);
+ len += utf8_split2(m->x + 33, &buf[len]);
+ len += utf8_split2(m->y + 33, &buf[len]);
+ } else {
+ if (m->b > 223 || m->x >= 222 || m->y > 222)
+ return;
+ len = xsnprintf(buf, sizeof buf, "\033[M");
+ buf[len++] = m->b + 32;
+ buf[len++] = m->x + 33;
+ buf[len++] = m->y + 33;
+ }
+ bufferevent_write(wp->event, buf, len);
}
}
diff --git a/input-keys.o b/input-keys.o
new file mode 100644
index 0000000..b07e348
--- a/dev/null
+++ b/input-keys.o
Binary files differ
diff --git a/input.c b/input.c
index 2ac2d07..5030294 100644
--- a/input.c
+++ b/input.c
@@ -1,4 +1,4 @@
-/* $Id: input.c,v 1.109 2010/04/18 15:11:47 tcunha Exp $ */
+/* $Id: input.c,v 1.114 2011/01/21 23:56:11 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -681,7 +681,9 @@ input_parse(struct window_pane *wp)
if (EVBUFFER_LENGTH(evb) == 0)
return;
+
wp->window->flags |= WINDOW_ACTIVITY;
+ wp->window->flags &= ~WINDOW_SILENCE;
/*
* Open the screen. Use NULL wp if there is a mode set as don't want to
@@ -718,11 +720,11 @@ input_parse(struct window_pane *wp)
* Execute the handler, if any. Don't switch state if it
* returns non-zero.
*/
- if (itr->handler && itr->handler(ictx) != 0)
+ if (itr->handler != NULL && itr->handler(ictx) != 0)
continue;
/* And switch state, if necessary. */
- if (itr->state) {
+ if (itr->state != NULL) {
if (ictx->state->exit != NULL)
ictx->state->exit(ictx);
ictx->state = itr->state;
@@ -922,9 +924,9 @@ input_c0_dispatch(struct input_ctx *ictx)
int
input_esc_dispatch(struct input_ctx *ictx)
{
- struct screen_write_ctx *sctx = &ictx->ctx;
- struct screen *s = sctx->s;
- struct input_table_entry *entry;
+ struct screen_write_ctx *sctx = &ictx->ctx;
+ struct screen *s = sctx->s;
+ struct input_table_entry *entry;
if (ictx->flags & INPUT_DISCARD)
return (0);
@@ -951,7 +953,7 @@ input_esc_dispatch(struct input_ctx *ictx)
screen_write_insertmode(sctx, 0);
screen_write_kcursormode(sctx, 0);
screen_write_kkeypadmode(sctx, 0);
- screen_write_mousemode(sctx, 0);
+ screen_write_mousemode_off(sctx);
screen_write_clearscreen(sctx);
screen_write_cursormove(sctx, 0, 0);
@@ -1154,7 +1156,13 @@ input_csi_dispatch(struct input_ctx *ictx)
screen_write_cursormode(&ictx->ctx, 0);
break;
case 1000:
- screen_write_mousemode(&ictx->ctx, 0);
+ case 1001:
+ case 1002:
+ case 1003:
+ screen_write_mousemode_off(&ictx->ctx);
+ break;
+ case 1005:
+ screen_write_utf8mousemode(&ictx->ctx, 0);
break;
case 1049:
window_pane_alternate_off(wp, &ictx->cell);
@@ -1190,7 +1198,18 @@ input_csi_dispatch(struct input_ctx *ictx)
screen_write_cursormode(&ictx->ctx, 1);
break;
case 1000:
- screen_write_mousemode(&ictx->ctx, 1);
+ screen_write_mousemode_on(
+ &ictx->ctx, MODE_MOUSE_STANDARD);
+ break;
+ case 1002:
+ screen_write_mousemode_on(
+ &ictx->ctx, MODE_MOUSE_BUTTON);
+ break;
+ case 1003:
+ screen_write_mousemode_on(&ictx->ctx, MODE_MOUSE_ANY);
+ break;
+ case 1005:
+ screen_write_utf8mousemode(&ictx->ctx, 1);
break;
case 1049:
window_pane_alternate_on(wp, &ictx->cell);
diff --git a/input.o b/input.o
new file mode 100644
index 0000000..5bdf2b0
--- a/dev/null
+++ b/input.o
Binary files differ
diff --git a/job.c b/job.c
index ddb5f18..9fd249b 100644
--- a/job.c
+++ b/job.c
@@ -1,4 +1,4 @@
-/* $Id: job.c,v 1.18 2010/08/29 14:42:11 tcunha Exp $ */
+/* $Id: job.c,v 1.20 2011/01/21 23:44:13 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -136,7 +136,7 @@ job_free(struct job *job)
int
job_run(struct job *job)
{
- int nullfd, out[2], mode;
+ int nullfd, out[2];
if (job->fd != -1 || job->pid != -1)
return (0);
@@ -168,18 +168,15 @@ job_run(struct job *job)
if (nullfd != STDIN_FILENO && nullfd != STDERR_FILENO)
close(nullfd);
+ closefrom(STDERR_FILENO + 1);
+
execl(_PATH_BSHELL, "sh", "-c", job->cmd, (char *) NULL);
fatal("execl failed");
default: /* parent */
close(out[1]);
job->fd = out[0];
- if ((mode = fcntl(job->fd, F_GETFL)) == -1)
- fatal("fcntl failed");
- if (fcntl(job->fd, F_SETFL, mode|O_NONBLOCK) == -1)
- fatal("fcntl failed");
- if (fcntl(job->fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
+ setblocking(job->fd, 0);
if (job->event != NULL)
bufferevent_free(job->event);
diff --git a/job.o b/job.o
new file mode 100644
index 0000000..b59910c
--- a/dev/null
+++ b/job.o
Binary files differ
diff --git a/key-bindings.c b/key-bindings.c
index 0c44191..d244cf7 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -1,4 +1,4 @@
-/* $Id: key-bindings.c,v 1.95 2010/09/10 13:36:17 tcunha Exp $ */
+/* $Id: key-bindings.c,v 1.98 2011/01/07 14:45:34 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -124,9 +124,11 @@ key_bindings_init(void)
{ '8', 0, &cmd_select_window_entry },
{ '9', 0, &cmd_select_window_entry },
{ ':', 0, &cmd_command_prompt_entry },
+ { ';', 0, &cmd_last_pane_entry },
{ '=', 0, &cmd_choose_buffer_entry },
{ '?', 0, &cmd_list_keys_entry },
{ 'D', 0, &cmd_choose_client_entry },
+ { 'L', 0, &cmd_switch_client_entry },
{ '[', 0, &cmd_copy_mode_entry },
{ '\'', 0, &cmd_command_prompt_entry },
{ '\002', /* C-b */ 0, &cmd_send_prefix_entry },
@@ -185,9 +187,10 @@ key_bindings_init(void)
cmd = xmalloc(sizeof *cmd);
cmd->entry = table[i].entry;
- cmd->data = NULL;
- if (cmd->entry->init != NULL)
- cmd->entry->init(cmd, table[i].key);
+ if (cmd->entry->key_binding != NULL)
+ cmd->entry->key_binding(cmd, table[i].key);
+ else
+ cmd->args = args_create(0);
TAILQ_INSERT_HEAD(&cmdlist->list, cmd, qentry);
key_bindings_add(
diff --git a/key-bindings.o b/key-bindings.o
new file mode 100644
index 0000000..ff8fc4d
--- a/dev/null
+++ b/key-bindings.o
Binary files differ
diff --git a/key-string.c b/key-string.c
index 2b4f839..ffdd6be 100644
--- a/key-string.c
+++ b/key-string.c
@@ -1,4 +1,4 @@
-/* $Id: key-string.c,v 1.34 2010/06/05 20:29:11 micahcowan Exp $ */
+/* $Id: key-string.c,v 1.36 2011/01/22 22:31:09 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -25,7 +25,7 @@
int key_string_search_table(const char *);
int key_string_get_modifiers(const char **);
-struct {
+const struct {
const char *string;
int key;
} key_string_table[] = {
@@ -147,7 +147,7 @@ key_string_lookup_string(const char *string)
/* Is this a standard ASCII key? */
if (string[1] == '\0') {
key = (u_char) string[0];
- if (key < 32 || key > 126)
+ if (key < 32 || key == 127 || key > 255)
return (KEYC_NONE);
} else {
/* Otherwise look the key up in the table. */
@@ -213,7 +213,7 @@ key_string_lookup_key(int key)
}
/* Invalid keys are errors. */
- if (key >= 127)
+ if (key == 127 || key > 255)
return (NULL);
/* Check for standard or control key. */
@@ -225,7 +225,9 @@ key_string_lookup_key(int key)
} else if (key >= 32 && key <= 126) {
tmp[0] = key;
tmp[1] = '\0';
- }
+ } else if (key >= 128)
+ xsnprintf(tmp, sizeof tmp, "\\%o", key);
+
strlcat(out, tmp, sizeof out);
return (out);
}
diff --git a/key-string.o b/key-string.o
new file mode 100644
index 0000000..0033fd5
--- a/dev/null
+++ b/key-string.o
Binary files differ
diff --git a/layout-custom.o b/layout-custom.o
new file mode 100644
index 0000000..105fa0d
--- a/dev/null
+++ b/layout-custom.o
Binary files differ
diff --git a/layout-set.c b/layout-set.c
index 8c46d98..3fc2cc2 100644
--- a/layout-set.c
+++ b/layout-set.c
@@ -1,4 +1,4 @@
-/* $Id: layout-set.c,v 1.6 2010/05/14 14:16:37 tcunha Exp $ */
+/* $Id: layout-set.c,v 1.8 2010/12/22 15:23:59 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -135,10 +135,9 @@ layout_set_even_h(struct window *w)
return;
/* How many can we fit? */
- if (w->sx / n < PANE_MINIMUM + 1)
- width = PANE_MINIMUM + 1;
- else
- width = w->sx / n;
+ width = (w->sx - (n - 1)) / n;
+ if (width < PANE_MINIMUM)
+ width = PANE_MINIMUM;
/* Free the old root and construct a new. */
layout_free(w);
@@ -151,12 +150,12 @@ layout_set_even_h(struct window *w)
TAILQ_FOREACH(wp, &w->panes, entry) {
/* Create child cell. */
lcnew = layout_create_cell(lc);
- layout_set_size(lcnew, width - 1, w->sy, xoff, 0);
+ layout_set_size(lcnew, width, w->sy, xoff, 0);
layout_make_leaf(lcnew, wp);
TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
i++;
- xoff += width;
+ xoff += width + 1;
}
/* Allocate any remaining space. */
@@ -189,10 +188,9 @@ layout_set_even_v(struct window *w)
return;
/* How many can we fit? */
- if (w->sy / n < PANE_MINIMUM + 1)
- height = PANE_MINIMUM + 1;
- else
- height = w->sy / n;
+ height = (w->sy - (n - 1)) / n;
+ if (height < PANE_MINIMUM)
+ height = PANE_MINIMUM;
/* Free the old root and construct a new. */
layout_free(w);
@@ -205,12 +203,12 @@ layout_set_even_v(struct window *w)
TAILQ_FOREACH(wp, &w->panes, entry) {
/* Create child cell. */
lcnew = layout_create_cell(lc);
- layout_set_size(lcnew, w->sx, height - 1, 0, yoff);
+ layout_set_size(lcnew, w->sx, height, 0, yoff);
layout_make_leaf(lcnew, wp);
TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
i++;
- yoff += height;
+ yoff += height + 1;
}
/* Allocate any remaining space. */
@@ -233,8 +231,8 @@ layout_set_main_h(struct window *w)
{
struct window_pane *wp;
struct layout_cell *lc, *lcmain, *lcrow, *lcchild;
- u_int n, mainheight, width, height, used;
- u_int i, j, columns, rows, totalrows;
+ u_int n, mainheight, otherheight, width, height;
+ u_int used, i, j, columns, rows, totalrows;
layout_print_cell(w->layout_root, __func__, 1);
@@ -244,16 +242,26 @@ layout_set_main_h(struct window *w)
return;
n--; /* take off main pane */
- /* How many rows and columns will be needed? */
- columns = w->sx / (PANE_MINIMUM + 1); /* maximum columns */
+ /* How many rows and columns will be needed, not counting main? */
+ columns = (w->sx + 1) / (PANE_MINIMUM + 1); /* maximum columns */
if (columns == 0)
columns = 1;
rows = 1 + (n - 1) / columns;
columns = 1 + (n - 1) / rows;
- width = w->sx / columns;
+ width = (w->sx - (n - 1)) / columns;
/* Get the main pane height and add one for separator line. */
mainheight = options_get_number(&w->options, "main-pane-height") + 1;
+
+ /* Get the optional other pane height and add one for separator line. */
+ otherheight = options_get_number(&w->options, "other-pane-height") + 1;
+
+ /*
+ * If an other pane height was specified, honour it so long as it
+ * doesn't shrink the main height to less than the main-pane-height
+ */
+ if (otherheight > 1 && w->sx - otherheight > mainheight)
+ mainheight = w->sx - otherheight;
if (mainheight < PANE_MINIMUM + 1)
mainheight = PANE_MINIMUM + 1;
@@ -264,14 +272,14 @@ layout_set_main_h(struct window *w)
mainheight = PANE_MINIMUM + 2;
else
mainheight = w->sy - totalrows;
- height = PANE_MINIMUM + 1;
+ height = PANE_MINIMUM;
} else
- height = (w->sy - mainheight) / rows;
+ height = (w->sy - mainheight - (rows - 1)) / rows;
/* Free old tree and create a new root. */
layout_free(w);
lc = w->layout_root = layout_create_cell(NULL);
- layout_set_size(lc, w->sx, mainheight + rows * height, 0, 0);
+ layout_set_size(lc, w->sx, mainheight + rows * (height + 1) - 1, 0, 0);
layout_make_node(lc, LAYOUT_TOPBOTTOM);
/* Create the main pane. */
@@ -289,7 +297,7 @@ layout_set_main_h(struct window *w)
/* Create the new row. */
lcrow = layout_create_cell(lc);
- layout_set_size(lcrow, w->sx, height - 1, 0, 0);
+ layout_set_size(lcrow, w->sx, height, 0, 0);
TAILQ_INSERT_TAIL(&lc->cells, lcrow, entry);
/* If only one column, just use the row directly. */
@@ -304,7 +312,7 @@ layout_set_main_h(struct window *w)
for (i = 0; i < columns; i++) {
/* Create and add a pane cell. */
lcchild = layout_create_cell(lcrow);
- layout_set_size(lcchild, width - 1, height - 1, 0, 0);
+ layout_set_size(lcchild, width, height, 0, 0);
layout_make_leaf(lcchild, wp);
TAILQ_INSERT_TAIL(&lcrow->cells, lcchild, entry);
@@ -316,7 +324,7 @@ layout_set_main_h(struct window *w)
/* Adjust the row to fit the full width if necessary. */
if (i == columns)
i--;
- used = ((i + 1) * width) - 1;
+ used = ((i + 1) * (width + 1)) - 1;
if (w->sx <= used)
continue;
lcchild = TAILQ_LAST(&lcrow->cells, layout_cells);
@@ -324,7 +332,7 @@ layout_set_main_h(struct window *w)
}
/* Adjust the last row height to fit if necessary. */
- used = mainheight + (rows * height) - 1;
+ used = mainheight + (rows * height) + rows - 1;
if (w->sy > used) {
lcrow = TAILQ_LAST(&lc->cells, layout_cells);
layout_resize_adjust(lcrow, LAYOUT_TOPBOTTOM, w->sy - used);
@@ -344,8 +352,8 @@ layout_set_main_v(struct window *w)
{
struct window_pane *wp;
struct layout_cell *lc, *lcmain, *lccolumn, *lcchild;
- u_int n, mainwidth, width, height, used;
- u_int i, j, columns, rows, totalcolumns;
+ u_int n, mainwidth, otherwidth, width, height;
+ u_int used, i, j, columns, rows, totalcolumns;
layout_print_cell(w->layout_root, __func__, 1);
@@ -355,16 +363,26 @@ layout_set_main_v(struct window *w)
return;
n--; /* take off main pane */
- /* How many rows and columns will be needed? */
- rows = w->sy / (PANE_MINIMUM + 1); /* maximum rows */
+ /* How many rows and columns will be needed, not counting main? */
+ rows = (w->sy + 1) / (PANE_MINIMUM + 1); /* maximum rows */
if (rows == 0)
rows = 1;
columns = 1 + (n - 1) / rows;
rows = 1 + (n - 1) / columns;
- height = w->sy / rows;
+ height = (w->sy - (n - 1)) / rows;
/* Get the main pane width and add one for separator line. */
mainwidth = options_get_number(&w->options, "main-pane-width") + 1;
+
+ /* Get the optional other pane width and add one for separator line. */
+ otherwidth = options_get_number(&w->options, "other-pane-width") + 1;
+
+ /*
+ * If an other pane width was specified, honour it so long as it
+ * doesn't shrink the main width to less than the main-pane-width
+ */
+ if (otherwidth > 1 && w->sx - otherwidth > mainwidth)
+ mainwidth = w->sx - otherwidth;
if (mainwidth < PANE_MINIMUM + 1)
mainwidth = PANE_MINIMUM + 1;
@@ -375,14 +393,14 @@ layout_set_main_v(struct window *w)
mainwidth = PANE_MINIMUM + 2;
else
mainwidth = w->sx - totalcolumns;
- width = PANE_MINIMUM + 1;
+ width = PANE_MINIMUM;
} else
- width = (w->sx - mainwidth) / columns;
+ width = (w->sx - mainwidth - (columns - 1)) / columns;
/* Free old tree and create a new root. */
layout_free(w);
lc = w->layout_root = layout_create_cell(NULL);
- layout_set_size(lc, mainwidth + columns * width, w->sy, 0, 0);
+ layout_set_size(lc, mainwidth + columns * (width + 1) - 1, w->sy, 0, 0);
layout_make_node(lc, LAYOUT_LEFTRIGHT);
/* Create the main pane. */
@@ -400,7 +418,7 @@ layout_set_main_v(struct window *w)
/* Create the new column. */
lccolumn = layout_create_cell(lc);
- layout_set_size(lccolumn, width - 1, w->sy, 0, 0);
+ layout_set_size(lccolumn, width, w->sy, 0, 0);
TAILQ_INSERT_TAIL(&lc->cells, lccolumn, entry);
/* If only one row, just use the row directly. */
@@ -415,7 +433,7 @@ layout_set_main_v(struct window *w)
for (i = 0; i < rows; i++) {
/* Create and add a pane cell. */
lcchild = layout_create_cell(lccolumn);
- layout_set_size(lcchild, width - 1, height - 1, 0, 0);
+ layout_set_size(lcchild, width, height, 0, 0);
layout_make_leaf(lcchild, wp);
TAILQ_INSERT_TAIL(&lccolumn->cells, lcchild, entry);
@@ -427,7 +445,7 @@ layout_set_main_v(struct window *w)
/* Adjust the column to fit the full height if necessary. */
if (i == rows)
i--;
- used = ((i + 1) * height) - 1;
+ used = ((i + 1) * (height + 1)) - 1;
if (w->sy <= used)
continue;
lcchild = TAILQ_LAST(&lccolumn->cells, layout_cells);
@@ -435,7 +453,7 @@ layout_set_main_v(struct window *w)
}
/* Adjust the last column width to fit if necessary. */
- used = mainwidth + (columns * width) - 1;
+ used = mainwidth + (columns * width) + columns - 1;
if (w->sx > used) {
lccolumn = TAILQ_LAST(&lc->cells, layout_cells);
layout_resize_adjust(lccolumn, LAYOUT_LEFTRIGHT, w->sx - used);
@@ -474,17 +492,18 @@ layout_set_tiled(struct window *w)
}
/* What width and height should they be? */
- width = w->sx / columns;
- if (width < PANE_MINIMUM + 1)
- width = PANE_MINIMUM + 1;
- height = w->sy / rows;
- if (width < PANE_MINIMUM + 1)
- width = PANE_MINIMUM + 1;
+ width = (w->sx - (columns - 1)) / columns;
+ if (width < PANE_MINIMUM)
+ width = PANE_MINIMUM;
+ height = (w->sy - (rows - 1)) / rows;
+ if (height < PANE_MINIMUM)
+ height = PANE_MINIMUM;
/* Free old tree and create a new root. */
layout_free(w);
lc = w->layout_root = layout_create_cell(NULL);
- layout_set_size(lc, width * columns, height * rows, 0, 0);
+ layout_set_size(lc, (width + 1) * columns - 1,
+ (height + 1) * rows - 1, 0, 0);
layout_make_node(lc, LAYOUT_TOPBOTTOM);
/* Create a grid of the cells. */
@@ -496,7 +515,7 @@ layout_set_tiled(struct window *w)
/* Create the new row. */
lcrow = layout_create_cell(lc);
- layout_set_size(lcrow, w->sx, height - 1, 0, 0);
+ layout_set_size(lcrow, w->sx, height, 0, 0);
TAILQ_INSERT_TAIL(&lc->cells, lcrow, entry);
/* If only one column, just use the row directly. */
@@ -511,7 +530,7 @@ layout_set_tiled(struct window *w)
for (i = 0; i < columns; i++) {
/* Create and add a pane cell. */
lcchild = layout_create_cell(lcrow);
- layout_set_size(lcchild, width - 1, height - 1, 0, 0);
+ layout_set_size(lcchild, width, height, 0, 0);
layout_make_leaf(lcchild, wp);
TAILQ_INSERT_TAIL(&lcrow->cells, lcchild, entry);
@@ -526,7 +545,7 @@ layout_set_tiled(struct window *w)
*/
if (i == columns)
i--;
- used = ((i + 1) * width) - 1;
+ used = ((i + 1) * (width + 1)) - 1;
if (w->sx <= used)
continue;
lcchild = TAILQ_LAST(&lcrow->cells, layout_cells);
@@ -534,7 +553,7 @@ layout_set_tiled(struct window *w)
}
/* Adjust the last row height to fit if necessary. */
- used = (rows * height) - 1;
+ used = (rows * height) + rows - 1;
if (w->sy > used) {
lcrow = TAILQ_LAST(&lc->cells, layout_cells);
layout_resize_adjust(lcrow, LAYOUT_TOPBOTTOM, w->sy - used);
diff --git a/layout-set.o b/layout-set.o
new file mode 100644
index 0000000..04381c6
--- a/dev/null
+++ b/layout-set.o
Binary files differ
diff --git a/layout-string.o b/layout-string.o
new file mode 100644
index 0000000..61f05c0
--- a/dev/null
+++ b/layout-string.o
Binary files differ
diff --git a/layout.o b/layout.o
new file mode 100644
index 0000000..e08183b
--- a/dev/null
+++ b/layout.o
Binary files differ
diff --git a/log.o b/log.o
new file mode 100644
index 0000000..2a81e04
--- a/dev/null
+++ b/log.o
Binary files differ
diff --git a/mode-key.c b/mode-key.c
index 7290ce5..033607d 100644
--- a/mode-key.c
+++ b/mode-key.c
@@ -1,4 +1,4 @@
-/* $Id: mode-key.c,v 1.46 2010/03/16 17:30:58 micahcowan Exp $ */
+/* $Id: mode-key.c,v 1.47 2011/01/03 23:31:26 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -40,7 +40,7 @@
*/
/* Edit keys command strings. */
-struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
+const struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
{ MODEKEYEDIT_BACKSPACE, "backspace" },
{ MODEKEYEDIT_CANCEL, "cancel" },
{ MODEKEYEDIT_COMPLETE, "complete" },
@@ -63,7 +63,7 @@ struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
};
/* Choice keys command strings. */
-struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
+const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ MODEKEYCHOICE_CANCEL, "cancel" },
{ MODEKEYCHOICE_CHOOSE, "choose" },
{ MODEKEYCHOICE_DOWN, "down" },
@@ -77,7 +77,7 @@ struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
};
/* Copy keys command strings. */
-struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
+const struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
{ MODEKEYCOPY_BACKTOINDENTATION, "back-to-indentation" },
{ MODEKEYCOPY_BOTTOMLINE, "bottom-line" },
{ MODEKEYCOPY_CANCEL, "cancel" },
@@ -384,7 +384,7 @@ mode_key_cmp(struct mode_key_binding *mbind1, struct mode_key_binding *mbind2)
}
const char *
-mode_key_tostring(struct mode_key_cmdstr *cmdstr, enum mode_key_cmd cmd)
+mode_key_tostring(const struct mode_key_cmdstr *cmdstr, enum mode_key_cmd cmd)
{
for (; cmdstr->name != NULL; cmdstr++) {
if (cmdstr->cmd == cmd)
@@ -394,7 +394,7 @@ mode_key_tostring(struct mode_key_cmdstr *cmdstr, enum mode_key_cmd cmd)
}
enum mode_key_cmd
-mode_key_fromstring(struct mode_key_cmdstr *cmdstr, const char *name)
+mode_key_fromstring(const struct mode_key_cmdstr *cmdstr, const char *name)
{
for (; cmdstr->name != NULL; cmdstr++) {
if (strcasecmp(cmdstr->name, name) == 0)
diff --git a/mode-key.o b/mode-key.o
new file mode 100644
index 0000000..82b81ce
--- a/dev/null
+++ b/mode-key.o
Binary files differ
diff --git a/names.o b/names.o
new file mode 100644
index 0000000..097362f
--- a/dev/null
+++ b/names.o
Binary files differ
diff --git a/options-table.c b/options-table.c
new file mode 100644
index 0000000..96ffd28
--- a/dev/null
+++ b/options-table.c
@@ -0,0 +1,643 @@
+/* $Id: options-table.c,v 1.4 2011/01/21 23:54:19 tcunha Exp $ */
+
+/*
+ * Copyright (c) 2011 Nicholas Marriott <[email protected]>
+ *
+ * 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"
+
+/*
+ * This file has a tables with all the server, session and window
+ * options. These tables are the master copy of the options with their real
+ * (user-visible) types, range limits and default values. At start these are
+ * copied into the runtime global options trees (which only has number and
+ * string types). These tables are then used to loop up the real type when
+ * the user sets an option or its value needs to be shown.
+ */
+
+/* Choice option type lists. */
+const char *options_table_mode_keys_list[] = {
+ "emacs", "vi", NULL
+};
+const char *options_table_clock_mode_style_list[] = {
+ "12", "24", NULL
+};
+const char *options_table_status_keys_list[] = {
+ "emacs", "vi", NULL
+};
+const char *options_table_status_justify_list[] = {
+ "left", "centre", "right", NULL
+};
+const char *options_table_bell_action_list[] = {
+ "none", "any", "current", NULL
+};
+
+/* Server options. */
+const struct options_table_entry server_options_table[] = {
+ { .name = "buffer-limit",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 1,
+ .maximum = INT_MAX,
+ .default_num = 9
+ },
+
+ { .name = "escape-time",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 500
+ },
+
+ { .name = "exit-unattached",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "quiet",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0 /* overridden in main() */
+ },
+
+ { .name = NULL }
+};
+
+/* Session options. */
+const struct options_table_entry session_options_table[] = {
+ { .name = "base-index",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0
+ },
+
+ { .name = "bell-action",
+ .type = OPTIONS_TABLE_CHOICE,
+ .choices = options_table_bell_action_list,
+ .default_num = BELL_ANY
+ },
+
+ { .name = "default-command",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = ""
+ },
+
+ { .name = "default-path",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = ""
+ },
+
+ { .name = "default-shell",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = _PATH_BSHELL
+ },
+
+ { .name = "default-terminal",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "screen"
+ },
+
+ { .name = "destroy-unattached",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "detach-on-destroy",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 1
+ },
+
+ { .name = "display-panes-active-colour",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 1
+ },
+
+ { .name = "display-panes-colour",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 4
+ },
+
+ { .name = "display-panes-time",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 1,
+ .maximum = INT_MAX,
+ .default_num = 1000
+ },
+
+ { .name = "display-time",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 1,
+ .maximum = INT_MAX,
+ .default_num = 750
+ },
+
+ { .name = "history-limit",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 2000
+ },
+
+ { .name = "lock-after-time",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0
+ },
+
+ { .name = "lock-command",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "lock -np"
+ },
+
+ { .name = "lock-server",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 1
+ },
+
+ { .name = "message-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = 0
+ },
+
+ { .name = "message-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 3
+ },
+
+ { .name = "message-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 0
+ },
+
+ { .name = "message-limit",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 20
+ },
+
+ { .name = "mouse-select-pane",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "mouse-utf8",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "pane-active-border-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "pane-active-border-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 2
+ },
+
+ { .name = "pane-border-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "pane-border-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "prefix",
+ .type = OPTIONS_TABLE_KEYS,
+ /* set in main() */
+ },
+
+ { .name = "repeat-time",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = SHRT_MAX,
+ .default_num = 500
+ },
+
+ { .name = "set-remain-on-exit",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "set-titles",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "set-titles-string",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "#S:#I:#W - \"#T\""
+ },
+
+ { .name = "status",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 1
+ },
+
+ { .name = "status-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = 0
+ },
+
+ { .name = "status-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 2
+ },
+
+ { .name = "status-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 0
+ },
+
+ { .name = "status-interval",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 15
+ },
+
+ { .name = "status-justify",
+ .type = OPTIONS_TABLE_CHOICE,
+ .choices = options_table_status_justify_list,
+ .default_num = 0
+ },
+
+ { .name = "status-keys",
+ .type = OPTIONS_TABLE_CHOICE,
+ .choices = options_table_status_keys_list,
+ .default_num = MODEKEY_EMACS
+ },
+
+ { .name = "status-left",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "[#S]"
+ },
+
+ { .name = "status-left-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = 0
+ },
+
+ { .name = "status-left-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "status-left-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "status-left-length",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = SHRT_MAX,
+ .default_num = 10
+ },
+
+ { .name = "status-right",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "\"#22T\" %H:%M %d-%b-%y"
+ },
+
+ { .name = "status-right-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = 0
+ },
+
+ { .name = "status-right-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "status-right-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "status-right-length",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = SHRT_MAX,
+ .default_num = 40
+ },
+
+ { .name = "status-utf8",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0 /* overridden in main() */
+ },
+
+ { .name = "terminal-overrides",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "*88col*:colors=88,*256col*:colors=256"
+ },
+
+ { .name = "update-environment",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
+ "SSH_CONNECTION WINDOWID XAUTHORITY"
+
+ },
+
+ { .name = "visual-activity",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "visual-bell",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "visual-content",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "visual-silence",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = NULL }
+};
+
+/* Window options. */
+const struct options_table_entry window_options_table[] = {
+ { .name = "aggressive-resize",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "alternate-screen",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 1
+ },
+
+ { .name = "automatic-rename",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 1
+ },
+
+ { .name = "clock-mode-colour",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 4
+ },
+
+ { .name = "clock-mode-style",
+ .type = OPTIONS_TABLE_CHOICE,
+ .choices = options_table_clock_mode_style_list,
+ .default_num = 1
+ },
+
+ { .name = "force-height",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0
+ },
+
+ { .name = "force-width",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0
+ },
+
+ { .name = "main-pane-height",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 1,
+ .maximum = INT_MAX,
+ .default_num = 24
+ },
+
+ { .name = "main-pane-width",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 1,
+ .maximum = INT_MAX,
+ .default_num = 80
+ },
+
+ { .name = "mode-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = 0
+ },
+
+ { .name = "mode-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 3
+ },
+
+ { .name = "mode-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 0
+ },
+
+ { .name = "mode-keys",
+ .type = OPTIONS_TABLE_CHOICE,
+ .choices = options_table_mode_keys_list,
+ .default_num = MODEKEY_EMACS
+ },
+
+ { .name = "mode-mouse",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "monitor-activity",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "monitor-content",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = ""
+ },
+
+ { .name = "monitor-silence",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0
+ },
+
+ { .name = "other-pane-height",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0
+ },
+
+ { .name = "other-pane-width",
+ .type = OPTIONS_TABLE_NUMBER,
+ .minimum = 0,
+ .maximum = INT_MAX,
+ .default_num = 0
+ },
+
+ { .name = "remain-on-exit",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "synchronize-panes",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = "utf8",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0 /* overridden in main() */
+ },
+
+ { .name = "window-status-alert-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = GRID_ATTR_REVERSE
+ },
+
+ { .name = "window-status-alert-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "window-status-alert-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "window-status-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = 0
+ },
+
+ { .name = "window-status-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "window-status-current-attr",
+ .type = OPTIONS_TABLE_ATTRIBUTES,
+ .default_num = 0
+ },
+
+ { .name = "window-status-current-bg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "window-status-current-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "window-status-current-format",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "#I:#W#F"
+ },
+
+ { .name = "window-status-fg",
+ .type = OPTIONS_TABLE_COLOUR,
+ .default_num = 8
+ },
+
+ { .name = "window-status-format",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "#I:#W#F"
+ },
+
+ { .name = "word-separators",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = " [email protected]"
+ },
+
+ { .name = "xterm-keys",
+ .type = OPTIONS_TABLE_FLAG,
+ .default_num = 0
+ },
+
+ { .name = NULL }
+};
+
+/* Populate an options tree from a table. */
+void
+options_table_populate_tree(
+ const struct options_table_entry *table, struct options *oo)
+{
+ const struct options_table_entry *oe;
+
+ for (oe = table; oe->name != NULL; oe++) {
+ if (oe->default_str != NULL)
+ options_set_string(oo, oe->name, "%s", oe->default_str);
+ else
+ options_set_number(oo, oe->name, oe->default_num);
+ }
+}
+
+/* Print an option using its type from the table. */
+const char *
+options_table_print_entry(
+ const struct options_table_entry *oe, struct options_entry *o)
+{
+ static char out[BUFSIZ];
+ const char *s;
+ struct keylist *keylist;
+ u_int i;
+
+ *out = '\0';
+ switch (oe->type) {
+ case OPTIONS_TABLE_STRING:
+ xsnprintf(out, sizeof out, "\"%s\"", o->str);
+ break;
+ case OPTIONS_TABLE_NUMBER:
+ xsnprintf(out, sizeof out, "%lld", o->num);
+ break;
+ case OPTIONS_TABLE_KEYS:
+ keylist = o->data;
+ for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
+ s = key_string_lookup_key(ARRAY_ITEM(keylist, i));
+ strlcat(out, s, sizeof out);
+ if (i != ARRAY_LENGTH(keylist) - 1)
+ strlcat(out, ",", sizeof out);
+ }
+ break;
+ case OPTIONS_TABLE_COLOUR:
+ s = colour_tostring(o->num);
+ xsnprintf(out, sizeof out, "%s", s);
+ break;
+ case OPTIONS_TABLE_ATTRIBUTES:
+ s = attributes_tostring(o->num);
+ xsnprintf(out, sizeof out, "%s", s);
+ break;
+ case OPTIONS_TABLE_FLAG:
+ if (o->num)
+ strlcpy(out, "on", sizeof out);
+ else
+ strlcpy(out, "off", sizeof out);
+ break;
+ case OPTIONS_TABLE_CHOICE:
+ s = oe->choices[o->num];
+ xsnprintf(out, sizeof out, "%s", s);
+ break;
+ }
+ return (out);
+}
diff --git a/options.o b/options.o
new file mode 100644
index 0000000..fc40d6d
--- a/dev/null
+++ b/options.o
Binary files differ
diff --git a/cmd-lock-session.c b/osdep-aix.c
index 75cc6da..03e8558 100644
--- a/cmd-lock-session.c
+++ b/osdep-aix.c
@@ -1,7 +1,7 @@
-/* $Id: cmd-lock-session.c,v 1.2 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: osdep-aix.c,v 1.1 2011/01/10 22:00:47 nicm Exp $ */
/*
- * Copyright (c) 2009 Nicholas Marriott <[email protected]>
+ * Copyright (c) 2011 Nicholas Marriott <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,36 +18,18 @@
#include <sys/types.h>
-#include "tmux.h"
-
-/*
- * Lock all clients attached to a session.
- */
-
-int cmd_lock_session_exec(struct cmd *, struct cmd_ctx *);
+#include <event.h>
-const struct cmd_entry cmd_lock_session_entry = {
- "lock-session", "locks",
- CMD_TARGET_SESSION_USAGE,
- 0, "",
- cmd_target_init,
- cmd_target_parse,
- cmd_lock_session_exec,
- cmd_target_free,
- cmd_target_print
-};
+#include "tmux.h"
-int
-cmd_lock_session_exec(struct cmd *self, struct cmd_ctx *ctx)
+char *
+osdep_get_name(unused int fd, unused char *tty)
{
- struct cmd_target_data *data = self->data;
- struct session *s;
-
- if ((s = cmd_find_session(ctx, data->target)) == NULL)
- return (-1);
-
- server_lock_session(s);
- recalculate_sizes();
+ return (NULL);
+}
- return (0);
+struct event_base *
+osdep_event_init(void)
+{
+ return (event_init());
}
diff --git a/osdep-darwin.c b/osdep-darwin.c
index bbc69ac..cf0ec28 100644
--- a/osdep-darwin.c
+++ b/osdep-darwin.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: osdep-darwin.c,v 1.12 2010/12/30 20:41:07 nicm Exp $ */
/*
* Copyright (c) 2009 Joshua Elsasser <[email protected]>
@@ -19,11 +19,13 @@
#include <sys/types.h>
#include <sys/sysctl.h>
+#include <event.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-char *osdep_get_name(int, char *);
+char *osdep_get_name(int, char *);
+struct event_base *osdep_event_init(void);
#define unused __attribute__ ((unused))
@@ -31,7 +33,7 @@ char *
osdep_get_name(int fd, unused char *tty)
{
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 };
- size_t size;
+ size_t size;
struct kinfo_proc kp;
if ((mib[3] = tcgetpgrp(fd)) == -1)
@@ -45,3 +47,15 @@ osdep_get_name(int fd, unused char *tty)
return (strdup(kp.kp_proc.p_comm));
}
+
+struct event_base *
+osdep_event_init(void)
+{
+ /*
+ * On OS X, kqueue and poll are both completely broken and don't
+ * work on anything except socket file descriptors (yes, really).
+ */
+ setenv("EVENT_NOKQUEUE", "1", 1);
+ setenv("EVENT_NOPOLL", "1", 1);
+ return (event_init());
+}
diff --git a/osdep-freebsd.c b/osdep-freebsd.c
index ddd865e..f13313b 100644
--- a/osdep-freebsd.c
+++ b/osdep-freebsd.c
@@ -1,4 +1,4 @@
-/* $Id: osdep-freebsd.c,v 1.19 2009/08/09 18:00:45 tcunha Exp $ */
+/* $Id: osdep-freebsd.c,v 1.20 2010/12/30 20:41:08 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -24,6 +24,7 @@
#include <err.h>
#include <errno.h>
+#include <event.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -31,6 +32,7 @@
struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *);
char *osdep_get_name(int, char *);
+struct event_base *osdep_event_init(void);
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
@@ -127,3 +129,14 @@ error:
free(buf);
return (NULL);
}
+
+struct event_base *
+osdep_event_init(void)
+{
+ /*
+ * On some versions of FreeBSD, kqueue doesn't work properly on tty
+ * file descriptors. This is fixed in recent FreeBSD versions.
+ */
+ setenv("EVENT_NOKQUEUE", "1", 1);
+ return (event_init());
+}
diff --git a/cmd-lock-client.c b/osdep-hpux.c
index 691be44..510cd35 100644
--- a/cmd-lock-client.c
+++ b/osdep-hpux.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-lock-client.c,v 1.2 2009/11/14 17:56:39 tcunha Exp $ */
+/* $Id: osdep-hpux.c,v 1.1 2011/01/21 20:35:20 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -18,36 +18,18 @@
#include <sys/types.h>
-#include "tmux.h"
-
-/*
- * Lock a single client.
- */
-
-int cmd_lock_client_exec(struct cmd *, struct cmd_ctx *);
+#include <event.h>
-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
-};
+#include "tmux.h"
-int
-cmd_lock_client_exec(struct cmd *self, struct cmd_ctx *ctx)
+char *
+osdep_get_name(unused int fd, unused char *tty)
{
- struct cmd_target_data *data = self->data;
- struct client *c;
-
- if ((c = cmd_find_client(ctx, data->target)) == NULL)
- return (-1);
-
- server_lock_client(c);
- recalculate_sizes();
+ return (NULL);
+}
- return (0);
+struct event_base *
+osdep_event_init(void)
+{
+ return (event_init());
}
diff --git a/osdep-linux.c b/osdep-linux.c
index b7235a5..63f311b 100644
--- a/osdep-linux.c
+++ b/osdep-linux.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: osdep-linux.c,v 1.8 2011/01/13 19:58:47 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -19,7 +19,9 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <event.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
@@ -57,3 +59,18 @@ osdep_get_name(int fd, unused char *tty)
fclose(f);
return (buf);
}
+
+struct event_base *
+osdep_event_init(void)
+{
+ /*
+ * On Linux, epoll doesn't work on /dev/null (yes, really).
+ *
+ * This has been commented because libevent versions up until the very
+ * latest (1.4 git or 2.0.10) do not handle signals properly when using
+ * poll or select, causing hangs.
+ *
+ */
+ /* setenv("EVENT_NOEPOLL", "1", 1); */
+ return (event_init());
+}
diff --git a/osdep-linux.o b/osdep-linux.o
new file mode 100644
index 0000000..2b011a3
--- a/dev/null
+++ b/osdep-linux.o
Binary files differ
diff --git a/osdep-netbsd.c b/osdep-netbsd.c
index aa25c0e..522d5af 100644
--- a/osdep-netbsd.c
+++ b/osdep-netbsd.c
@@ -1,4 +1,4 @@
-/* $Id: osdep-netbsd.c,v 1.9 2009/09/24 12:30:22 nicm Exp $ */
+/* $Id: osdep-netbsd.c,v 1.10 2010/12/30 20:41:08 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -22,6 +22,7 @@
#include <sys/sysctl.h>
#include <errno.h>
+#include <event.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -33,6 +34,7 @@
struct kinfo_proc2 *cmp_procs(struct kinfo_proc2 *, struct kinfo_proc2 *);
char *osdep_get_name(int, char *);
+struct event_base *osdep_event_init(void);
struct kinfo_proc2 *
cmp_procs(struct kinfo_proc2 *p1, struct kinfo_proc2 *p2)
@@ -120,3 +122,9 @@ error:
free(buf);
return (NULL);
}
+
+struct event_base *
+osdep_event_init(void)
+{
+ return (event_init());
+}
diff --git a/osdep-openbsd.c b/osdep-openbsd.c
index 2f6d88f..cec140f 100644
--- a/osdep-openbsd.c
+++ b/osdep-openbsd.c
@@ -1,4 +1,4 @@
-/* $Id: osdep-openbsd.c,v 1.20 2009/12/26 23:48:37 tcunha Exp $ */
+/* $Id: osdep-openbsd.c,v 1.22 2010/12/30 20:42:39 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -21,6 +21,7 @@
#include <sys/stat.h>
#include <errno.h>
+#include <event.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -35,7 +36,8 @@
((p)->p_stat == SSTOP || (p)->p_stat == SZOMB || (p)->p_stat == SDEAD)
struct kinfo_proc2 *cmp_procs(struct kinfo_proc2 *, struct kinfo_proc2 *);
-char *osdep_get_name(int, char *);
+char *osdep_get_name(int, char *);
+struct event_base *osdep_event_init(void);
struct kinfo_proc2 *
cmp_procs(struct kinfo_proc2 *p1, struct kinfo_proc2 *p2)
@@ -130,3 +132,9 @@ error:
free(buf);
return (NULL);
}
+
+struct event_base *
+osdep_event_init(void)
+{
+ return (event_init());
+}
diff --git a/osdep-sunos.c b/osdep-sunos.c
index 925fc04..f7fd1ee 100644
--- a/osdep-sunos.c
+++ b/osdep-sunos.c
@@ -1,4 +1,4 @@
-/* $Id: osdep-sunos.c,v 1.2 2009/10/15 07:11:25 nicm Exp $ */
+/* $Id: osdep-sunos.c,v 1.3 2010/12/30 20:41:08 nicm Exp $ */
/*
* Copyright (c) 2009 Todd Carson <[email protected]>
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <event.h>
#include <fcntl.h>
#include <procfs.h>
#include <stdio.h>
@@ -63,3 +64,9 @@ osdep_get_name(int fd, char *tty)
return (xstrdup(p.pr_fname));
}
+
+struct event_base *
+osdep_event_init(void)
+{
+ return (event_init());
+}
diff --git a/osdep-unknown.c b/osdep-unknown.c
index 2b8d20f..e181ba7 100644
--- a/osdep-unknown.c
+++ b/osdep-unknown.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: osdep-unknown.c,v 1.6 2010/12/30 20:41:08 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -18,6 +18,8 @@
#include <sys/types.h>
+#include <event.h>
+
#include "tmux.h"
char *
@@ -25,3 +27,9 @@ osdep_get_name(unused int fd, unused char *tty)
{
return (NULL);
}
+
+struct event_base *
+osdep_event_init(void)
+{
+ return (event_init());
+}
diff --git a/paste.c b/paste.c
index 10701e1..977d790 100644
--- a/paste.c
+++ b/paste.c
@@ -1,4 +1,4 @@
-/* $Id: paste.c,v 1.15 2010/06/22 23:36:54 tcunha Exp $ */
+/* $Id: paste.c,v 1.16 2010/12/30 22:39:49 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -28,19 +28,6 @@
* string!
*/
-void
-paste_init_stack(struct paste_stack *ps)
-{
- ARRAY_INIT(ps);
-}
-
-void
-paste_free_stack(struct paste_stack *ps)
-{
- while (paste_free_top(ps) == 0)
- ;
-}
-
/* Return each item of the stack in turn. */
struct paste_buffer *
paste_walk_stack(struct paste_stack *ps, uint *idx)
diff --git a/paste.o b/paste.o
new file mode 100644
index 0000000..5b17abf
--- a/dev/null
+++ b/paste.o
Binary files differ
diff --git a/resize.c b/resize.c
index b666dde..da3c498 100644
--- a/resize.c
+++ b/resize.c
@@ -1,4 +1,4 @@
-/* $Id: resize.c,v 1.25 2010/06/22 23:26:18 tcunha Exp $ */
+/* $Id: resize.c,v 1.27 2010/12/22 15:36:44 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -52,11 +52,7 @@ recalculate_sizes(void)
u_int i, j, ssx, ssy, has, limit;
int flag;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s == NULL)
- continue;
-
+ RB_FOREACH(s, sessions, &sessions) {
ssx = ssy = UINT_MAX;
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
@@ -98,9 +94,8 @@ recalculate_sizes(void)
flag = options_get_number(&w->options, "aggressive-resize");
ssx = ssy = UINT_MAX;
- for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
- s = ARRAY_ITEM(&sessions, j);
- if (s == NULL || s->flags & SESSION_UNATTACHED)
+ RB_FOREACH(s, sessions, &sessions) {
+ if (s->flags & SESSION_UNATTACHED)
continue;
if (flag)
has = s->curw->window == w;
@@ -113,11 +108,8 @@ recalculate_sizes(void)
ssy = s->sy;
}
}
- if (ssx == UINT_MAX || ssy == UINT_MAX) {
- w->flags |= WINDOW_HIDDEN;
+ if (ssx == UINT_MAX || ssy == UINT_MAX)
continue;
- }
- w->flags &= ~WINDOW_HIDDEN;
limit = options_get_number(&w->options, "force-width");
if (limit != 0 && ssx > limit)
diff --git a/resize.o b/resize.o
new file mode 100644
index 0000000..b14a756
--- a/dev/null
+++ b/resize.o
Binary files differ
diff --git a/screen-redraw.o b/screen-redraw.o
new file mode 100644
index 0000000..3efb8c7
--- a/dev/null
+++ b/screen-redraw.o
Binary files differ
diff --git a/screen-write.c b/screen-write.c
index 97bfe9b..3e757f6 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -1,4 +1,4 @@
-/* $Id: screen-write.c,v 1.90 2010/06/16 18:09:23 micahcowan Exp $ */
+/* $Id: screen-write.c,v 1.92 2011/01/07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -829,16 +829,35 @@ screen_write_insertmode(struct screen_write_ctx *ctx, int state)
s->mode &= ~MODE_INSERT;
}
-/* Set mouse mode. */
+/* Set UTF-8 mouse mode. */
void
-screen_write_mousemode(struct screen_write_ctx *ctx, int state)
+screen_write_utf8mousemode(struct screen_write_ctx *ctx, int state)
{
struct screen *s = ctx->s;
if (state)
- s->mode |= MODE_MOUSE;
+ s->mode |= MODE_MOUSE_UTF8;
else
- s->mode &= ~MODE_MOUSE;
+ s->mode &= ~MODE_MOUSE_UTF8;
+}
+
+/* Set mouse mode off. */
+void
+screen_write_mousemode_off(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ s->mode &= ~ALL_MOUSE_MODES;
+}
+
+/* Set mouse mode on. */
+void
+screen_write_mousemode_on(struct screen_write_ctx *ctx, int mode)
+{
+ struct screen *s = ctx->s;
+
+ s->mode &= ~ALL_MOUSE_MODES;
+ s->mode |= mode;
}
/* Line feed. */
diff --git a/screen-write.o b/screen-write.o
new file mode 100644
index 0000000..b6f3c66
--- a/dev/null
+++ b/screen-write.o
Binary files differ
diff --git a/screen.c b/screen.c
index a9f18f6..a3261c0 100644
--- a/screen.c
+++ b/screen.c
@@ -1,4 +1,4 @@
-/* $Id: screen.c,v 1.102 2010/07/19 18:31:42 nicm Exp $ */
+/* $Id: screen.c,v 1.103 2010/12/11 17:57:28 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -287,7 +287,7 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
*/
if (sel->ex < sel->sx) {
/* Cursor (ex) is on the left. */
- if (px <= sel->ex)
+ if (px < sel->ex)
return (0);
if (px > sel->sx)
@@ -297,7 +297,7 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
if (px < sel->sx)
return (0);
- if (px >= sel->ex)
+ if (px > sel->ex)
return (0);
}
} else {
diff --git a/screen.o b/screen.o
new file mode 100644
index 0000000..7d42e97
--- a/dev/null
+++ b/screen.o
Binary files differ
diff --git a/server-client.c b/server-client.c
index 32b5d02..a67c498 100644
--- a/server-client.c
+++ b/server-client.c
@@ -1,4 +1,4 @@
-/* $Id: server-client.c,v 1.41 2010/09/07 13:19:53 tcunha Exp $ */
+/* $Id: server-client.c,v 1.53 2011/01/21 23:56:53 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -52,15 +52,9 @@ void
server_client_create(int fd)
{
struct client *c;
- int mode;
u_int i;
- if ((mode = fcntl(fd, F_GETFL)) == -1)
- fatal("fcntl failed");
- if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
- fatal("fcntl failed");
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
+ setblocking(fd, 0);
c = xcalloc(1, sizeof *c);
c->references = 0;
@@ -71,8 +65,6 @@ server_client_create(int fd)
fatal("gettimeofday failed");
memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time);
- ARRAY_INIT(&c->prompt_hdata);
-
c->stdin_event = NULL;
c->stdout_event = NULL;
c->stderr_event = NULL;
@@ -81,6 +73,7 @@ server_client_create(int fd)
c->title = NULL;
c->session = NULL;
+ c->last_session = NULL;
c->tty.sx = 80;
c->tty.sy = 24;
@@ -126,16 +119,22 @@ server_client_lost(struct client *c)
if (c->flags & CLIENT_TERMINAL)
tty_free(&c->tty);
- if (c->stdin_fd != -1)
+ if (c->stdin_fd != -1) {
+ setblocking(c->stdin_fd, 1);
close(c->stdin_fd);
+ }
if (c->stdin_event != NULL)
bufferevent_free(c->stdin_event);
- if (c->stdout_fd != -1)
+ if (c->stdout_fd != -1) {
+ setblocking(c->stdout_fd, 1);
close(c->stdout_fd);
+ }
if (c->stdout_event != NULL)
bufferevent_free(c->stdout_event);
- if (c->stderr_fd != -1)
+ if (c->stderr_fd != -1) {
+ setblocking(c->stderr_fd, 1);
close(c->stderr_fd);
+ }
if (c->stderr_event != NULL)
bufferevent_free(c->stderr_event);
@@ -162,9 +161,6 @@ server_client_lost(struct client *c)
xfree(c->prompt_string);
if (c->prompt_buffer != NULL)
xfree(c->prompt_buffer);
- for (i = 0; i < ARRAY_LENGTH(&c->prompt_hdata); i++)
- xfree(ARRAY_ITEM(&c->prompt_hdata, i));
- ARRAY_FREE(&c->prompt_hdata);
if (c->cwd != NULL)
xfree(c->cwd);
@@ -184,6 +180,7 @@ server_client_lost(struct client *c)
c->flags |= CLIENT_DEAD;
recalculate_sizes();
+ server_check_unattached();
server_update_socket();
}
@@ -451,10 +448,30 @@ server_client_reset_state(struct client *c)
else
tty_cursor(&c->tty, wp->xoff + s->cx, wp->yoff + s->cy);
+ /*
+ * Any mode will do for mouse-select-pane, but set standard mode if
+ * none.
+ */
mode = s->mode;
if (TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) != NULL &&
- options_get_number(oo, "mouse-select-pane"))
- mode |= MODE_MOUSE;
+ options_get_number(oo, "mouse-select-pane") &&
+ (mode & ALL_MOUSE_MODES) == 0)
+ mode |= MODE_MOUSE_STANDARD;
+
+ /*
+ * Set UTF-8 mouse input if required. If the terminal is UTF-8, the
+ * user has set mouse-utf8 and any mouse mode is in effect, turn on
+ * UTF-8 mouse input. If the receiving terminal hasn't requested it
+ * (that is, it isn't in s->mode), then it'll be converted in
+ * input_mouse.
+ */
+ if ((c->tty.flags & TTY_UTF8) &&
+ (mode & ALL_MOUSE_MODES) && options_get_number(oo, "mouse-utf8"))
+ mode |= MODE_MOUSE_UTF8;
+ else
+ mode &= ~MODE_MOUSE_UTF8;
+
+ /* Set the terminal mode and reset attributes. */
tty_update_mode(&c->tty, mode);
tty_reset(&c->tty);
}
@@ -621,6 +638,7 @@ server_client_in_callback(
return;
bufferevent_disable(c->stdin_event, EV_READ|EV_WRITE);
+ setblocking(c->stdin_fd, 1);
close(c->stdin_fd);
c->stdin_fd = -1;
@@ -636,6 +654,7 @@ server_client_out_callback(
struct client *c = data;
bufferevent_disable(c->stdout_event, EV_READ|EV_WRITE);
+ setblocking(c->stdout_fd, 1);
close(c->stdout_fd);
c->stdout_fd = -1;
}
@@ -648,6 +667,7 @@ server_client_err_callback(
struct client *c = data;
bufferevent_disable(c->stderr_event, EV_READ|EV_WRITE);
+ setblocking(c->stderr_fd, 1);
close(c->stderr_fd);
c->stderr_fd = -1;
}
@@ -661,7 +681,6 @@ server_client_msg_dispatch(struct client *c)
struct msg_identify_data identifydata;
struct msg_environ_data environdata;
ssize_t n, datalen;
- int mode;
if ((n = imsg_read(&c->ibuf)) == -1 || n == 0)
return (-1);
@@ -701,11 +720,7 @@ server_client_msg_dispatch(struct client *c)
NULL, NULL, server_client_in_callback, c);
if (c->stdin_event == NULL)
fatalx("failed to create stdin event");
-
- if ((mode = fcntl(c->stdin_fd, F_GETFL)) != -1)
- fcntl(c->stdin_fd, F_SETFL, mode|O_NONBLOCK);
- if (fcntl(c->stdin_fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
+ setblocking(c->stdin_fd, 0);
server_client_msg_identify(c, &identifydata, imsg.fd);
break;
@@ -720,11 +735,8 @@ server_client_msg_dispatch(struct client *c)
NULL, NULL, server_client_out_callback, c);
if (c->stdout_event == NULL)
fatalx("failed to create stdout event");
+ setblocking(c->stdout_fd, 0);
- if ((mode = fcntl(c->stdout_fd, F_GETFL)) != -1)
- fcntl(c->stdout_fd, F_SETFL, mode|O_NONBLOCK);
- if (fcntl(c->stdout_fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
break;
case MSG_STDERR:
if (datalen != 0)
@@ -737,11 +749,8 @@ server_client_msg_dispatch(struct client *c)
NULL, NULL, server_client_err_callback, c);
if (c->stderr_event == NULL)
fatalx("failed to create stderr event");
+ setblocking(c->stderr_fd, 0);
- if ((mode = fcntl(c->stderr_fd, F_GETFL)) != -1)
- fcntl(c->stderr_fd, F_SETFL, mode|O_NONBLOCK);
- if (fcntl(c->stderr_fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
break;
case MSG_RESIZE:
if (datalen != 0)
@@ -771,11 +780,8 @@ server_client_msg_dispatch(struct client *c)
if (gettimeofday(&c->activity_time, NULL) != 0)
fatal("gettimeofday");
- if (c->session != NULL) {
- memcpy(&c->session->activity_time,
- &c->activity_time,
- sizeof c->session->activity_time);
- }
+ if (c->session != NULL)
+ session_update_activity(c->session);
tty_start_tty(&c->tty);
server_redraw_client(c);
diff --git a/server-client.o b/server-client.o
new file mode 100644
index 0000000..5576a90
--- a/dev/null
+++ b/server-client.o
Binary files differ
diff --git a/server-fn.c b/server-fn.c
index 63b8d30..e0cc89a 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -1,4 +1,4 @@
-/* $Id: server-fn.c,v 1.110 2010/08/11 22:16:43 tcunha Exp $ */
+/* $Id: server-fn.c,v 1.118 2011/01/03 23:27:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -30,13 +30,10 @@ void server_callback_identify(int, short, void *);
void
server_fill_environ(struct session *s, struct environ *env)
{
- char tmuxvar[MAXPATHLEN], *term;
- u_int idx;
+ char tmuxvar[MAXPATHLEN], *term;
- if (session_index(s, &idx) != 0)
- fatalx("session not found");
xsnprintf(tmuxvar, sizeof tmuxvar,
- "%s,%ld,%u", socket_path, (long) getpid(), idx);
+ "%s,%ld,%u", socket_path, (long) getpid(), s->idx);
environ_set(env, "TMUX", tmuxvar);
term = options_get_string(&s->options, "default-terminal");
@@ -175,7 +172,6 @@ void
server_status_window(struct window *w)
{
struct session *s;
- u_int i;
/*
* This is slightly different. We want to redraw the status line of any
@@ -183,9 +179,8 @@ server_status_window(struct window *w)
* current window.
*/
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s != NULL && session_has(s, w) != NULL)
+ RB_FOREACH(s, sessions, &sessions) {
+ if (session_has(s, w) != NULL)
server_status_session(s);
}
}
@@ -244,13 +239,15 @@ server_lock_client(struct client *c)
void
server_kill_window(struct window *w)
{
- struct session *s;
+ struct session *s, *next_s;
struct winlink *wl;
- u_int i;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s == NULL || session_has(s, w) == NULL)
+ next_s = RB_MIN(sessions, &sessions);
+ while (next_s != NULL) {
+ s = next_s;
+ next_s = RB_NEXT(sessions, &sessions, s);
+
+ if (session_has(s, w) == NULL)
continue;
while ((wl = winlink_find_by_window(&s->windows, w)) != NULL) {
if (session_detach(s, wl)) {
@@ -280,8 +277,10 @@ server_link_window(struct session *src, struct winlink *srcwl,
if (dstidx != -1)
dstwl = winlink_find_by_index(&dst->windows, dstidx);
if (dstwl != NULL) {
- if (dstwl->window == srcwl->window)
+ if (dstwl->window == srcwl->window) {
+ xasprintf(cause, "same index: %d", dstidx);
return (-1);
+ }
if (killflag) {
/*
* Can't use session_detach as it will destroy session
@@ -363,11 +362,9 @@ struct session *
server_next_session(struct session *s)
{
struct session *s_loop, *s_out;
- u_int i;
s_out = NULL;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s_loop = ARRAY_ITEM(&sessions, i);
+ RB_FOREACH(s_loop, sessions, &sessions) {
if (s_loop == s)
continue;
if (s_out == NULL ||
@@ -397,7 +394,9 @@ server_destroy_session(struct session *s)
c->session = NULL;
c->flags |= CLIENT_EXIT;
} else {
+ c->last_session = NULL;
c->session = s_new;
+ session_update_activity(s_new);
server_redraw_client(c);
}
}
@@ -405,6 +404,23 @@ server_destroy_session(struct session *s)
}
void
+server_check_unattached (void)
+{
+ struct session *s;
+
+ /*
+ * If any sessions are no longer attached and have destroy-unattached
+ * set, collect them.
+ */
+ RB_FOREACH(s, sessions, &sessions) {
+ if (!(s->flags & SESSION_UNATTACHED))
+ continue;
+ if (options_get_number (&s->options, "destroy-unattached"))
+ session_destroy(s);
+ }
+}
+
+void
server_set_identify(struct client *c)
{
struct timeval tv;
diff --git a/server-fn.o b/server-fn.o
new file mode 100644
index 0000000..a8565cc
--- a/dev/null
+++ b/server-fn.o
Binary files differ
diff --git a/server-window.c b/server-window.c
index 713c8cb..389094b 100644
--- a/server-window.c
+++ b/server-window.c
@@ -1,4 +1,4 @@
-/* $Id: server-window.c,v 1.17 2010/08/11 22:16:03 tcunha Exp $ */
+/* $Id: server-window.c,v 1.19 2010/12/22 15:36:44 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -26,6 +26,7 @@
int server_window_backoff(struct window_pane *);
int server_window_check_bell(struct session *, struct winlink *);
int server_window_check_activity(struct session *, struct winlink *);
+int server_window_check_silence(struct session *, struct winlink *);
int server_window_check_content(
struct session *, struct winlink *, struct window_pane *);
@@ -37,23 +38,21 @@ server_window_loop(void)
struct winlink *wl;
struct window_pane *wp;
struct session *s;
- u_int i, j;
+ u_int i;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
w = ARRAY_ITEM(&windows, i);
if (w == NULL)
continue;
- for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
- s = ARRAY_ITEM(&sessions, j);
- if (s == NULL)
- continue;
+ RB_FOREACH(s, sessions, &sessions) {
wl = session_has(s, w);
if (wl == NULL)
continue;
if (server_window_check_bell(s, wl) ||
- server_window_check_activity(s, wl))
+ server_window_check_activity(s, wl) ||
+ server_window_check_silence(s, wl))
server_status_session(s);
TAILQ_FOREACH(wp, &w->panes, entry)
server_window_check_content(s, wl, wp);
@@ -151,6 +150,55 @@ server_window_check_activity(struct session *s, struct winlink *wl)
return (1);
}
+/* Check for silence in window. */
+int
+server_window_check_silence(struct session *s, struct winlink *wl)
+{
+ struct client *c;
+ struct window *w = wl->window;
+ struct timeval timer;
+ u_int i;
+ int silence_interval, timer_difference;
+
+ if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
+ return (0);
+
+ if (s->curw == wl) {
+ /*
+ * Reset the timer for this window if we've focused it. We
+ * don't want the timer tripping as soon as we've switched away
+ * from this window.
+ */
+ if (gettimeofday(&w->silence_timer, NULL) != 0)
+ fatal("gettimeofday failed.");
+
+ return (0);
+ }
+
+ silence_interval = options_get_number(&w->options, "monitor-silence");
+ if (silence_interval == 0)
+ return (0);
+
+ if (gettimeofday(&timer, NULL) != 0)
+ fatal("gettimeofday");
+ timer_difference = timer.tv_sec - w->silence_timer.tv_sec;
+ if (timer_difference <= silence_interval)
+ return (0);
+ wl->flags |= WINLINK_SILENCE;
+
+ if (options_get_number(&s->options, "visual-silence")) {
+ for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+ c = ARRAY_ITEM(&clients, i);
+ if (c == NULL || c->session != s)
+ continue;
+ status_message_set(c, "Silence in window %u",
+ winlink_find_by_window(&s->windows, w)->idx);
+ }
+ }
+
+ return (1);
+}
+
/* Check for content change in window. */
int
server_window_check_content(
diff --git a/server-window.o b/server-window.o
new file mode 100644
index 0000000..471b3bf
--- a/dev/null
+++ b/server-window.o
Binary files differ
diff --git a/server.c b/server.c
index fc9390a..4206c6b 100644
--- a/server.c
+++ b/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c,v 1.243 2010/08/29 14:42:11 tcunha Exp $ */
+/* $Id: server.c,v 1.252 2011/01/21 23:44:13 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -50,6 +50,8 @@ int server_shutdown;
struct event server_ev_accept;
struct event server_ev_second;
+struct paste_stack global_buffers;
+
int server_create_socket(void);
void server_loop(void);
int server_should_shutdown(void);
@@ -71,7 +73,7 @@ server_create_socket(void)
struct sockaddr_un sa;
size_t size;
mode_t mask;
- int fd, mode;
+ int fd;
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
@@ -92,13 +94,7 @@ server_create_socket(void)
if (listen(fd, 16) == -1)
fatal("listen failed");
-
- if ((mode = fcntl(fd, F_GETFL)) == -1)
- fatal("fcntl failed");
- if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
- fatal("fcntl failed");
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
+ setblocking(fd, 0);
server_update_socket();
@@ -107,16 +103,13 @@ server_create_socket(void)
/* Fork new server. */
int
-server_start(char *path)
+server_start(void)
{
struct window_pane *wp;
int pair[2];
char *cause;
struct timeval tv;
u_int i;
-#ifdef HAVE_SETPROCTITLE
- char rpathbuf[MAXPATHLEN];
-#endif
/* The first client is special and gets a socketpair; create it. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
@@ -151,21 +144,18 @@ server_start(char *path)
ARRAY_INIT(&windows);
ARRAY_INIT(&clients);
ARRAY_INIT(&dead_clients);
- ARRAY_INIT(&sessions);
- ARRAY_INIT(&dead_sessions);
+ RB_INIT(&sessions);
+ RB_INIT(&dead_sessions);
TAILQ_INIT(&session_groups);
+ ARRAY_INIT(&global_buffers);
mode_key_init_trees();
key_bindings_init();
utf8_build();
start_time = time(NULL);
- socket_path = path;
-
-#ifdef HAVE_SETPROCTITLE
- if (realpath(socket_path, rpathbuf) == NULL)
- strlcpy(rpathbuf, socket_path, sizeof rpathbuf);
log_debug("socket path %s", socket_path);
- setproctitle("server (%s)", rpathbuf);
+#ifdef HAVE_SETPROCTITLE
+ setproctitle("server (%s)", socket_path);
#endif
server_fd = server_create_socket();
@@ -184,8 +174,8 @@ server_start(char *path)
* If there is a session already, put the current window and pane into
* more mode.
*/
- if (!ARRAY_EMPTY(&sessions) && !ARRAY_EMPTY(&cfg_causes)) {
- wp = ARRAY_FIRST(&sessions)->curw->window->active;
+ if (!RB_EMPTY(&sessions) && !ARRAY_EMPTY(&cfg_causes)) {
+ wp = RB_MIN(sessions, &sessions)->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
@@ -226,14 +216,14 @@ server_loop(void)
}
}
-/* Check if the server should be shutting down (no more clients or windows). */
+/* Check if the server should be shutting down (no more clients or sessions). */
int
server_should_shutdown(void)
{
u_int i;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if (ARRAY_ITEM(&sessions, i) != NULL)
+ if (!options_get_number(&global_options, "exit-unattached")) {
+ if (!RB_EMPTY(&sessions))
return (0);
}
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -248,7 +238,7 @@ void
server_send_shutdown(void)
{
struct client *c;
- struct session *s;
+ struct session *s, *next_s;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -262,9 +252,11 @@ server_send_shutdown(void)
}
}
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if ((s = ARRAY_ITEM(&sessions, i)) != NULL)
- session_destroy(s);
+ s = RB_MIN(sessions, &sessions);
+ while (s != NULL) {
+ next_s = RB_NEXT(sessions, &sessions, s);
+ session_destroy(s);
+ s = next_s;
}
}
@@ -272,16 +264,19 @@ server_send_shutdown(void)
void
server_clean_dead(void)
{
- struct session *s;
+ struct session *s, *next_s;
struct client *c;
u_int i;
- for (i = 0; i < ARRAY_LENGTH(&dead_sessions); i++) {
- s = ARRAY_ITEM(&dead_sessions, i);
- if (s == NULL || s->references != 0)
- continue;
- ARRAY_SET(&dead_sessions, i, NULL);
- xfree(s);
+ s = RB_MIN(sessions, &dead_sessions);
+ while (s != NULL) {
+ next_s = RB_NEXT(sessions, &dead_sessions, s);
+ if (s->references == 0) {
+ RB_REMOVE(sessions, &dead_sessions, s);
+ xfree(s->name);
+ xfree(s);
+ }
+ s = next_s;
}
for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
@@ -298,14 +293,13 @@ void
server_update_socket(void)
{
struct session *s;
- u_int i;
static int last = -1;
- int n;
+ int n, mode;
+ struct stat sb;
n = 0;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s != NULL && !(s->flags & SESSION_UNATTACHED)) {
+ RB_FOREACH(s, sessions, &sessions) {
+ if (!(s->flags & SESSION_UNATTACHED)) {
n++;
break;
}
@@ -313,10 +307,20 @@ server_update_socket(void)
if (n != last) {
last = n;
- if (n != 0)
- chmod(socket_path, S_IRWXU|S_IRWXG);
- else
- chmod(socket_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
+
+ if (stat(socket_path, &sb) != 0)
+ return;
+ mode = sb.st_mode;
+ if (n != 0) {
+ if (mode & S_IRUSR)
+ mode |= S_IXUSR;
+ if (mode & S_IRGRP)
+ mode |= S_IXGRP;
+ if (mode & S_IROTH)
+ mode |= S_IXOTH;
+ } else
+ mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+ chmod(socket_path, mode);
}
}
@@ -482,21 +486,13 @@ void
server_lock_server(void)
{
struct session *s;
- u_int i;
int timeout;
time_t t;
t = time(NULL);
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
- continue;
-
- if (s->flags & SESSION_UNATTACHED) {
- if (gettimeofday(&s->activity_time, NULL) != 0)
- fatal("gettimeofday failed");
+ RB_FOREACH(s, sessions, &sessions) {
+ if (s->flags & SESSION_UNATTACHED)
continue;
- }
-
timeout = options_get_number(&s->options, "lock-after-time");
if (timeout <= 0 || t <= s->activity_time.tv_sec + timeout)
return; /* not timed out */
@@ -511,21 +507,13 @@ void
server_lock_sessions(void)
{
struct session *s;
- u_int i;
int timeout;
time_t t;
t = time(NULL);
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
- continue;
-
- if (s->flags & SESSION_UNATTACHED) {
- if (gettimeofday(&s->activity_time, NULL) != 0)
- fatal("gettimeofday failed");
+ RB_FOREACH(s, sessions, &sessions) {
+ if (s->flags & SESSION_UNATTACHED)
continue;
- }
-
timeout = options_get_number(&s->options, "lock-after-time");
if (timeout > 0 && t > s->activity_time.tv_sec + timeout) {
server_lock_session(s);
diff --git a/server.o b/server.o
new file mode 100644
index 0000000..f77e7ca
--- a/dev/null
+++ b/server.o
Binary files differ
diff --git a/session.c b/session.c
index 6869ebb..7c2b991 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $Id: session.c,v 1.78 2010/09/10 13:36:17 tcunha Exp $ */
+/* $Id: session.c,v 1.87 2011/01/21 23:53:01 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -29,24 +29,56 @@
/* Global session list. */
struct sessions sessions;
struct sessions dead_sessions;
+u_int next_session;
struct session_groups session_groups;
struct winlink *session_next_alert(struct winlink *);
struct winlink *session_previous_alert(struct winlink *);
+RB_GENERATE(sessions, session, entry, session_cmp);
+
+int
+session_cmp(struct session *s1, struct session *s2)
+{
+ return (strcmp(s1->name, s2->name));
+}
+
+/*
+ * Find if session is still alive. This is true if it is still on the global
+ * sessions list.
+ */
+int
+session_alive(struct session *s)
+{
+ struct session *s_loop;
+
+ RB_FOREACH(s_loop, sessions, &sessions) {
+ if (s_loop == s)
+ return (1);
+ }
+ return (0);
+}
+
/* Find session by name. */
struct session *
session_find(const char *name)
{
+ struct session s;
+
+ s.name = (char *) name;
+ return (RB_FIND(sessions, &sessions, &s));
+}
+
+/* Find session by index. */
+struct session *
+session_find_by_index(u_int idx)
+{
struct session *s;
- u_int i;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s != NULL && strcmp(s->name, name) == 0)
+ RB_FOREACH(s, sessions, &sessions) {
+ if (s->idx == idx)
return (s);
}
-
return (NULL);
}
@@ -57,7 +89,6 @@ session_create(const char *name, const char *cmd, const char *cwd,
char **cause)
{
struct session *s;
- u_int i;
s = xmalloc(sizeof *s);
s->references = 0;
@@ -65,7 +96,7 @@ session_create(const char *name, const char *cmd, const char *cwd,
if (gettimeofday(&s->creation_time, NULL) != 0)
fatal("gettimeofday failed");
- memcpy(&s->activity_time, &s->creation_time, sizeof s->activity_time);
+ session_update_activity(s);
s->cwd = xstrdup(cwd);
@@ -73,8 +104,6 @@ session_create(const char *name, const char *cmd, const char *cwd,
TAILQ_INIT(&s->lastw);
RB_INIT(&s->windows);
- paste_init_stack(&s->buffers);
-
options_init(&s->options, &global_s_options);
environ_init(&s->environ);
if (env != NULL)
@@ -89,19 +118,12 @@ session_create(const char *name, const char *cmd, const char *cwd,
s->sx = sx;
s->sy = sy;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if (ARRAY_ITEM(&sessions, i) == NULL) {
- ARRAY_SET(&sessions, i, s);
- break;
- }
- }
- if (i == ARRAY_LENGTH(&sessions))
- ARRAY_ADD(&sessions, s);
-
+ s->idx = next_session++;
if (name != NULL)
s->name = xstrdup(name);
else
- xasprintf(&s->name, "%u", i);
+ xasprintf(&s->name, "%u", s->idx);
+ RB_INSERT(sessions, &sessions, s);
if (cmd != NULL) {
if (session_new(s, NULL, cmd, cwd, idx, cause) == NULL) {
@@ -120,15 +142,9 @@ session_create(const char *name, const char *cmd, const char *cwd,
void
session_destroy(struct session *s)
{
- u_int i;
-
log_debug("session %s destroyed", s->name);
- if (session_index(s, &i) != 0)
- fatalx("session not found");
- ARRAY_SET(&sessions, i, NULL);
- while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL)
- ARRAY_TRUNC(&sessions, 1);
+ RB_REMOVE(sessions, &sessions, s);
if (s->tio != NULL)
xfree(s->tio);
@@ -136,7 +152,6 @@ session_destroy(struct session *s)
session_group_remove(s);
environ_free(&s->environ);
options_free(&s->options);
- paste_free_stack(&s->buffers);
while (!TAILQ_EMPTY(&s->lastw))
winlink_stack_remove(&s->lastw, TAILQ_FIRST(&s->lastw));
@@ -144,28 +159,16 @@ session_destroy(struct session *s)
winlink_remove(&s->windows, RB_ROOT(&s->windows));
xfree(s->cwd);
- xfree(s->name);
- for (i = 0; i < ARRAY_LENGTH(&dead_sessions); i++) {
- if (ARRAY_ITEM(&dead_sessions, i) == NULL) {
- ARRAY_SET(&dead_sessions, i, s);
- break;
- }
- }
- if (i == ARRAY_LENGTH(&dead_sessions))
- ARRAY_ADD(&dead_sessions, s);
- s->flags |= SESSION_DEAD;
+ RB_INSERT(sessions, &dead_sessions, s);
}
-/* Find session index. */
-int
-session_index(struct session *s, u_int *i)
+/* Update session active time. */
+void
+session_update_activity(struct session *s)
{
- for (*i = 0; *i < ARRAY_LENGTH(&sessions); (*i)++) {
- if (s == ARRAY_ITEM(&sessions, *i))
- return (0);
- }
- return (-1);
+ if (gettimeofday(&s->activity_time, NULL) != 0)
+ fatal("gettimeofday");
}
/* Find the next usable session. */
@@ -173,19 +176,15 @@ struct session *
session_next_session(struct session *s)
{
struct session *s2;
- u_int i;
- if (ARRAY_LENGTH(&sessions) == 0 || session_index(s, &i) != 0)
+ if (RB_EMPTY(&sessions) || !session_alive(s))
return (NULL);
- do {
- if (i == ARRAY_LENGTH(&sessions) - 1)
- i = 0;
- else
- i++;
- s2 = ARRAY_ITEM(&sessions, i);
- } while (s2 == NULL || s2->flags & SESSION_DEAD);
-
+ s2 = RB_NEXT(sessions, &sessions, s);
+ if (s2 == NULL)
+ s2 = RB_MIN(sessions, &sessions);
+ if (s2 == s)
+ return (NULL);
return (s2);
}
@@ -194,19 +193,15 @@ struct session *
session_previous_session(struct session *s)
{
struct session *s2;
- u_int i;
- if (ARRAY_LENGTH(&sessions) == 0 || session_index(s, &i) != 0)
+ if (RB_EMPTY(&sessions) || !session_alive(s))
return (NULL);
- do {
- if (i == 0)
- i = ARRAY_LENGTH(&sessions) - 1;
- else
- i--;
- s2 = ARRAY_ITEM(&sessions, i);
- } while (s2 == NULL || s2->flags & SESSION_DEAD);
-
+ s2 = RB_PREV(sessions, &sessions, s);
+ if (s2 == NULL)
+ s2 = RB_MAX(sessions, &sessions);
+ if (s2 == s)
+ return (NULL);
return (s2);
}
diff --git a/session.o b/session.o
new file mode 100644
index 0000000..fd875fe
--- a/dev/null
+++ b/session.o
Binary files differ
diff --git a/signal.o b/signal.o
new file mode 100644
index 0000000..be40490
--- a/dev/null
+++ b/signal.o
Binary files differ
diff --git a/status.c b/status.c
index dbc1d26..dd0078a 100644
--- a/status.c
+++ b/status.c
@@ -1,4 +1,4 @@
-/* $Id: status.c,v 1.149 2010/06/22 23:26:18 tcunha Exp $ */
+/* $Id: status.c,v 1.155 2011/01/07 16:55:40 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -41,9 +41,14 @@ void status_replace1(struct client *,
struct winlink *, char **, char **, char *, size_t, int);
void status_message_callback(int, short, void *);
-void status_prompt_add_history(struct client *);
+const char *status_prompt_up_history(u_int *);
+const char *status_prompt_down_history(u_int *);
+void status_prompt_add_history(const char *);
char *status_prompt_complete(const char *);
+/* Status prompt history. */
+ARRAY_DECL(, char *) status_prompt_history = ARRAY_INITIALIZER;
+
/* Retrieve options for left string. */
char *
status_redraw_get_left(struct client *c,
@@ -388,19 +393,8 @@ status_replace1(struct client *c,struct winlink *wl,
ptr = wl->window->name;
goto do_replace;
case 'F':
- tmp[0] = ' ';
- if (wl->flags & WINLINK_CONTENT)
- tmp[0] = '+';
- else if (wl->flags & WINLINK_BELL)
- tmp[0] = '!';
- else if (wl->flags & WINLINK_ACTIVITY)
- tmp[0] = '#';
- else if (wl == s->curw)
- tmp[0] = '*';
- else if (wl == TAILQ_FIRST(&s->lastw))
- tmp[0] = '-';
- tmp[1] = '\0';
- ptr = tmp;
+ ptr = window_printable_flags(s, wl);
+ freeptr = ptr;
goto do_replace;
case '[':
/*
@@ -462,7 +456,7 @@ status_replace(struct client *c,
break;
ch = *iptr++;
- if (ch != '#') {
+ if (ch != '#' || *iptr == '\0') {
*optr++ = ch;
continue;
}
@@ -858,6 +852,7 @@ status_prompt_key(struct client *c, int key)
{
struct paste_buffer *pb;
char *s, *first, *last, word[64], swapc;
+ const char *histstr;
u_char ch;
size_t size, n, off, idx;
@@ -970,34 +965,25 @@ status_prompt_key(struct client *c, int key)
}
break;
case MODEKEYEDIT_HISTORYUP:
- if (ARRAY_LENGTH(&c->prompt_hdata) == 0)
+ histstr = status_prompt_up_history(&c->prompt_hindex);
+ if (histstr == NULL)
break;
xfree(c->prompt_buffer);
-
- c->prompt_buffer = xstrdup(ARRAY_ITEM(&c->prompt_hdata,
- ARRAY_LENGTH(&c->prompt_hdata) - 1 - c->prompt_hindex));
- if (c->prompt_hindex != ARRAY_LENGTH(&c->prompt_hdata) - 1)
- c->prompt_hindex++;
-
+ c->prompt_buffer = xstrdup(histstr);
c->prompt_index = strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_HISTORYDOWN:
+ histstr = status_prompt_down_history(&c->prompt_hindex);
+ if (histstr == NULL)
+ break;
xfree(c->prompt_buffer);
-
- if (c->prompt_hindex != 0) {
- c->prompt_hindex--;
- c->prompt_buffer = xstrdup(ARRAY_ITEM(
- &c->prompt_hdata, ARRAY_LENGTH(
- &c->prompt_hdata) - 1 - c->prompt_hindex));
- } else
- c->prompt_buffer = xstrdup("");
-
+ c->prompt_buffer = xstrdup(histstr);
c->prompt_index = strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
case MODEKEYEDIT_PASTE:
- if ((pb = paste_get_top(&c->session->buffers)) == NULL)
+ if ((pb = paste_get_top(&global_buffers)) == NULL)
break;
for (n = 0; n < pb->size; n++) {
ch = (u_char) pb->data[n];
@@ -1034,7 +1020,7 @@ status_prompt_key(struct client *c, int key)
break;
case MODEKEYEDIT_ENTER:
if (*c->prompt_buffer != '\0')
- status_prompt_add_history(c);
+ status_prompt_add_history(c->prompt_buffer);
if (c->prompt_callbackfn(c->prompt_data, c->prompt_buffer) == 0)
status_prompt_clear(c);
break;
@@ -1070,32 +1056,68 @@ status_prompt_key(struct client *c, int key)
}
}
+/* Get previous line from the history. */
+const char *
+status_prompt_up_history(u_int *idx)
+{
+ u_int size;
+
+ /*
+ * History runs from 0 to size - 1.
+ *
+ * Index is from 0 to size. Zero is empty.
+ */
+
+ size = ARRAY_LENGTH(&status_prompt_history);
+ if (size == 0 || *idx == size)
+ return (NULL);
+ (*idx)++;
+ return (ARRAY_ITEM(&status_prompt_history, size - *idx));
+}
+
+/* Get next line from the history. */
+const char *
+status_prompt_down_history(u_int *idx)
+{
+ u_int size;
+
+ size = ARRAY_LENGTH(&status_prompt_history);
+ if (size == 0 || *idx == 0)
+ return ("");
+ (*idx)--;
+ if (*idx == 0)
+ return ("");
+ return (ARRAY_ITEM(&status_prompt_history, size - *idx));
+}
+
/* Add line to the history. */
void
-status_prompt_add_history(struct client *c)
+status_prompt_add_history(const char *line)
{
- if (ARRAY_LENGTH(&c->prompt_hdata) > 0 &&
- strcmp(ARRAY_LAST(&c->prompt_hdata), c->prompt_buffer) == 0)
+ u_int size;
+
+ size = ARRAY_LENGTH(&status_prompt_history);
+ if (size > 0 && strcmp(ARRAY_LAST(&status_prompt_history), line) == 0)
return;
- if (ARRAY_LENGTH(&c->prompt_hdata) == PROMPT_HISTORY) {
- xfree(ARRAY_FIRST(&c->prompt_hdata));
- ARRAY_REMOVE(&c->prompt_hdata, 0);
+ if (size == PROMPT_HISTORY) {
+ xfree(ARRAY_FIRST(&status_prompt_history));
+ ARRAY_REMOVE(&status_prompt_history, 0);
}
- ARRAY_ADD(&c->prompt_hdata, xstrdup(c->prompt_buffer));
+ ARRAY_ADD(&status_prompt_history, xstrdup(line));
}
/* Complete word. */
char *
status_prompt_complete(const char *s)
{
- const struct cmd_entry **cmdent;
- const struct set_option_entry *entry;
- ARRAY_DECL(, const char *) list;
- char *prefix, *s2;
- u_int i;
- size_t j;
+ const struct cmd_entry **cmdent;
+ const struct options_table_entry *oe;
+ ARRAY_DECL(, const char *) list;
+ char *prefix, *s2;
+ u_int i;
+ size_t j;
if (*s == '\0')
return (NULL);
@@ -1106,17 +1128,17 @@ status_prompt_complete(const char *s)
if (strncmp((*cmdent)->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, (*cmdent)->name);
}
- for (entry = set_option_table; entry->name != NULL; entry++) {
- if (strncmp(entry->name, s, strlen(s)) == 0)
- ARRAY_ADD(&list, entry->name);
+ for (oe = server_options_table; oe->name != NULL; oe++) {
+ if (strncmp(oe->name, s, strlen(s)) == 0)
+ ARRAY_ADD(&list, oe->name);
}
- for (entry = set_session_option_table; entry->name != NULL; entry++) {
- if (strncmp(entry->name, s, strlen(s)) == 0)
- ARRAY_ADD(&list, entry->name);
+ for (oe = session_options_table; oe->name != NULL; oe++) {
+ if (strncmp(oe->name, s, strlen(s)) == 0)
+ ARRAY_ADD(&list, oe->name);
}
- for (entry = set_window_option_table; entry->name != NULL; entry++) {
- if (strncmp(entry->name, s, strlen(s)) == 0)
- ARRAY_ADD(&list, entry->name);
+ for (oe = window_options_table; oe->name != NULL; oe++) {
+ if (strncmp(oe->name, s, strlen(s)) == 0)
+ ARRAY_ADD(&list, oe->name);
}
/* If none, bail now. */
diff --git a/status.o b/status.o
new file mode 100644
index 0000000..2b5c1e4
--- a/dev/null
+++ b/status.o
Binary files differ
diff --git a/tmux b/tmux
new file mode 100755
index 0000000..9e01849
--- a/dev/null
+++ b/tmux
Binary files differ
diff --git a/tmux.1 b/tmux.1
index 4983864..caf86a6 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1,4 +1,4 @@
-.\" $Id: tmux.1,v 1.265 2010/09/10 13:36:17 tcunha Exp $
+.\" $Id: tmux.1,v 1.295 2011/01/21 23:55:26 tcunha Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <[email protected]>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 8 2010 $
+.Dd $Mdocdate: December 10 2010 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -23,7 +23,7 @@
.Sh SYNOPSIS
.Nm tmux
.Bk -words
-.Op Fl 28lquv
+.Op Fl 28lquvV
.Op Fl c Ar shell-command
.Op Fl f Ar file
.Op Fl L Ar socket-name
@@ -134,7 +134,10 @@ will report an error and exit without executing further commands.
.It Fl L Ar socket-name
.Nm
stores the server socket in a directory under
-.Pa /tmp ;
+.Pa /tmp
+(or
+.Ev TMPDIR
+if set);
the default socket is named
.Em default .
This option allows a different socket name to be specified, allowing several
@@ -198,6 +201,10 @@ and
files in the current directory, where
.Em PID
is the PID of the server or client process.
+.It Fl V
+Report the
+.Nm
+version.
.It Ar command Op Ar flags
This specifies one of a set of commands used to control
.Nm ,
@@ -248,6 +255,8 @@ Select windows 0 to 9.
Enter the
.Nm
command prompt.
+.It ;
+Move to the previously active pane.
.It =
Choose which buffer to paste interactively from a list.
.It \&?
@@ -280,6 +289,8 @@ Briefly display pane indexes.
Force redraw of the attached client.
.It s
Select a new session for the attached client interactively.
+.It L
+Switch the attached client back to the last session.
.It t
Show the time.
.It w
@@ -507,7 +518,7 @@ when they are created with the
command, or later with the
.Ic attach-session
command.
-Each session has one of more windows
+Each session has one or more windows
.Em linked
into it.
Windows may be linked to multiple sessions and are made up of one or
@@ -584,6 +595,8 @@ Lock all clients attached to
.Op Fl n Ar window-name
.Op Fl s Ar session-name
.Op Fl t Ar target-session
+.Op Fl x Ar width
+.Op Fl y Ar height
.Op Ar shell-command
.Xc
.D1 (alias: Ic new )
@@ -597,6 +610,13 @@ is given.
and
.Ar shell-command
are the name of and shell command to execute in the initial window.
+If
+.Fl d
+is used,
+.Fl x
+and
+.Fl y
+specify the size of the initial window (80 by 24 if not given).
.Pp
If run from a terminal, any
.Xr termios 4
@@ -653,14 +673,14 @@ Start the
.Nm
server, if not already running, without creating any sessions.
.It Xo Ic suspend-client
-.Op Fl c Ar target-client
+.Op Fl t Ar target-client
.Xc
.D1 (alias: Ic suspendc )
Suspend a client by sending
.Dv SIGTSTP
(tty stop).
.It Xo Ic switch-client
-.Op Fl np
+.Op Fl lnp
.Op Fl c Ar target-client
.Op Fl t Ar target-session
.Xc
@@ -670,10 +690,12 @@ Switch the current session for client
to
.Ar target-session .
If
+.Fl l ,
.Fl n
or
.Fl p
-is used, the client is moved to the next or previous session respectively.
+is used, the client is moved to the last, next or previous session
+respectively.
.El
.Sh WINDOWS AND PANES
A
@@ -896,6 +918,7 @@ $ tmux list-windows
layout: bb62,159x48,0,0{79x48,0,0,79x48,80,0}
$ tmux select-layout bb62,159x48,0,0{79x48,0,0,79x48,80,0}
.Ed
+.Pp
.Nm
automatically adjusts the size of the layout for the current window size.
Note that a layout cannot be applied to a window with more panes than that
@@ -1037,6 +1060,9 @@ option kills all but the pane given with
Kill the current window or the window at
.Ar target-window ,
removing it from any sessions to which it is linked.
+.It Ic last-pane Op Fl t Ar target-window
+.D1 (alias: Ic lastp )
+Select the last (previously selected) pane.
.It Ic last-window Op Fl t Ar target-session
.D1 (alias: Ic last )
Select the last (previously selected) window.
@@ -1087,7 +1113,7 @@ except the window at
is moved to
.Ar dst-window .
.It Xo Ic new-window
-.Op Fl adk
+.Op Fl adkP
.Op Fl n Ar window-name
.Op Fl t Ar target-window
.Op Ar shell-command
@@ -1135,6 +1161,10 @@ New windows will automatically have
.Dq TERM=screen
added to their environment, but care must be taken not to reset this in shell
start-up files.
+.Pp
+The
+.Fl P
+option prints the location of the new window after it has been created.
.It Ic next-layout Op Fl t Ar target-window
.D1 (alias: Ic nextl )
Move a window to the next layout and rearrange the panes to fit.
@@ -1241,6 +1271,7 @@ lower) with
.Fl U
or downward (numerically higher).
.It Xo Ic select-layout
+.Op Fl np
.Op Fl t Ar target-window
.Op Ar layout-name
.Xc
@@ -1249,8 +1280,16 @@ Choose a specific layout for a window.
If
.Ar layout-name
is not given, the last preset layout used (if any) is reapplied.
+.Fl n
+and
+.Fl p
+are equivalent to the
+.Ic next-layout
+and
+.Ic previous-layout
+commands.
.It Xo Ic select-pane
-.Op Fl DLRU
+.Op Fl lDLRU
.Op Fl t Ar target-pane
.Xc
.D1 (alias: Ic selectp )
@@ -1266,12 +1305,29 @@ or
.Fl U
is used, respectively the pane below, to the left, to the right, or above the
target pane is used.
-.It Ic select-window Op Fl t Ar target-window
+.Fl l
+is the same as using the
+.Ic last-pane
+command.
+.It Xo Ic select-window
+.Op Fl lnp
+.Op Fl t Ar target-window
+.Xc
.D1 (alias: Ic selectw )
Select the window at
.Ar target-window .
+.Fl l ,
+.Fl n
+and
+.Fl p
+are equivalent to the
+.Ic last-window ,
+.Ic next-window
+and
+.Ic previous-window
+commands.
.It Xo Ic split-window
-.Op Fl dhv
+.Op Fl dhvP
.Oo Fl l
.Ar size |
.Fl p Ar percentage Oc
@@ -1474,7 +1530,7 @@ All arguments are sent sequentially from first to last.
Send the prefix key to a window as if it was pressed.
If multiple prefix keys are configured, only the first is sent.
.It Xo Ic unbind-key
-.Op Fl cn
+.Op Fl acn
.Op Fl t Ar key-table
.Ar key
.Xc
@@ -1488,6 +1544,9 @@ the primary key bindings are modified; in this case, if
is specified, the command bound to
.Ar key
without a prefix (if any) is removed.
+If
+.Fl a
+is present, all key bindings are removed.
.Pp
If
.Fl t
@@ -1581,18 +1640,23 @@ Available window options are listed under
.Pp
Available server options are:
.Bl -tag -width Ds
-.It Ic detach-on-destroy
-If on (the default), the client is detached when the session it is attached to
-is destroyed.
-If off, the client is switched to the most recently active of the remaining
-sessions.
-.It Ic escape-time
+.It Ic buffer-limit Ar number
+Set the number of buffers; as new buffers are added to the top of the stack,
+old ones are removed from the bottom if necessary to maintain this maximum
+length.
+.It Ic escape-time Ar time
Set the time in milliseconds for which
.Nm
waits after an escape is input to determine if it is part of a function or meta
key sequences.
The default is 500 milliseconds.
-.It Ic quiet
+.It Xo Ic exit-unattached
+.Op Ic on | off
+.Xc
+If enabled, the server will exit when there are no attached clients.
+.It Xo Ic quiet
+.Op Ic on | off
+.Xc
Enable or disable the display of various informational messages (see also the
.Fl q
command line flag).
@@ -1615,10 +1679,6 @@ window of that session,
means all bells are ignored and
.Ic current
means only bell in windows other than the current window are ignored.
-.It Ic buffer-limit Ar number
-Set the number of buffers kept for each session; as new buffers are added to
-the top of the stack, old ones are removed from the bottom if necessary to
-maintain this maximum length.
.It Ic default-command Ar shell-command
Set the command used for new windows (if not specified when the window is
created) to
@@ -1631,6 +1691,11 @@ The default is an empty string, which instructs
to create a login shell using the value of the
.Ic default-shell
option.
+.It Ic default-path Ar path
+Set the default working directory for processes created from keys, or
+interactively from the prompt.
+The default is empty, which means to use the working directory of the shell
+from which the server was started if it is available or the user's home if not.
.It Ic default-shell Ar path
Specify the default shell.
This is used as the login shell for new windows when the
@@ -1647,11 +1712,6 @@ or
This option should be configured when
.Nm
is used as a login shell.
-.It Ic default-path Ar path
-Set the default working directory for processes created from keys, or
-interactively from the prompt.
-The default is empty, which means to use the working directory of the shell
-from which the server was started if it is available or the user's home if not.
.It Ic default-terminal Ar terminal
Set the default terminal for new windows created in this session - the
default value of the
@@ -1664,6 +1724,18 @@ to work correctly, this
be set to
.Ql screen
or a derivative of it.
+.It Xo Ic destroy-unattached
+.Op Ic on | off
+.Xc
+If enabled and the session is no longer attached to any clients, it is
+destroyed.
+.It Xo Ic detach-on-destroy
+.Op Ic on | off
+.Xc
+If on (the default), the client is detached when the session it is attached to
+is destroyed.
+If off, the client is switched to the most recently active of the remaining
+sessions.
.It Ic display-panes-active-colour Ar colour
Set the colour used by the
.Ic display-panes
@@ -1744,8 +1816,11 @@ is one of:
.Ic colour0
to
.Ic colour255
-from the 256-colour palette, or
-.Ic default .
+from the 256-colour set,
+.Ic default ,
+or a hexadecimal RGB string such as
+.Ql #ffffff ,
+which chooses the closest match from the default 256-colour set.
.It Ic message-fg Ar colour
Set status line message foreground colour.
.It Ic message-limit Ar number
@@ -1760,12 +1835,12 @@ If on,
captures the mouse and when a window is split into multiple panes the mouse may
be used to select the current pane.
The mouse click is also passed through to the application as normal.
-.It Ic pane-border-fg Ar colour
-.It Ic pane-border-bg Ar colour
-Set the pane border colour for panes aside from the active pane.
-.It Ic pane-active-border-fg Ar colour
.It Ic pane-active-border-bg Ar colour
+.It Ic pane-active-border-fg Ar colour
Set the pane border colour for the currently active pane.
+.It Ic pane-border-bg Ar colour
+.It Ic pane-border-fg Ar colour
+Set the pane border colour for panes aside from the active pane.
.It Ic prefix Ar keys
Set the keys accepted as a prefix key.
.Ar keys
@@ -1783,6 +1858,10 @@ flag to
Repeat is enabled for the default keys bound to the
.Ic resize-pane
command.
+.It Xo Ic mouse-utf8
+.Op Ic on | off
+.Xc
+If enabled, request mouse input as UTF-8 on UTF-8 terminals.
.It Xo Ic set-remain-on-exit
.Op Ic on | off
.Xc
@@ -1838,7 +1917,12 @@ or right justified.
.Xc
Use vi or emacs-style
key bindings in the status line, for example at the command prompt.
-Defaults to emacs.
+The default is emacs, unless the
+.Ev VISUAL
+or
+.Ev EDITOR
+environment variables are set and contain the string
+.Ql vi .
.It Ic status-left Ar string
Display
.Ar string
@@ -1915,10 +1999,10 @@ is not interpreted, to enable UTF-8, use the
option.
.It Ic status-left-attr Ar attributes
Set the attribute of the left part of the status line.
-.It Ic status-left-fg Ar colour
-Set the foreground colour of the left part of the status line.
.It Ic status-left-bg Ar colour
Set the background colour of the left part of the status line.
+.It Ic status-left-fg Ar colour
+Set the foreground colour of the left part of the status line.
.It Ic status-left-length Ar length
Set the maximum
.Ar length
@@ -1940,16 +2024,15 @@ character pairs are replaced, and UTF-8 is dependent on the
option.
.It Ic status-right-attr Ar attributes
Set the attribute of the right part of the status line.
-.It Ic status-right-fg Ar colour
-Set the foreground colour of the right part of the status line.
.It Ic status-right-bg Ar colour
Set the background colour of the right part of the status line.
+.It Ic status-right-fg Ar colour
+Set the foreground colour of the right part of the status line.
.It Ic status-right-length Ar length
Set the maximum
.Ar length
of the right component of the status bar.
The default is 40.
-.Pp
.It Xo Ic status-utf8
.Op Ic on | off
.Xc
@@ -2008,7 +2091,8 @@ was given to the
.Ic set-environment
command).
The default is
-"DISPLAY WINDOWID SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION".
+"DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID
+XAUTHORITY".
.It Xo Ic visual-activity
.Op Ic on | off
.Xc
@@ -2033,6 +2117,12 @@ display a message when content is present in a window
for which the
.Ic monitor-content
window option is enabled.
+.It Xo Ic visual-silence
+.Op Ic on | off
+.Xc
+If
+.Ic monitor-silence
+is enabled, prints a message after the interval has expired on a given window.
.El
.It Xo Ic set-window-option
.Op Fl agu
@@ -2066,6 +2156,22 @@ this option is good for full-screen programs which support
.Dv SIGWINCH
and poor for interactive programs such as shells.
.Pp
+.It Xo Ic alternate-screen
+.Op Ic on | off
+.Xc
+This option configures whether programs running inside
+.Nm
+may use the terminal alternate screen feature, which allows the
+.Em smcup
+and
+.Em rmcup
+.Xr terminfo 5
+capabilities.
+The alternate screen feature preserves the contents of the window when an
+interactive application starts and restores it on exit, so that any output
+visible before the application starts reappears unchanged after it exits.
+The default is on.
+.Pp
.It Xo Ic automatic-rename
.Op Ic on | off
.Xc
@@ -2076,7 +2182,8 @@ will attempt - on supported platforms - to rename the window to reflect the
command currently running in it.
This flag is automatically disabled for an individual window when a name
is specified at creation with
-.Ic new-window or
+.Ic new-window
+or
.Ic new-session ,
or later with
.Ic rename-window .
@@ -2103,8 +2210,8 @@ or
.Ar height .
A value of zero restores the default unlimited setting.
.Pp
-.It Ic main-pane-width Ar width
.It Ic main-pane-height Ar height
+.It Ic main-pane-width Ar width
Set the width or height of the main (left or top) pane in the
.Ic main-horizontal
or
@@ -2124,7 +2231,14 @@ Set window modes foreground colour.
.Op Ic vi | emacs
.Xc
Use vi or emacs-style key bindings in copy and choice modes.
-Key bindings default to emacs.
+As with the
+.Ic status-keys
+option, the default is emacs, unless
+.Ev VISUAL
+or
+.Ev EDITOR
+contains
+.Ql vi .
.Pp
.It Xo Ic mode-mouse
.Op Ic on | off
@@ -2147,6 +2261,35 @@ pattern
.Ar match-string
appears in the window, it is highlighted in the status line.
.Pp
+.It Xo Ic monitor-silence
+.Op Ic interval
+.Xc
+Monitor for silence (no activity) in the window within
+.Ic interval
+seconds.
+Windows that have been silent for the interval are highlighted in the
+status line.
+An interval of zero disables the monitoring.
+.Pp
+.It Ic other-pane-height Ar height
+Set the height of the other panes (not the main pane) in the
+.Ic main-horizontal
+layout.
+If this option is set to 0 (the default), it will have no effect.
+If both the
+.Ic main-pane-height
+and
+.Ic other-pane-height
+options are set, the main pane will grow taller to make the other panes the
+specified height, but will never shrink to do so.
+.Pp
+.It Ic other-pane-width Ar width
+Like
+.Ic other-pane-height ,
+but set the width of other panes in the
+.Ic main-vertical
+layout.
+.Pp
.It Xo Ic remain-on-exit
.Op Ic on | off
.Xc
@@ -2162,19 +2305,6 @@ command.
Duplicate input to any pane to all other panes in the same window (only
for panes that are not in any special mode).
.Pp
-.It Xo Ic alternate-screen
-.Op Ic on | off
-.Xc
-This option configures whether programs running inside
-.Nm
-may use the terminal alternate screen feature, which allows the
-.Em smcup
-and
-.Em rmcup
-.Xr terminfo 5
-capabilities to be issued to preserve the existing window content on start and
-restore it on exit.
-.Pp
.It Xo Ic utf8
.Op Ic on | off
.Xc
@@ -2275,9 +2405,9 @@ copies the environment into the
.Em global environment ;
in addition, each session has a
.Em session environment .
-When a window is created, the session and global environments are merged with
-the session environment overriding any variable present in both.
-This is the initial environment passed to the new process.
+When a window is created, the session and global environments are merged.
+If a variable exists in both, the value from the session environment is used.
+The result is the initial environment passed to the new process.
.Pp
The
.Ic update-environment
@@ -2358,6 +2488,7 @@ The flag is one of the following symbols appended to the window name:
.It Li "#" Ta "Window is monitored and activity has been detected."
.It Li "!" Ta "A bell has occurred in the window."
.It Li "+" Ta "Window is monitored for content and it has appeared."
+.It Li "~" Ta "The window has been silent for the monitor-silence interval."
.El
.Pp
The # symbol relates to the
@@ -2456,8 +2587,7 @@ with the exception that #() are not handled.
.Sh BUFFERS
.Nm
maintains a stack of
-.Em paste buffers
-for each session.
+.Em paste buffers .
Up to the value of the
.Ic buffer-limit
option are kept; when a new buffer is added, the buffer at the bottom of the
@@ -2499,29 +2629,16 @@ This command works only from inside
.It Ic clear-history Op Fl t Ar target-pane
.D1 (alias: Ic clearhist )
Remove and free the history for the specified pane.
-.It Xo Ic copy-buffer
-.Op Fl a Ar src-index
-.Op Fl b Ar dst-index
-.Op Fl s Ar src-session
-.Op Fl t Ar dst-session
-.Xc
-.D1 (alias: Ic copyb )
-Copy a session paste buffer to another session.
-If no sessions are specified, the current one is used instead.
-.It Xo Ic delete-buffer
-.Op Fl b Ar buffer-index
-.Op Fl t Ar target-session
-.Xc
+.It Ic delete-buffer Op Fl b Ar buffer-index
.D1 (alias: Ic deleteb )
Delete the buffer at
.Ar buffer-index ,
or the top buffer if not specified.
-.It Ic list-buffers Op Fl t Ar target-session
+.It Ic list-buffers
.D1 (alias: Ic lsb )
-List the buffers in the given session.
+List the global buffers.
.It Xo Ic load-buffer
.Op Fl b Ar buffer-index
-.Op Fl t Ar target-session
.Ar path
.Xc
.D1 (alias: Ic loadb )
@@ -2550,7 +2667,6 @@ flag means to do no replacement (equivalent to a separator of LF).
.It Xo Ic save-buffer
.Op Fl a
.Op Fl b Ar buffer-index
-.Op Fl t Ar target-session
.Ar path
.Xc
.D1 (alias: Ic saveb )
@@ -2561,7 +2677,6 @@ The
option appends to rather than overwriting the file.
.It Xo Ic set-buffer
.Op Fl b Ar buffer-index
-.Op Fl t Ar target-session
.Ar data
.Xc
.D1 (alias: Ic setb )
@@ -2569,13 +2684,11 @@ Set the contents of the specified buffer to
.Ar data .
.It Xo Ic show-buffer
.Op Fl b Ar buffer-index
-.Op Fl t Ar target-session
.Xc
.D1 (alias: Ic showb )
Display the contents of the specified buffer.
.El
.Sh MISCELLANEOUS
-.Pp
Miscellaneous commands are as follows:
.Bl -tag -width Ds
.It Ic clock-mode Op Fl t Ar target-pane
diff --git a/tmux.c b/tmux.c
index 02e84bc..504c726 100644
--- a/tmux.c
+++ b/tmux.c
@@ -1,4 +1,4 @@
-/* $Id: tmux.c,v 1.215 2010/08/29 14:42:11 tcunha Exp $ */
+/* $Id: tmux.c,v 1.235 2011/01/21 23:46:50 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -18,15 +18,13 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/wait.h>
#include <errno.h>
#include <event.h>
+#include <fcntl.h>
#include <pwd.h>
-#include <signal.h>
#include <stdlib.h>
#include <string.h>
-#include <syslog.h>
#include <unistd.h>
#include "tmux.h"
@@ -35,7 +33,6 @@
extern char *malloc_options;
#endif
-char *cfg_file;
struct options global_options; /* server options */
struct options global_s_options; /* session options */
struct options global_w_options; /* window options */
@@ -43,29 +40,21 @@ struct environ global_environ;
struct event_base *ev_base;
+char *cfg_file;
+char *shell_cmd;
int debug_level;
time_t start_time;
-char *socket_path;
+char socket_path[MAXPATHLEN];
int login_shell;
-
-struct env_data {
- char *path;
- pid_t pid;
- u_int idx;
-};
+char *environ_path;
+pid_t environ_pid;
+u_int environ_idx;
__dead void usage(void);
-void parse_env(struct env_data *);
-char *makesockpath(const char *);
-__dead void shell_exec(const char *, const char *);
-
-struct imsgbuf *main_ibuf;
+void parseenvironment(void);
+char *makesocketpath(const char *);
-void main_signal(int, short, unused void *);
-void main_callback(int, short, void *);
-void main_dispatch(const char *);
-
-#ifndef HAVE_PROGNAME
+#ifndef HAVE___PROGNAME
char *__progname = (char *) "tmux";
#endif
@@ -73,7 +62,7 @@ __dead void
usage(void)
{
fprintf(stderr,
- "usage: %s [-28lquv] [-c shell-command] [-f file] [-L socket-name]\n"
+ "usage: %s [-28lquvV] [-c shell-command] [-f file] [-L socket-name]\n"
" [-S socket-path] [command [flags]]\n",
__progname);
exit(1);
@@ -137,14 +126,14 @@ areshell(const char *shell)
}
void
-parse_env(struct env_data *data)
+parseenvironment(void)
{
char *env, *path_pid, *pid_idx, buf[256];
size_t len;
const char *errstr;
long long ll;
- data->pid = -1;
+ environ_pid = -1;
if ((env = getenv("TMUX")) == NULL)
return;
@@ -157,9 +146,9 @@ parse_env(struct env_data *data)
/* path */
len = path_pid - env;
- data->path = xmalloc (len + 1);
- memcpy(data->path, env, len);
- data->path[len] = '\0';
+ environ_path = xmalloc(len + 1);
+ memcpy(environ_path, env, len);
+ environ_path[len] = '\0';
/* pid */
len = pid_idx - path_pid - 1;
@@ -171,24 +160,27 @@ parse_env(struct env_data *data)
ll = strtonum(buf, 0, LONG_MAX, &errstr);
if (errstr != NULL)
return;
- data->pid = ll;
+ environ_pid = ll;
/* idx */
- ll = strtonum(pid_idx+1, 0, UINT_MAX, &errstr);
+ ll = strtonum(pid_idx + 1, 0, UINT_MAX, &errstr);
if (errstr != NULL)
return;
- data->idx = ll;
+ environ_idx = ll;
}
char *
-makesockpath(const char *label)
+makesocketpath(const char *label)
{
- char base[MAXPATHLEN], *path;
+ char base[MAXPATHLEN], *path, *s;
struct stat sb;
u_int uid;
uid = getuid();
- xsnprintf(base, MAXPATHLEN, "%s/tmux-%d", _PATH_TMP, uid);
+ if ((s = getenv("TMPDIR")) == NULL || *s == '\0')
+ xsnprintf(base, sizeof base, "%s/tmux-%u", _PATH_TMP, uid);
+ else
+ xsnprintf(base, sizeof base, "%s/tmux-%u", s, uid);
if (mkdir(base, S_IRWXU) != 0 && errno != EEXIST)
return (NULL);
@@ -208,6 +200,20 @@ makesockpath(const char *label)
return (path);
}
+void
+setblocking(int fd, int state)
+{
+ int mode;
+
+ if ((mode = fcntl(fd, F_GETFL)) != -1) {
+ if (!state)
+ mode |= O_NONBLOCK;
+ else
+ mode &= ~O_NONBLOCK;
+ fcntl(fd, F_SETFL, mode);
+ }
+}
+
__dead void
shell_exec(const char *shell, const char *shellcmd)
{
@@ -225,6 +231,11 @@ shell_exec(const char *shell, const char *shellcmd)
xasprintf(&argv0, "%s", shellname);
setenv("SHELL", shell, 1);
+ setblocking(STDIN_FILENO, 1);
+ setblocking(STDOUT_FILENO, 1);
+ setblocking(STDERR_FILENO, 1);
+ closefrom(STDERR_FILENO + 1);
+
execl(shell, argv0, "-c", shellcmd, (char *) NULL);
fatal("execl failed");
}
@@ -232,30 +243,19 @@ shell_exec(const char *shell, const char *shellcmd)
int
main(int argc, char **argv)
{
- struct cmd_list *cmdlist;
- struct cmd *cmd;
- enum msgtype msg;
- struct passwd *pw;
- struct options *oo, *so, *wo;
- struct keylist *keylist;
- struct env_data envdata;
- struct msg_command_data cmddata;
- char *s, *shellcmd, *path, *label, *home, *cause;
- char **var;
- void *buf;
- size_t len;
- int opt, flags, quiet = 0, cmdflags = 0;
- short events;
+ struct passwd *pw;
+ struct keylist *keylist;
+ char *s, *path, *label, *home, **var;
+ int opt, flags, quiet, keys;
#if defined(DEBUG) && defined(__OpenBSD__)
malloc_options = (char *) "AFGJPX";
#endif
- flags = 0;
- shellcmd = label = path = NULL;
- envdata.path = NULL;
+ quiet = flags = 0;
+ label = path = NULL;
login_shell = (**argv == '-');
- while ((opt = getopt(argc, argv, "28c:df:lL:qS:uUv")) != -1) {
+ while ((opt = getopt(argc, argv, "28c:df:lL:qS:uUvV")) != -1) {
switch (opt) {
case '2':
flags |= IDENTIFY_256COLOURS;
@@ -266,10 +266,13 @@ main(int argc, char **argv)
flags &= ~IDENTIFY_256COLOURS;
break;
case 'c':
- if (shellcmd != NULL)
- xfree(shellcmd);
- shellcmd = xstrdup(optarg);
+ if (shell_cmd != NULL)
+ xfree(shell_cmd);
+ shell_cmd = xstrdup(optarg);
break;
+ case 'V':
+ printf("%s %s\n", __progname, VERSION);
+ exit(0);
case 'f':
if (cfg_file != NULL)
xfree(cfg_file);
@@ -304,7 +307,7 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
- if (shellcmd != NULL && argc != 0)
+ if (shell_cmd != NULL && argc != 0)
usage();
log_open_tty(debug_level);
@@ -331,113 +334,42 @@ main(int argc, char **argv)
environ_put(&global_environ, *var);
options_init(&global_options, NULL);
- oo = &global_options;
- options_set_number(oo, "quiet", quiet);
- options_set_number(oo, "escape-time", 500);
+ options_table_populate_tree(server_options_table, &global_options);
+ options_set_number(&global_options, "quiet", quiet);
options_init(&global_s_options, NULL);
- so = &global_s_options;
- options_set_number(so, "base-index", 0);
- options_set_number(so, "bell-action", BELL_ANY);
- options_set_number(so, "buffer-limit", 9);
- options_set_string(so, "default-command", "%s", "");
- options_set_string(so, "default-path", "%s", "");
- options_set_string(so, "default-shell", "%s", getshell());
- options_set_string(so, "default-terminal", "screen");
- options_set_number(so, "detach-on-destroy", 1);
- options_set_number(so, "display-panes-active-colour", 1);
- options_set_number(so, "display-panes-colour", 4);
- options_set_number(so, "display-panes-time", 1000);
- options_set_number(so, "display-time", 750);
- options_set_number(so, "history-limit", 2000);
- options_set_number(so, "lock-after-time", 0);
- options_set_string(so, "lock-command", "lock -np");
- options_set_number(so, "lock-server", 1);
- options_set_number(so, "message-attr", 0);
- options_set_number(so, "message-bg", 3);
- options_set_number(so, "message-fg", 0);
- options_set_number(so, "message-limit", 20);
- options_set_number(so, "mouse-select-pane", 0);
- options_set_number(so, "pane-active-border-bg", 8);
- options_set_number(so, "pane-active-border-fg", 2);
- options_set_number(so, "pane-border-bg", 8);
- options_set_number(so, "pane-border-fg", 8);
- options_set_number(so, "repeat-time", 500);
- options_set_number(so, "set-remain-on-exit", 0);
- options_set_number(so, "set-titles", 0);
- options_set_string(so, "set-titles-string", "#S:#I:#W - \"#T\"");
- options_set_number(so, "status", 1);
- options_set_number(so, "status-attr", 0);
- options_set_number(so, "status-bg", 2);
- options_set_number(so, "status-fg", 0);
- options_set_number(so, "status-interval", 15);
- options_set_number(so, "status-justify", 0);
- options_set_number(so, "status-keys", MODEKEY_EMACS);
- options_set_string(so, "status-left", "[#S]");
- options_set_number(so, "status-left-attr", 0);
- options_set_number(so, "status-left-bg", 8);
- options_set_number(so, "status-left-fg", 8);
- options_set_number(so, "status-left-length", 10);
- options_set_string(so, "status-right", "\"#22T\" %%H:%%M %%d-%%b-%%y");
- options_set_number(so, "status-right-attr", 0);
- options_set_number(so, "status-right-bg", 8);
- options_set_number(so, "status-right-fg", 8);
- options_set_number(so, "status-right-length", 40);
- options_set_string(so, "terminal-overrides",
- "*88col*:colors=88,*256col*:colors=256");
- options_set_string(so, "update-environment", "DISPLAY "
- "WINDOWID SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION");
- options_set_number(so, "visual-activity", 0);
- options_set_number(so, "visual-bell", 0);
- options_set_number(so, "visual-content", 0);
+ options_table_populate_tree(session_options_table, &global_s_options);
+ options_set_string(&global_s_options, "default-shell", "%s", getshell());
+
+ options_init(&global_w_options, NULL);
+ options_table_populate_tree(window_options_table, &global_w_options);
+ /* Set the prefix option (its a list, so not in the table). */
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ARRAY_ADD(keylist, '\002');
- options_set_data(so, "prefix", keylist, xfree);
-
- options_init(&global_w_options, NULL);
- wo = &global_w_options;
- options_set_number(wo, "aggressive-resize", 0);
- options_set_number(wo, "alternate-screen", 1);
- options_set_number(wo, "automatic-rename", 1);
- options_set_number(wo, "clock-mode-colour", 4);
- options_set_number(wo, "clock-mode-style", 1);
- options_set_number(wo, "force-height", 0);
- options_set_number(wo, "force-width", 0);
- options_set_number(wo, "main-pane-height", 24);
- options_set_number(wo, "main-pane-width", 81);
- options_set_number(wo, "mode-attr", 0);
- options_set_number(wo, "mode-bg", 3);
- options_set_number(wo, "mode-fg", 0);
- options_set_number(wo, "mode-keys", MODEKEY_EMACS);
- options_set_number(wo, "mode-mouse", 0);
- options_set_number(wo, "monitor-activity", 0);
- options_set_string(wo, "monitor-content", "%s", "");
- options_set_number(wo, "window-status-attr", 0);
- options_set_number(wo, "window-status-bg", 8);
- options_set_number(wo, "window-status-current-attr", 0);
- options_set_number(wo, "window-status-current-bg", 8);
- options_set_number(wo, "window-status-current-fg", 8);
- options_set_number(wo, "window-status-fg", 8);
- options_set_number(wo, "window-status-alert-attr", GRID_ATTR_REVERSE);
- options_set_number(wo, "window-status-alert-bg", 8);
- options_set_number(wo, "window-status-alert-fg", 8);
- options_set_string(wo, "window-status-format", "#I:#W#F");
- options_set_string(wo, "window-status-current-format", "#I:#W#F");
- options_set_string(wo, "word-separators", " [email protected]");
- options_set_number(wo, "xterm-keys", 0);
- options_set_number(wo, "remain-on-exit", 0);
- options_set_number(wo, "synchronize-panes", 0);
+ options_set_data(&global_s_options, "prefix", keylist, xfree);
+ /* Enable UTF-8 if the first client is on UTF-8 terminal. */
if (flags & IDENTIFY_UTF8) {
- options_set_number(so, "status-utf8", 1);
- options_set_number(wo, "utf8", 1);
- } else {
- options_set_number(so, "status-utf8", 0);
- options_set_number(wo, "utf8", 0);
+ options_set_number(&global_s_options, "status-utf8", 1);
+ options_set_number(&global_s_options, "mouse-utf8", 1);
+ options_set_number(&global_w_options, "utf8", 1);
+ }
+
+ /* Override keys to vi if VISUAL or EDITOR are set. */
+ if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) {
+ if (strrchr(s, '/') != NULL)
+ s = strrchr(s, '/') + 1;
+ if (strstr(s, "vi") != NULL)
+ keys = MODEKEY_VI;
+ else
+ keys = MODEKEY_EMACS;
+ options_set_number(&global_s_options, "status-keys", keys);
+ options_set_number(&global_w_options, "mode-keys", keys);
}
+ /* Locate the configuration file. */
if (cfg_file == NULL) {
home = getenv("HOME");
if (home == NULL || *home == '\0') {
@@ -453,21 +385,22 @@ main(int argc, char **argv)
}
/*
- * Figure out the socket path. If specified on the command-line with
- * -S or -L, use it, otherwise try $TMUX or assume -L default.
+ * Figure out the socket path. If specified on the command-line with -S
+ * or -L, use it, otherwise try $TMUX or assume -L default.
*/
- parse_env(&envdata);
+ parseenvironment();
if (path == NULL) {
- /* No -L. Try $TMUX, or default. */
+ /* If no -L, use the environment. */
if (label == NULL) {
- path = envdata.path;
- if (path == NULL)
+ if (environ_path != NULL)
+ path = xstrdup(environ_path);
+ else
label = xstrdup("default");
}
/* -L or default set. */
if (label != NULL) {
- if ((path = makesockpath(label)) == NULL) {
+ if ((path = makesocketpath(label)) == NULL) {
log_warn("can't create socket");
exit(1);
}
@@ -475,191 +408,16 @@ main(int argc, char **argv)
}
if (label != NULL)
xfree(label);
-
- if (shellcmd != NULL) {
- msg = MSG_SHELL;
- buf = NULL;
- len = 0;
- } else {
- cmddata.pid = envdata.pid;
- cmddata.idx = envdata.idx;
-
- /* Prepare command for server. */
- cmddata.argc = argc;
- if (cmd_pack_argv(
- argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
- log_warnx("command too long");
- exit(1);
- }
-
- msg = MSG_COMMAND;
- buf = &cmddata;
- len = sizeof cmddata;
- }
-
- if (shellcmd != NULL)
- cmdflags |= CMD_STARTSERVER;
- else if (argc == 0) /* new-session is the default */
- cmdflags |= CMD_STARTSERVER|CMD_SENDENVIRON|CMD_CANTNEST;
- else {
- /*
- * It sucks parsing the command string twice (in client and
- * later in server) but it is necessary to get the start server
- * flag.
- */
- if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
- log_warnx("%s", cause);
- exit(1);
- }
- cmdflags &= ~CMD_STARTSERVER;
- TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
- if (cmd->entry->flags & CMD_STARTSERVER)
- cmdflags |= CMD_STARTSERVER;
- if (cmd->entry->flags & CMD_SENDENVIRON)
- cmdflags |= CMD_SENDENVIRON;
- if (cmd->entry->flags & CMD_CANTNEST)
- cmdflags |= CMD_CANTNEST;
- }
- cmd_list_free(cmdlist);
- }
-
- /*
- * Check if this could be a nested session, if the command can't nest:
- * if the socket path matches $TMUX, this is probably the same server.
- */
- if (shellcmd == NULL && envdata.path != NULL &&
- cmdflags & CMD_CANTNEST &&
- (path == envdata.path || strcmp(path, envdata.path) == 0)) {
- log_warnx("sessions should be nested with care. "
- "unset $TMUX to force.");
- exit(1);
- }
-
-#ifdef HAVE_BROKEN_KQUEUE
- if (setenv("EVENT_NOKQUEUE", "1", 1) != 0)
- fatal("setenv failed");
-#endif
-#ifdef HAVE_BROKEN_POLL
- if (setenv("EVENT_NOPOLL", "1", 1) != 0)
- fatal("setenv failed");
-#endif
- ev_base = event_init();
-#ifdef HAVE_BROKEN_KQUEUE
- unsetenv("EVENT_NOKQUEUE");
-#endif
-#ifdef HAVE_BROKEN_POLL
- unsetenv("EVENT_NOPOLL");
-#endif
- set_signals(main_signal);
-
- /* Initialise the client socket/start the server. */
- if ((main_ibuf = client_init(path, cmdflags, flags)) == NULL)
- exit(1);
+ if (realpath(path, socket_path) == NULL)
+ strlcpy(socket_path, path, sizeof socket_path);
xfree(path);
- imsg_compose(main_ibuf, msg, PROTOCOL_VERSION, -1, -1, buf, len);
-
- events = EV_READ;
- if (main_ibuf->w.queued > 0)
- events |= EV_WRITE;
- event_once(main_ibuf->fd, events, main_callback, shellcmd, NULL);
-
- event_dispatch();
-
- clear_signals(0);
-
- client_main(); /* doesn't return */
-}
-
-/* ARGSUSED */
-void
-main_signal(int sig, unused short events, unused void *data)
-{
- int status;
-
- switch (sig) {
- case SIGTERM:
- exit(1);
- case SIGCHLD:
- waitpid(WAIT_ANY, &status, WNOHANG);
- break;
- }
-}
-
-/* ARGSUSED */
-void
-main_callback(unused int fd, short events, void *data)
-{
- char *shellcmd = data;
-
- if (events & EV_READ)
- main_dispatch(shellcmd);
-
- if (events & EV_WRITE) {
- if (msgbuf_write(&main_ibuf->w) < 0)
- fatalx("msgbuf_write failed");
- }
-
- events = EV_READ;
- if (main_ibuf->w.queued > 0)
- events |= EV_WRITE;
- event_once(main_ibuf->fd, events, main_callback, shellcmd, NULL);
-}
-
-void
-main_dispatch(const char *shellcmd)
-{
- struct imsg imsg;
- ssize_t n, datalen;
- struct msg_shell_data shelldata;
- struct msg_exit_data exitdata;
-
- if ((n = imsg_read(main_ibuf)) == -1 || n == 0)
- fatalx("imsg_read failed");
-
- for (;;) {
- if ((n = imsg_get(main_ibuf, &imsg)) == -1)
- fatalx("imsg_get failed");
- if (n == 0)
- return;
- datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
-
- switch (imsg.hdr.type) {
- case MSG_EXIT:
- case MSG_SHUTDOWN:
- if (datalen != sizeof exitdata) {
- if (datalen != 0)
- fatalx("bad MSG_EXIT size");
- exit(0);
- }
- memcpy(&exitdata, imsg.data, sizeof exitdata);
- exit(exitdata.retcode);
- case MSG_READY:
- if (datalen != 0)
- fatalx("bad MSG_READY size");
-
- event_loopexit(NULL); /* move to client_main() */
- break;
- case MSG_VERSION:
- if (datalen != 0)
- fatalx("bad MSG_VERSION size");
-
- log_warnx("protocol version mismatch (client %u, "
- "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid);
- exit(1);
- case MSG_SHELL:
- if (datalen != sizeof shelldata)
- fatalx("bad MSG_SHELL size");
- memcpy(&shelldata, imsg.data, sizeof shelldata);
- shelldata.shell[(sizeof shelldata.shell) - 1] = '\0';
-
- clear_signals(0);
-
- shell_exec(shelldata.shell, shellcmd);
- default:
- fatalx("unexpected message");
- }
+#ifdef HAVE_SETPROCTITLE
+ /* Set process title. */
+ setproctitle("%s (%s)", __progname, socket_path);
+#endif
- imsg_free(&imsg);
- }
+ /* Pass control to the client. */
+ ev_base = osdep_event_init();
+ exit(client_main(argc, argv, flags));
}
diff --git a/tmux.h b/tmux.h
index 60f46ba..798ae6d 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.577 2010/09/18 15:43:53 tcunha Exp $ */
+/* $Id: tmux.h,v 1.605 2011/01/21 23:56:11 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -19,8 +19,6 @@
#ifndef TMUX_H
#define TMUX_H
-#include "config.h"
-
#define PROTOCOL_VERSION 6
#include <sys/param.h>
@@ -532,10 +530,10 @@ struct mode_key_cmdstr {
/* Named mode key table description. */
struct mode_key_table {
- const char *name;
- struct mode_key_cmdstr *cmdstr;
- struct mode_key_tree *tree;
- const struct mode_key_entry *table; /* default entries */
+ const char *name;
+ const struct mode_key_cmdstr *cmdstr;
+ struct mode_key_tree *tree;
+ const struct mode_key_entry *table; /* default entries */
};
/* Modes. */
@@ -543,9 +541,13 @@ struct mode_key_table {
#define MODE_INSERT 0x2
#define MODE_KCURSOR 0x4
#define MODE_KKEYPAD 0x8 /* set = application, clear = number */
-#define MODE_MOUSE 0x10
-#define MODE_MOUSEMOTION 0x20
-#define MODE_WRAP 0x40 /* whether lines wrap */
+#define MODE_WRAP 0x10 /* whether lines wrap */
+#define MODE_MOUSE_STANDARD 0x20
+#define MODE_MOUSE_BUTTON 0x40
+#define MODE_MOUSE_ANY 0x80
+#define MODE_MOUSE_UTF8 0x100
+
+#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
/*
* A single UTF-8 character.
@@ -828,8 +830,10 @@ TAILQ_HEAD(window_panes, window_pane);
struct window {
char *name;
struct event name_timer;
+ struct timeval silence_timer;
struct window_pane *active;
+ struct window_pane *last;
struct window_panes panes;
int lastlayout;
@@ -840,9 +844,9 @@ struct window {
int flags;
#define WINDOW_BELL 0x1
-#define WINDOW_HIDDEN 0x2
-#define WINDOW_ACTIVITY 0x4
-#define WINDOW_REDRAW 0x8
+#define WINDOW_ACTIVITY 0x2
+#define WINDOW_REDRAW 0x4
+#define WINDOW_SILENCE 0x8
struct options options;
@@ -863,7 +867,9 @@ struct winlink {
#define WINLINK_BELL 0x1
#define WINLINK_ACTIVITY 0x2
#define WINLINK_CONTENT 0x4
-#define WINLINK_ALERTFLAGS (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT)
+#define WINLINK_SILENCE 0x8
+#define WINLINK_ALERTFLAGS \
+ (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT|WINLINK_SILENCE)
RB_ENTRY(winlink) entry;
TAILQ_ENTRY(winlink) sentry;
@@ -924,6 +930,8 @@ struct session_group {
TAILQ_HEAD(session_groups, session_group);
struct session {
+ u_int idx;
+
char *name;
char *cwd;
@@ -939,10 +947,7 @@ struct session {
struct options options;
- struct paste_stack buffers;
-
#define SESSION_UNATTACHED 0x1 /* not attached to any clients */
-#define SESSION_DEAD 0x2
int flags;
struct termios *tio;
@@ -952,8 +957,10 @@ struct session {
int references;
TAILQ_ENTRY(session) gentry;
+ RB_ENTRY(session) entry;
};
-ARRAY_DECL(sessions, struct session *);
+RB_HEAD(sessions, session);
+ARRAY_DECL(sessionslist, struct session *);
/* TTY information. */
struct tty_key {
@@ -1063,15 +1070,15 @@ struct tty_ctx {
*/
/* Mouse input. */
struct mouse_event {
- u_char b;
+ u_int b;
#define MOUSE_1 0
#define MOUSE_2 1
#define MOUSE_3 2
#define MOUSE_UP 3
#define MOUSE_BUTTON 3
#define MOUSE_45 64
- u_char x;
- u_char y;
+ u_int x;
+ u_int y;
};
/* Saved message entry. */
@@ -1141,21 +1148,29 @@ struct client {
int (*prompt_callbackfn)(void *, const char *);
void (*prompt_freefn)(void *);
void *prompt_data;
+ u_int prompt_hindex;
#define PROMPT_SINGLE 0x1
int prompt_flags;
- u_int prompt_hindex;
- ARRAY_DECL(, char *) prompt_hdata;
-
struct mode_key_data prompt_mdata;
struct session *session;
+ struct session *last_session;
int references;
};
ARRAY_DECL(clients, struct client *);
+/* Parsed arguments. */
+struct args {
+ bitstr_t *flags;
+ char *values[SCHAR_MAX]; /* XXX This is awfully big. */
+
+ int argc;
+ char **argv;
+};
+
/* Key/command line command. */
struct cmd_ctx {
/*
@@ -1186,68 +1201,35 @@ struct cmd_ctx {
};
struct cmd {
- const struct cmd_entry *entry;
- void *data;
+ const struct cmd_entry *entry;
+ struct args *args;
- TAILQ_ENTRY(cmd) qentry;
+ TAILQ_ENTRY(cmd) qentry;
};
struct cmd_list {
- int references;
- TAILQ_HEAD(, cmd) list;
+ int references;
+ TAILQ_HEAD(, cmd) list;
};
struct cmd_entry {
const char *name;
const char *alias;
+
+ const char *args_template;
+ int args_lower;
+ int args_upper;
+
const char *usage;
#define CMD_STARTSERVER 0x1
#define CMD_CANTNEST 0x2
#define CMD_SENDENVIRON 0x4
-#define CMD_ARG1 0x8
-#define CMD_ARG01 0x10
-#define CMD_ARG2 0x20
-#define CMD_ARG12 0x40
-#define CMD_READONLY 0x80
+#define CMD_READONLY 0x8
int flags;
- const char *chflags;
-
- void (*init)(struct cmd *, int);
- int (*parse)(struct cmd *, int, char **, char **);
+ void (*key_binding)(struct cmd *, int);
+ int (*check)(struct args *);
int (*exec)(struct cmd *, struct cmd_ctx *);
- void (*free)(struct cmd *);
- size_t (*print)(struct cmd *, char *, size_t);
-};
-
-/* Generic command data. */
-struct cmd_target_data {
- uint64_t chflags;
-
- char *target;
-
- char *arg;
- char *arg2;
-};
-
-struct cmd_srcdst_data {
- uint64_t chflags;
-
- char *src;
- char *dst;
-
- char *arg;
- char *arg2;
-};
-
-struct cmd_buffer_data {
- uint64_t chflags;
-
- char *target;
- int buffer;
-
- char *arg;
- char *arg2;
};
/* Key binding. */
@@ -1260,28 +1242,47 @@ struct key_binding {
};
SPLAY_HEAD(key_bindings, key_binding);
-/* Set/display option data. */
-struct set_option_entry {
- const char *name;
- enum {
- SET_OPTION_STRING,
- SET_OPTION_NUMBER,
- SET_OPTION_KEYS,
- SET_OPTION_COLOUR,
- SET_OPTION_ATTRIBUTES,
- SET_OPTION_FLAG,
- SET_OPTION_CHOICE
- } type;
+/*
+ * Option table entries. The option table is the user-visible part of the
+ * option, as opposed to the internal options (struct option) which are just
+ * number or string.
+ */
+enum options_table_type {
+ OPTIONS_TABLE_STRING,
+ OPTIONS_TABLE_NUMBER,
+ OPTIONS_TABLE_KEYS,
+ OPTIONS_TABLE_COLOUR,
+ OPTIONS_TABLE_ATTRIBUTES,
+ OPTIONS_TABLE_FLAG,
+ OPTIONS_TABLE_CHOICE
+};
+
+struct options_table_entry {
+ const char *name;
+ enum options_table_type type;
- u_int minimum;
- u_int maximum;
+ u_int minimum;
+ u_int maximum;
+ const char **choices;
- const char **choices;
+ const char *default_str;
+ long long default_num;
};
/* List of configuration causes. */
ARRAY_DECL(causelist, char *);
+/* Common command usages. */
+#define CMD_TARGET_PANE_USAGE "[-t target-pane]"
+#define CMD_TARGET_WINDOW_USAGE "[-t target-window]"
+#define CMD_TARGET_SESSION_USAGE "[-t target-session]"
+#define CMD_TARGET_CLIENT_USAGE "[-t target-client]"
+#define CMD_SRCDST_PANE_USAGE "[-s src-pane] [-t dst-pane]"
+#define CMD_SRCDST_WINDOW_USAGE "[-s src-window] [-t dst-window]"
+#define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]"
+#define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]"
+#define CMD_BUFFER_USAGE "[-b buffer-index]"
+
/* tmux.c */
extern struct options global_options;
extern struct options global_s_options;
@@ -1289,19 +1290,24 @@ extern struct options global_w_options;
extern struct environ global_environ;
extern struct event_base *ev_base;
extern char *cfg_file;
+extern char *shell_cmd;
extern int debug_level;
-extern int be_quiet;
extern time_t start_time;
-extern char *socket_path;
+extern char socket_path[MAXPATHLEN];
extern int login_shell;
+extern char *environ_path;
+extern pid_t environ_pid;
+extern u_int environ_idx;
void logfile(const char *);
const char *getshell(void);
int checkshell(const char *);
int areshell(const char *);
+void setblocking(int, int);
+__dead void shell_exec(const char *, const char *);
/* cfg.c */
extern int cfg_finished;
-struct causelist cfg_causes;
+extern struct causelist cfg_causes;
void printflike2 cfg_add_cause(struct causelist *, const char *, ...);
int load_cfg(const char *, struct cmd_ctx *, struct causelist *);
@@ -1315,8 +1321,10 @@ extern struct mode_key_tree mode_key_tree_emacs_choice;
extern struct mode_key_tree mode_key_tree_emacs_copy;
int mode_key_cmp(struct mode_key_binding *, struct mode_key_binding *);
SPLAY_PROTOTYPE(mode_key_tree, mode_key_binding, entry, mode_key_cmp);
-const char *mode_key_tostring(struct mode_key_cmdstr *r, enum mode_key_cmd);
-enum mode_key_cmd mode_key_fromstring(struct mode_key_cmdstr *, const char *);
+const char *mode_key_tostring(const struct mode_key_cmdstr *,
+ enum mode_key_cmd);
+enum mode_key_cmd mode_key_fromstring(const struct mode_key_cmdstr *,
+ const char *);
const struct mode_key_table *mode_key_findtable(const char *);
void mode_key_init_trees(void);
void mode_key_init(struct mode_key_data *, struct mode_key_tree *);
@@ -1340,6 +1348,15 @@ struct options_entry *options_set_data(
struct options *, const char *, void *, void (*)(void *));
void *options_get_data(struct options *, const char *);
+/* options-table.c */
+extern const struct options_table_entry server_options_table[];
+extern const struct options_table_entry session_options_table[];
+extern const struct options_table_entry window_options_table[];
+void options_table_populate_tree(
+ const struct options_table_entry *, struct options *);
+const char *options_table_print_entry(
+ const struct options_table_entry *, struct options_entry *);
+
/* job.c */
extern struct joblist all_jobs;
int job_cmp(struct job *, struct job *);
@@ -1412,7 +1429,7 @@ void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
/* tty-term.c */
extern struct tty_terms tty_terms;
-extern struct tty_term_code_entry tty_term_codes[NTTYCODE];
+extern const struct tty_term_code_entry tty_term_codes[NTTYCODE];
struct tty_term *tty_term_find(char *, int, const char *, char **);
void tty_term_free(struct tty_term *);
int tty_term_has(struct tty_term *, enum tty_code_code);
@@ -1432,8 +1449,6 @@ void tty_keys_free(struct tty *);
int tty_keys_next(struct tty *);
/* paste.c */
-void paste_init_stack(struct paste_stack *);
-void paste_free_stack(struct paste_stack *);
struct paste_buffer *paste_walk_stack(struct paste_stack *, uint *);
struct paste_buffer *paste_get_top(struct paste_stack *);
struct paste_buffer *paste_get_index(struct paste_stack *, u_int);
@@ -1447,16 +1462,21 @@ char *paste_print(struct paste_buffer *, size_t);
extern const char clock_table[14][5][5];
void clock_draw(struct screen_write_ctx *, int, int);
-/* cmd-set-option.c */
-extern const struct set_option_entry set_option_table[];
-extern const struct set_option_entry set_session_option_table[];
-extern const struct set_option_entry set_window_option_table[];
-const char *cmd_set_option_print(
- const struct set_option_entry *, struct options_entry *);
+/* arguments.c */
+struct args *args_create(int, ...);
+struct args *args_parse(const char *, int, char **);
+void args_free(struct args *);
+size_t args_print(struct args *, char *, size_t);
+int args_has(struct args *, u_char);
+void args_set(struct args *, u_char, const char *);
+const char *args_get(struct args *, u_char);
+long long args_strtonum(
+ struct args *, u_char, long long, long long, char **);
/* cmd.c */
int cmd_pack_argv(int, char **, char *, size_t);
int cmd_unpack_argv(char *, size_t, int, char ***);
+char **cmd_copy_argv(int, char *const *);
void cmd_free_argv(int, char **);
struct cmd *cmd_parse(int, char **, char **);
int cmd_exec(struct cmd *, struct cmd_ctx *);
@@ -1486,7 +1506,6 @@ extern const struct cmd_entry cmd_clear_history_entry;
extern const struct cmd_entry cmd_clock_mode_entry;
extern const struct cmd_entry cmd_command_prompt_entry;
extern const struct cmd_entry cmd_confirm_before_entry;
-extern const struct cmd_entry cmd_copy_buffer_entry;
extern const struct cmd_entry cmd_copy_mode_entry;
extern const struct cmd_entry cmd_delete_buffer_entry;
extern const struct cmd_entry cmd_detach_client_entry;
@@ -1501,6 +1520,7 @@ extern const struct cmd_entry cmd_kill_pane_entry;
extern const struct cmd_entry cmd_kill_server_entry;
extern const struct cmd_entry cmd_kill_session_entry;
extern const struct cmd_entry cmd_kill_window_entry;
+extern const struct cmd_entry cmd_last_pane_entry;
extern const struct cmd_entry cmd_last_window_entry;
extern const struct cmd_entry cmd_link_window_entry;
extern const struct cmd_entry cmd_list_buffers_entry;
@@ -1566,38 +1586,8 @@ size_t cmd_list_print(struct cmd_list *, char *, size_t);
/* cmd-string.c */
int cmd_string_parse(const char *, struct cmd_list **, char **);
-/* cmd-generic.c */
-size_t cmd_prarg(char *, size_t, const char *, char *);
-int cmd_check_flag(uint64_t, int);
-void cmd_set_flag(uint64_t *, int);
-#define CMD_TARGET_PANE_USAGE "[-t target-pane]"
-#define CMD_TARGET_WINDOW_USAGE "[-t target-window]"
-#define CMD_TARGET_SESSION_USAGE "[-t target-session]"
-#define CMD_TARGET_CLIENT_USAGE "[-t target-client]"
-void cmd_target_init(struct cmd *, int);
-int cmd_target_parse(struct cmd *, int, char **, char **);
-void cmd_target_free(struct cmd *);
-size_t cmd_target_print(struct cmd *, char *, size_t);
-#define CMD_SRCDST_PANE_USAGE "[-s src-pane] [-t dst-pane]"
-#define CMD_SRCDST_WINDOW_USAGE "[-s src-window] [-t dst-window]"
-#define CMD_SRCDST_SESSION_USAGE "[-s src-session] [-t dst-session]"
-#define CMD_SRCDST_CLIENT_USAGE "[-s src-client] [-t dst-client]"
-void cmd_srcdst_init(struct cmd *, int);
-int cmd_srcdst_parse(struct cmd *, int, char **, char **);
-void cmd_srcdst_free(struct cmd *);
-size_t cmd_srcdst_print(struct cmd *, char *, size_t);
-#define CMD_BUFFER_PANE_USAGE "[-b buffer-index] [-t target-pane]"
-#define CMD_BUFFER_WINDOW_USAGE "[-b buffer-index] [-t target-window]"
-#define CMD_BUFFER_SESSION_USAGE "[-b buffer-index] [-t target-session]"
-#define CMD_BUFFER_CLIENT_USAGE "[-b buffer-index] [-t target-client]"
-void cmd_buffer_init(struct cmd *, int);
-int cmd_buffer_parse(struct cmd *, int, char **, char **);
-void cmd_buffer_free(struct cmd *);
-size_t cmd_buffer_print(struct cmd *, char *, size_t);
-
/* client.c */
-struct imsgbuf *client_init(char *, int, int);
-__dead void client_main(void);
+int client_main(int, char **, int);
/* key-bindings.c */
extern struct key_bindings key_bindings;
@@ -1620,7 +1610,8 @@ const char *key_string_lookup_key(int);
/* server.c */
extern struct clients clients;
extern struct clients dead_clients;
-int server_start(char *);
+extern struct paste_stack global_buffers;
+int server_start(void);
void server_update_socket(void);
/* server-client.c */
@@ -1659,6 +1650,7 @@ void server_unlink_window(struct session *, struct winlink *);
void server_destroy_pane(struct window_pane *);
void server_destroy_session_group(struct session *);
void server_destroy_session(struct session *);
+void server_check_unattached (void);
void server_set_identify(struct client *);
void server_clear_identify(struct client *);
void server_update_event(struct client *);
@@ -1794,7 +1786,9 @@ void screen_write_cursormode(struct screen_write_ctx *, int);
void screen_write_reverseindex(struct screen_write_ctx *);
void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int);
void screen_write_insertmode(struct screen_write_ctx *, int);
-void screen_write_mousemode(struct screen_write_ctx *, int);
+void screen_write_utf8mousemode(struct screen_write_ctx *, int);
+void screen_write_mousemode_on(struct screen_write_ctx *, int);
+void screen_write_mousemode_off(struct screen_write_ctx *);
void screen_write_linefeed(struct screen_write_ctx *, int);
void screen_write_linefeedscreen(struct screen_write_ctx *, int);
void screen_write_carriagereturn(struct screen_write_ctx *);
@@ -1824,9 +1818,7 @@ int screen_check_selection(struct screen *, u_int, u_int);
/* window.c */
extern struct windows windows;
-int window_cmp(struct window *, struct window *);
int winlink_cmp(struct winlink *, struct winlink *);
-RB_PROTOTYPE(windows, window, entry, window_cmp);
RB_PROTOTYPE(winlinks, winlink, entry, winlink_cmp);
struct winlink *winlink_find_by_index(struct winlinks *, int);
struct winlink *winlink_find_by_window(struct winlinks *, struct window *);
@@ -1880,6 +1872,8 @@ void window_pane_mouse(struct window_pane *,
int window_pane_visible(struct window_pane *);
char *window_pane_search(
struct window_pane *, const char *, u_int *);
+char *window_printable_flags(struct session *, struct winlink *);
+
struct window_pane *window_pane_find_up(struct window_pane *);
struct window_pane *window_pane_find_down(struct window_pane *);
struct window_pane *window_pane_find_left(struct window_pane *);
@@ -1959,12 +1953,16 @@ void clear_signals(int);
extern struct sessions sessions;
extern struct sessions dead_sessions;
extern struct session_groups session_groups;
+int session_cmp(struct session *, struct session *);
+RB_PROTOTYPE(sessions, session, entry, session_cmp);
+int session_alive(struct session *);
struct session *session_find(const char *);
+struct session *session_find_by_index(u_int);
struct session *session_create(const char *, const char *, const char *,
struct environ *, struct termios *, int, u_int, u_int,
char **);
void session_destroy(struct session *);
-int session_index(struct session *, u_int *);
+void session_update_activity(struct session *);
struct session *session_next_session(struct session *);
struct session *session_previous_session(struct session *);
struct winlink *session_new(struct session *,
@@ -1989,9 +1987,12 @@ void session_group_synchronize1(struct session *, struct session *);
void utf8_build(void);
int utf8_open(struct utf8_data *, u_char);
int utf8_append(struct utf8_data *, u_char);
+u_int utf8_combine(const struct utf8_data *);
+u_int utf8_split2(u_int, u_char *);
/* osdep-*.c */
-char *osdep_get_name(int, char *);
+char *osdep_get_name(int, char *);
+struct event_base *osdep_event_init(void);
/* log.c */
void log_open_tty(int);
diff --git a/tmux.o b/tmux.o
new file mode 100644
index 0000000..78bc6d5
--- a/dev/null
+++ b/tmux.o
Binary files differ
diff --git a/tools/check-compat.sh b/tools/check-compat.sh
new file mode 100644
index 0000000..1864cf9
--- a/dev/null
+++ b/tools/check-compat.sh
@@ -0,0 +1,5 @@
+# $Id: check-compat.sh,v 1.1 2010/10/24 00:42:04 tcunha Exp $
+
+grep "#include" compat.h|while read line; do
+ grep "$line" *.[ch] compat/*.[ch]
+done
diff --git a/tools/dist.mk b/tools/dist.mk
deleted file mode 100644
index 9827f96..0000000
--- a/tools/dist.mk
+++ b/dev/null
@@ -1,33 +0,0 @@
-# $Id: dist.mk,v 1.10 2010/07/19 13:57:22 tcunha Exp $
-
-VERSION= 1.3
-
-DISTDIR= tmux-${VERSION}
-DISTFILES= *.[ch] Makefile GNUmakefile configure tmux.1 \
- NOTES TODO CHANGES FAQ \
- `find examples compat -type f -and ! -path '*CVS*'`
-
-dist:
- (./configure && make clean-all)
- grep '^#FDEBUG=' Makefile
- grep '^#FDEBUG=' GNUmakefile
- [ "`(grep '^VERSION' Makefile; grep '^VERSION' GNUmakefile)| \
- uniq -u`" = "" ]
- chmod +x configure
- tar -zc \
- -s '/.*/${DISTDIR}\/\0/' \
- -f ${DISTDIR}.tar.gz ${DISTFILES}
-
-upload-index.html: update-index.html
- scp www/index.html www/main.css www/images/*.png \
- ${USER},[email protected]:/home/groups/t/tm/tmux/htdocs
- rm -f www/index.html www/images/small-*
-
-update-index.html:
- (cd www/images && \
- rm -f small-* && \
- for i in *.png; do \
- convert "$$i" -resize 200x150 "small-$$i"; \
- done \
- )
- sed "s/%%VERSION%%/${VERSION}/g" www/index.html.in >www/index.html
diff --git a/tools/fuzz.c b/tools/fuzz.c
new file mode 100644
index 0000000..39a2a4d
--- a/dev/null
+++ b/tools/fuzz.c
@@ -0,0 +1,31 @@
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+ time_t t;
+ int i;
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ t = time(NULL);
+ srandom((u_int) t);
+
+ for (;;) {
+ putchar('\033');
+
+ for (i = 0; i < random() % 25; i++) {
+ if (i > 22)
+ putchar(';');
+ else
+ putchar(random() % 256);
+ }
+
+ /* usleep(100); */
+ }
+}
diff --git a/tty-acs.o b/tty-acs.o
new file mode 100644
index 0000000..cbf3f94
--- a/dev/null
+++ b/tty-acs.o
Binary files differ
diff --git a/tty-keys.c b/tty-keys.c
index fc6c701..bd30876 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -1,4 +1,4 @@
-/* $Id: tty-keys.c,v 1.57 2010/06/06 00:23:44 tcunha Exp $ */
+/* $Id: tty-keys.c,v 1.59 2011/01/07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -38,7 +38,7 @@ struct tty_key *tty_keys_find1(
struct tty_key *, const char *, size_t, size_t *);
struct tty_key *tty_keys_find(struct tty *, const char *, size_t, size_t *);
void tty_keys_callback(int, short, void *);
-int tty_keys_mouse(
+int tty_keys_mouse(struct tty *,
const char *, size_t, size_t *, struct mouse_event *);
struct tty_key_ent {
@@ -54,7 +54,7 @@ struct tty_key_ent {
* Default key tables. Those flagged with TTYKEY_RAW are inserted directly,
* otherwise they are looked up in terminfo(5).
*/
-struct tty_key_ent tty_keys[] = {
+const struct tty_key_ent tty_keys[] = {
/*
* Numeric keypad. Just use the vt100 escape sequences here and always
* put the terminal into keypad_xmit mode. Translation of numbers
@@ -343,9 +343,9 @@ tty_keys_add1(struct tty_key **tkp, const char *s, int key)
void
tty_keys_init(struct tty *tty)
{
- struct tty_key_ent *tke;
- u_int i;
- const char *s;
+ const struct tty_key_ent *tke;
+ u_int i;
+ const char *s;
tty->key_tree = NULL;
for (i = 0; i < nitems(tty_keys); i++) {
@@ -462,7 +462,7 @@ tty_keys_next(struct tty *tty)
}
/* Is this a mouse key press? */
- switch (tty_keys_mouse(buf, len, &size, &mouse)) {
+ switch (tty_keys_mouse(tty, buf, len, &size, &mouse)) {
case 0: /* yes */
evbuffer_drain(tty->event->input, size);
key = KEYC_MOUSE;
@@ -584,44 +584,74 @@ tty_keys_callback(unused int fd, unused short events, void *data)
* (probably a mouse sequence but need more data).
*/
int
-tty_keys_mouse(const char *buf, size_t len, size_t *size, struct mouse_event *m)
+tty_keys_mouse(struct tty *tty,
+ const char *buf, size_t len, size_t *size, struct mouse_event *m)
{
+ struct utf8_data utf8data;
+ u_int i, value;
+
/*
- * Mouse sequences are \033[M followed by three characters indicating
- * buttons, X and Y, all based at 32 with 1,1 top-left.
+ * Standard mouse sequences are \033[M followed by three characters
+ * indicating buttons, X and Y, all based at 32 with 1,1 top-left.
+ *
+ * UTF-8 mouse sequences are similar but the three are expressed as
+ * UTF-8 characters.
*/
*size = 0;
+ /* First three bytes are always \033[M. */
if (buf[0] != '\033')
return (-1);
if (len == 1)
return (1);
-
if (buf[1] != '[')
return (-1);
if (len == 2)
return (1);
-
if (buf[2] != 'M')
return (-1);
if (len == 3)
return (1);
- if (len < 6)
- return (1);
- *size = 6;
+ /* Read the three inputs. */
+ *size = 3;
+ for (i = 0; i < 3; i++) {
+ if (len < *size)
+ return (1);
+
+ if (tty->mode & MODE_MOUSE_UTF8) {
+ if (utf8_open(&utf8data, buf[*size])) {
+ if (utf8data.size != 2)
+ return (-1);
+ (*size)++;
+ if (len < *size)
+ return (1);
+ utf8_append(&utf8data, buf[*size]);
+ value = utf8_combine(&utf8data);
+ } else
+ value = buf[*size];
+ (*size)++;
+ } else {
+ value = buf[*size];
+ (*size)++;
+ }
- log_debug(
- "mouse input: %.6s (%hhu,%hhu/%hhu)", buf, buf[4], buf[5], buf[3]);
+ if (i == 0)
+ m->b = value;
+ else if (i == 1)
+ m->x = value;
+ else
+ m->y = value;
+ }
+ log_debug("mouse input: %.*s", (int) *size, buf);
- m->b = buf[3];
- m->x = buf[4];
- m->y = buf[5];
+ /* Check and return the mouse input. */
if (m->b < 32 || m->x < 33 || m->y < 33)
return (-1);
m->b -= 32;
m->x -= 33;
m->y -= 33;
+ log_debug("mouse position: x=%u y=%u b=%u", m->x, m->y, m->b);
return (0);
}
diff --git a/tty-keys.o b/tty-keys.o
new file mode 100644
index 0000000..105e8bb
--- a/dev/null
+++ b/tty-keys.o
Binary files differ
diff --git a/tty-term.c b/tty-term.c
index 09896e0..76ae1e3 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -1,4 +1,4 @@
-/* $Id: tty-term.c,v 1.43 2010/09/18 15:43:53 tcunha Exp $ */
+/* $Id: tty-term.c,v 1.45 2011/01/03 23:30:43 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -18,10 +18,10 @@
#include <sys/types.h>
-#ifdef HAVE_BROKEN_CURSES_H
-#include <ncurses.h>
-#else
+#ifdef HAVE_CURSES_H
#include <curses.h>
+#else
+#include <ncurses.h>
#endif
#include <fnmatch.h>
#include <stdlib.h>
@@ -35,7 +35,7 @@ char *tty_term_strip(const char *);
struct tty_terms tty_terms = SLIST_HEAD_INITIALIZER(tty_terms);
-struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
+const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_ACSC, TTYCODE_STRING, "acsc" },
{ TTYC_AX, TTYCODE_FLAG, "AX" },
{ TTYC_BEL, TTYCODE_STRING, "bel" },
@@ -217,13 +217,14 @@ tty_term_strip(const char *s)
void
tty_term_override(struct tty_term *term, const char *overrides)
{
- struct tty_term_code_entry *ent;
- struct tty_code *code;
- char *termnext, *termstr, *entnext, *entstr;
- char *s, *ptr, *val;
- const char *errstr;
- u_int i;
- int n, removeflag;
+ const struct tty_term_code_entry *ent;
+ struct tty_code *code;
+ char *termnext, *termstr;
+ char *entnext, *entstr;
+ char *s, *ptr, *val;
+ const char *errstr;
+ u_int i;
+ int n, removeflag;
s = xstrdup(overrides);
@@ -299,13 +300,13 @@ tty_term_override(struct tty_term *term, const char *overrides)
struct tty_term *
tty_term_find(char *name, int fd, const char *overrides, char **cause)
{
- struct tty_term *term;
- struct tty_term_code_entry *ent;
- struct tty_code *code;
- u_int i;
- int n, error;
- char *s;
- const char *acs;
+ struct tty_term *term;
+ const struct tty_term_code_entry *ent;
+ struct tty_code *code;
+ u_int i;
+ int n, error;
+ char *s;
+ const char *acs;
SLIST_FOREACH(term, &tty_terms, entry) {
if (strcmp(term->name, name) == 0) {
diff --git a/tty-term.o b/tty-term.o
new file mode 100644
index 0000000..48098f2
--- a/dev/null
+++ b/tty-term.o
Binary files differ
diff --git a/tty.c b/tty.c
index 52307c1..4637a59 100644
--- a/tty.c
+++ b/tty.c
@@ -1,4 +1,4 @@
-/* $Id: tty.c,v 1.195 2010/09/18 15:45:03 tcunha Exp $ */
+/* $Id: tty.c,v 1.202 2011/01/21 23:56:53 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -61,9 +61,6 @@ tty_init(struct tty *tty, int fd, char *term)
tty->termname = xstrdup("unknown");
else
tty->termname = xstrdup(term);
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
tty->fd = fd;
if ((path = ttyname(fd)) == NULL)
@@ -168,15 +165,11 @@ void
tty_start_tty(struct tty *tty)
{
struct termios tio;
- int mode;
if (tty->fd == -1)
return;
- if ((mode = fcntl(tty->fd, F_GETFL)) == -1)
- fatal("fcntl failed");
- if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1)
- fatal("fcntl failed");
+ setblocking(tty->fd, 0);
bufferevent_enable(tty->event, EV_READ|EV_WRITE);
@@ -223,7 +216,6 @@ void
tty_stop_tty(struct tty *tty)
{
struct winsize ws;
- int mode;
if (!(tty->flags & TTY_STARTED))
return;
@@ -254,8 +246,7 @@ tty_stop_tty(struct tty *tty)
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
- if ((mode = fcntl(tty->fd, F_GETFL)) != -1)
- fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK);
+ setblocking(tty->fd, 1);
}
void
@@ -406,17 +397,25 @@ tty_update_mode(struct tty *tty, int mode)
else
tty_putcode(tty, TTYC_CIVIS);
}
- if (changed & (MODE_MOUSE|MODE_MOUSEMOTION)) {
- if (mode & MODE_MOUSE) {
- if (mode & MODE_MOUSEMOTION)
+ if (changed & ALL_MOUSE_MODES) {
+ if (mode & ALL_MOUSE_MODES) {
+ if (mode & MODE_MOUSE_UTF8)
+ tty_puts(tty, "\033[?1005h");
+ if (mode & MODE_MOUSE_ANY)
tty_puts(tty, "\033[?1003h");
- else
+ else if (mode & MODE_MOUSE_BUTTON)
+ tty_puts(tty, "\033[?1002h");
+ else if (mode & MODE_MOUSE_STANDARD)
tty_puts(tty, "\033[?1000h");
} else {
- if (mode & MODE_MOUSEMOTION)
+ if (tty->mode & MODE_MOUSE_ANY)
tty_puts(tty, "\033[?1003l");
- else
+ else if (tty->mode & MODE_MOUSE_BUTTON)
+ tty_puts(tty, "\033[?1002l");
+ else if (tty->mode & MODE_MOUSE_STANDARD)
tty_puts(tty, "\033[?1000l");
+ if (tty->mode & MODE_MOUSE_UTF8)
+ tty_puts(tty, "\033[?1005l");
}
}
if (changed & MODE_KKEYPAD) {
@@ -550,7 +549,7 @@ tty_write(void (*cmdfn)(
if (wp->window->flags & WINDOW_REDRAW || wp->flags & PANE_REDRAW)
return;
- if (wp->window->flags & WINDOW_HIDDEN || !window_pane_visible(wp))
+ if (!window_pane_visible(wp))
return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
diff --git a/tty.o b/tty.o
new file mode 100644
index 0000000..ad9f004
--- a/dev/null
+++ b/tty.o
Binary files differ
diff --git a/utf8.c b/utf8.c
index 11114b5..73878ca 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1,4 +1,4 @@
-/* $Id: utf8.c,v 1.11 2009/10/23 17:21:34 tcunha Exp $ */
+/* $Id: utf8.c,v 1.12 2011/01/07 14:34:45 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <[email protected]>
@@ -318,6 +318,19 @@ utf8_combine(const struct utf8_data *utf8data)
return (value);
}
+/* Split a two-byte UTF-8 character. */
+u_int
+utf8_split2(u_int uc, u_char *ptr)
+{
+ if (uc > 0x7f) {
+ ptr[0] = (uc >> 6) | 0xc0;
+ ptr[1] = (uc & 0x3f) | 0x80;
+ return (2);
+ }
+ ptr[0] = uc;
+ return (1);
+}
+
/* Lookup width of UTF-8 data in tree. */
u_int
utf8_width(const struct utf8_data *utf8data)
diff --git a/utf8.o b/utf8.o
new file mode 100644
index 0000000..5977190
--- a/dev/null
+++ b/utf8.o
Binary files differ
diff --git a/window-choose.c b/window-choose.c
index bce3ecb..fd9cf74 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -1,4 +1,4 @@
-/* $Id: window-choose.c,v 1.30 2010/05/22 21:56:04 micahcowan Exp $ */
+/* $Id: window-choose.c,v 1.31 2010/12/30 22:27:38 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <[email protected]>
@@ -127,7 +127,7 @@ window_choose_init(struct window_pane *wp)
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
if (options_get_number(&wp->window->options, "mode-mouse"))
- s->mode |= MODE_MOUSE;
+ s->mode |= MODE_MOUSE_STANDARD;
keys = options_get_number(&wp->window->options, "mode-keys");
if (keys == MODEKEY_EMACS)
diff --git a/window-choose.o b/window-choose.o
new file mode 100644
index 0000000..86a6b8a
--- a/dev/null
+++ b/window-choose.o
Binary files differ
diff --git a/window-clock.o b/window-clock.o
new file mode 100644
index 0000000..5685a7c
--- a/dev/null
+++ b/window-clock.o
Binary files differ
diff --git a/window-copy.c b/window-copy.c
index a34c4a5..100a65c 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -1,4 +1,4 @@
-/* $Id: window-copy.c,v 1.124 2010/09/18 15:41:18 tcunha Exp $ */
+/* $Id: window-copy.c,v 1.127 2010/12/30 22:39:49 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <[email protected]>
@@ -52,7 +52,7 @@ void window_copy_goto_line(struct window_pane *, const char *);
void window_copy_update_cursor(struct window_pane *, u_int, u_int);
void window_copy_start_selection(struct window_pane *);
int window_copy_update_selection(struct window_pane *);
-void window_copy_copy_selection(struct window_pane *, struct session *);
+void window_copy_copy_selection(struct window_pane *);
void window_copy_clear_selection(struct window_pane *);
void window_copy_copy_line(<