1 Commits
1.0 ... 0.8

Author SHA1 Message Date
no_author
c23359e5d7 This commit was manufactured by cvs2svn to create tag 'TMUX_0_8'. 2009-04-21 20:10:23 +00:00
186 changed files with 8606 additions and 14295 deletions

162
CHANGES
View File

@@ -1,157 +1,3 @@
CHANGES FROM 0.9 TO 1.0, 20 Sept 2009
* Option to alter the format of the window title set by tmux.
* Backoff for a while after multiple incorrect password attempts.
* Quick display of pane numbers (C-b q).
* Better choose-window, choose-session commands and a new choose-client command.
* Option to request multiple responses when using command-prompt.
* Improved environment handling.
* Combine wrapped lines when pasting.
* Option to override terminal settings (terminal-overrides).
* Use the full range of ACS characters for drawing pane separator lines.
* Customisable mode keys.
* Status line colour options, with embedded colours in status-left/right, and
an option to centre the window list.
* Much improved layouts, including both horizontal and vertical splitting.
* Optional visual bell, activity and content indications.
* Set the utf8 and status-utf8 options when the server is started with -u.
* display-message command to show a message in the status line, by default some
information about the current window.
* Improved current process detection on NetBSD.
* unlink-window -k is now the same as kill-window.
* attach-session now works from inside tmux.
* A system-wide configuration file, /etc/tmux.conf.
* A number of new commands in copy mode, including searching.
* Panes are now specified using the target (-t) notation.
* -t now accepts fnmatch(3) patterns and looks for prefixes.
* Translate \r into \n when pasting.
* Support for binding commands to keys without the prefix key
* Support for alternate screen (terminfo smcup/rmcup).
* Maintain data that goes off screen after reducing the window size, so it can
be restored when the size is increased again.
* New if-shell command to test a shell command before running a tmux command.
* tmux now works as the shell.
* Man page reorganisation.
* Many minor additions, much code tidying and several bug fixes.
CHANGES FROM 0.8 TO 0.9, 01 July 2009
* Major changes to build infrastructure: cleanup of makefiles and addition
of a configure script.
* monitor-content window option to monitor a window for a specific fnmatch(3)
pattern. The find-window command also now accepts fnmatch(3) patterns.
* previous-layout and select-layout commands, and a main-horizontal layout.
* Recreate the server socket on SIGUSR1.
* clear-history command.
* Use ACS line drawing characters for pane separator lines.
* UTF-8 improvements, and code to detect UTF-8 support by looking at
environment variables.
* The resize-pane-up and resize-pane-down commands are now merged together
into a new resize-pane command with -U and -D flags.
* confirm-before command to request a yes/no answer before executing dangerous
commands.
* Status line bug fixes, support for UTF-8 (status-utf8 option), and a key to
paste from the paste buffer.
* Support for some additional escape sequences and terminal features, including
better support for insert mode and tab stops.
* Improved window resizing behaviour, modelled after xterm.
* Some code reduction and a number of miscellaneous bug fixes.
================================================================================
On 01 June 2009, tmux was imported into the OpenBSD base system. From this date
onward changes are logged as part of the normal CVS commit message to either
OpenBSD or SourceForge CVS. This file will be updated to contain a summary of
major changes with each release, and to mention important configuration or
command syntax changes during development.
The list of older changes is below.
================================================================================
21 May 2009
* stat(2) files before trying to load them to avoid problems, for example
with "source-file /dev/zero".
19 May 2009
* Try to guess if the window is UTF-8 by outputting a three-byte UTF-8 wide
character and seeing how much the cursor moves. Currently tries to figure out
if this works by some stupid checks on the terminal, these need to be
rethought. Also might be better using a width 1 character rather than width 2.
* If LANG contains "UTF-8", assume the terminal supports UTF-8, on the grounds
that anyone who configures it probably wants UTF-8. Not certain if this is
a perfect idea but let's see if it causes any problems.
* New window option: monitor-content. Searches for a string in a window and if
it matches, highlight the status line.
18 May 2009
* main-horizontal layout and main-pane-height option to match vertical.
* New window option main-pane-width to set the width of the large left pane with
main-vertical (was left-vertical) layout.
* Lots of layout cleanup. manual layout is now manual-vertical.
16 May 2009
* select-layout command and a few default key bindings (M-0, M-1, M-2, M-9) to
select layouts.
* Recreate server socket on SIGUSR1, per SF feature request 2792533.
14 May 2009
* Keys in status line (p in vi mode, M-y in emacs) to paste the first line
of the upper paste buffer. Suggested by Dan Colish.
* clear-history command to clear a pane's history.
* Don't force wrapping with \n when asked, let the cursor code figure it out.
Should fix terminals which use this to detect line breaks.
* Major cleanup and restructuring of build infrastructure. Still separate files
for GNU and BSD make, but they are now hugely simplified at the expense of
adding a configure script which must be run before make. Now build and
install with:
$ ./configure && make && sudo make install
04 May 2009
* Use ACS line drawing characters for pane separator lines.
30 April 2009
* Support command sequences without a space before the semicolon, for example
"neww; neww" now works as well as "neww ; neww". "neww;neww" is still an
error.
* previous-layout command.
* Display the layout name in window lists.
* Merge resize-pane-up and resize-pane-down into resize-pane with -U and -D
flags.
29 April 2009
* Get rid of compat/vis.* - only one function was used which is easily
replaced,and less compat code == good.
27 April 2009
* Avoid using the prompt history when the server is locked, and prevent any
input entered from being added to the client's prompt history.
* New command, confirm-before (alias confirm), which asks for confirmation
before executing a command. Bound "&" and "x" by default to confirm-before
"kill-window" and confirm-before "kill-pane", respectively.
23 April 2009
* Support NEL, yet another way of making newline. Fixes the output from some
Gentoo packaging thing. Reported by someone on SF then logs that allowed a
fix sent by tcunha.
* Use the xenl terminfo flag to detect early-wrap terminals like the FreeBSD
console. Many thanks for a very informative email from Christian Weisgerber.
21 April 2009
* tmux 0.8 released.
17 April 2009 17 April 2009
* Remove the right number of characters from the buffer when escape then * Remove the right number of characters from the buffer when escape then
@@ -401,7 +247,7 @@ The list of older changes is below.
18 January 2009 18 January 2009
* Unbreak UTF-8. * Unbreak UTF-8.
* -a flag to next-window and previous-window to select the next or previous * -a flag to next-window and previous-window to select the next or previous
window with activity or bell. Bound to M-n and M-p. window with activity or bell. Bound to M-n and M-p.
* find-window command to search window names, titles and visible content (but * find-window command to search window names, titles and visible content (but
not history) for a string. If only one is found, the window is selected not history) for a string. If only one is found, the window is selected
@@ -486,7 +332,7 @@ The list of older changes is below.
* Vertical window splitting. Currently can only split a window into two panes. * Vertical window splitting. Currently can only split a window into two panes.
New split-window command splits (bound to ") and switch-pane command (bound to New split-window command splits (bound to ") and switch-pane command (bound to
o) switches between panes. o) switches between panes.
close-pane, swap-pane commands are to follow. Also to come are pane resizing, close-pane, swap-pane commands are to follow. Also to come are pane resizing,
>2 panes, the ability to break a pane out to a full window and vice versa and >2 panes, the ability to break a pane out to a full window and vice versa and
@@ -505,7 +351,7 @@ The list of older changes is below.
* New option, lock-after-time. If there is no activity in the period specified * New option, lock-after-time. If there is no activity in the period specified
by this option (in seconds), tmux will lock the server. Default is 1800 (30 by this option (in seconds), tmux will lock the server. Default is 1800 (30
minutes), set to 0 to disable. minutes), set to 0 to disable.
* Server locking. Two new commands: set-password to set a password (a * Server locking. Two new commands: set-password to set a password (a
preencrypted password may be specified with -c); and lock-server to lock the preencrypted password may be specified with -c); and lock-server to lock the
server until the password is entered. Also an additional command line flag, server until the password is entered. Also an additional command line flag,
@@ -1358,7 +1204,7 @@ The list of older changes is below.
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.300 2009-09-20 18:54:21 nicm Exp $ $Id: CHANGES,v 1.272 2009-04-17 12:36:21 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr 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 LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms

65
FAQ
View File

@@ -42,17 +42,16 @@ include as much of the following information as possible:
Please send feature requests by email to nicm@users.sourceforge.net. Please send feature requests by email to nicm@users.sourceforge.net.
* Why do you use the screen terminal description inside tmux? It sucks. * Why do you use the screen termcap inside tmux? It sucks.
It is already widely available. It is planned to change to something else such It is already widely available. It is planned to change to something else
as xterm-xfree86 at some point, if possible. such as xterm-color at some point, if possible.
* I don't see any colour in my terminal! Help! * I don't see any colour in my terminal! Help!
On some platforms, common terminal descriptions such as xterm do not include On some platforms, common termcaps such as xterm do not include colour. screen
colour. screen ignores this, tmux does not. If the terminal emulator in use ignores this, tmux does not. If the terminal emulator in use supports colour,
supports colour, use a value for TERM which correctly lists this, such as use a termcap which correctly lists this, such as xterm-color.
xterm-color.
* tmux freezes my terminal when I attach to a session. I even have to kill -9 * tmux freezes my terminal when I attach to a session. I even have to kill -9
the shell it was started from to recover! the shell it was started from to recover!
@@ -88,27 +87,17 @@ for each tmux window or globally by setting the "utf8" flag:
setw -g utf8 on setw -g utf8 on
As of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by And, as it is not possible to automatically detect that a terminal is UTF-8
checking the LC_ALL, LC_CTYPE and LANG environment variables. list-clients may capable, tmux must be told by passing the -u flag when creating or
be used to check if this is detected correctly; if not, the -u command-line attaching a client to a tmux session:
flag may be specified when creating or attaching a client to a tmux session:
$ tmux -u new $ tmux -u new
* How do I use a 256 colour terminal? * How do I use a 256 colour terminal?
Provided the underlying terminal supports 256 colours, it is usually sufficient tmux will attempt to detect a 256 colour terminal both by looking at the Co
to add the following to ~/.tmux.conf: termcap entry and, as this is broken for some terminals such as xterm-256color,
by looking for the string "256col" in the termcap name.
set -g default-terminal "screen-256color"
Note that some platforms do not support "screen-256color" ("infocmp
screen-256color" will return an error) - in this case see the next entry in
this FAQ.
tmux attempts to detect a 256 colour terminal both by looking at the colors
terminfo entry and by looking for the string "256col" in the TERM environment
variable.
If both these methods fail, the -2 flag may be passed to tmux when attaching If both these methods fail, the -2 flag may be passed to tmux when attaching
to a session to indicate the terminal supports 256 colours. to a session to indicate the terminal supports 256 colours.
@@ -116,18 +105,22 @@ to a session to indicate the terminal supports 256 colours.
* vim or $otherprogram doesn't display 256 colours. What's up? * vim or $otherprogram doesn't display 256 colours. What's up?
Some programs attempt to detect the number of colours a terminal is capable of Some programs attempt to detect the number of colours a terminal is capable of
by checking the colors terminfo or Co termcap entry. However, this is not by checking the Co termcap entry. However, this is not reliable, and in any
reliable, and in any case is missing from the "screen" terminal description case is missing from the "screen" termcap used inside tmux.
used inside tmux.
There are two options (aside from using "screen-256color") to allow programs to There are three options to allow programs to recognise they are running on
recognise they are running on a 256-colour terminal inside tmux: a 256-colour terminal inside tmux:
- Manually force the application to use 256 colours always or if TERM is set to - Manually force the application to use 256 colours always or if TERM is set to
screen. For vim, you can do this by overriding the t_Co option, see screen. For vim, you can do this by overriding the t_Co option, see
http://vim.wikia.com/wiki/256_colors_in_vim. http://vim.wikia.com/wiki/256_colors_in_vim.
- Creating a custom terminfo file that includes colors#256 in ~/.terminfo and - If the platform includes it, using the "screen-256color" termcap (set
using it instead. These may be compiled with tic(1). TERM=screen-256color). "infocmp screen-256color" can be used to check if this
is supported. It is not currently possible to set this globally inside tmux
but it may be done in a shell startup script by checking if TERM is screen
and exporting TERM=screen-256color instead.
- Creating a custom terminfo file that includes Co#256 in ~/.terminfo and using
it instead. These may be compiled with tic(1).
* How do I make Ctrl-PgUp and Ctrl-PgDn work in vim? * How do I make Ctrl-PgUp and Ctrl-PgDn work in vim?
@@ -193,12 +186,4 @@ Automatic window renaming may use a lot of CPU, particularly on slow computers:
if this is a problem, turn it off with "setw -g automatic-rename off". If this if this is a problem, turn it off with "setw -g automatic-rename off". If this
doesn't fix it, please report the problem. doesn't fix it, please report the problem.
* I use PuTTY and my tmux window pane separators are all qqqqqqqqq's! $Id: FAQ,v 1.21 2009-03-31 23:17:28 nicm Exp $
PuTTY is using a character set translation that doesn't support ACS line
drawing. With a Unicode font, try setting PuTTY to use a different translation
on the Window -> Translation configuration page. For example, change UTF-8 to
ISO-8859-1 or CP437. It may also be necessary to adjust the way PuTTY treats
line drawing characters in the lower part of the same configuration page.
$Id: FAQ,v 1.29 2009-08-08 20:46:26 nicm Exp $

View File

@@ -1,65 +1,144 @@
# $Id: GNUmakefile,v 1.114 2009-09-20 18:54:21 nicm Exp $ # $Id: GNUmakefile,v 1.82 2009-04-21 20:10:22 nicm Exp $
.PHONY: clean .PHONY: clean
VERSION= 1.0 PROG= tmux
VERSION= 0.8
DATE= $(shell date +%Y%m%d-%H%M)
#FDEBUG= 1 #FDEBUG= 1
CC?= gcc META?= \002
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+=
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c \
screen.c screen-write.c screen-redraw.c \
grid.c grid-view.c \
window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
key-string.c key-bindings.c resize.c arg.c mode-key.c \
layout.c cmd.c cmd-generic.c cmd-string.c cmd-list.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \
cmd-refresh-client.c cmd-kill-window.c cmd-list-clients.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
cmd-rotate-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c util.c names.c \
osdep-unknown.c osdep-openbsd.c osdep-freebsd.c osdep-linux.c \
osdep-darwin.c attributes.c
CC?= gcc
INCDIRS+= -I. -I-
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\"" -DMETA="'${META}'"
ifdef FDEBUG ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG CFLAGS+= -g -ggdb -DDEBUG
LDFLAGS+= -rdynamic
LIBS+= -ldl
endif
ifeq (${CC},gcc)
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
endif endif
# This sort of sucks but gets rid of the stupid warning and should work on LDFLAGS+=
# most platforms... LIBS+= -lncurses
ifeq ($(shell (LC_ALL=C $(CC) -v 2>&1|awk '/gcc version 4|clang/') || true), )
CPPFLAGS:= -I. -I- $(CPPFLAGS)
else
CPPFLAGS:= -iquote. $(CPPFLAGS)
ifdef FDEBUG
CFLAGS+= -Wno-pointer-sign
endif
endif
PREFIX?= /usr/local PREFIX?= /usr/local
INSTALLDIR= install -d INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555 INSTALLBIN= install -g bin -o root -m 555
INSTALLMAN= install -g bin -o root -m 444 INSTALLMAN= install -g bin -o root -m 444
SRCS= $(shell echo *.c|sed 's|osdep-[a-z0-9]*.c||g') ifeq ($(shell uname),AIX)
include config.mk INCDIRS+= -I/usr/local/include/ncurses -Icompat
SRCS+= compat/vis.c compat/strlcpy.c compat/strlcat.c compat/strtonum.c \
compat/fgetln.c compat/asprintf.c compat/daemon.c compat/forkpty-aix.c \
compat/getopt_long.c compat/bsd-poll.c
CFLAGS+= -DNO_TREE_H -DNO_ASPRINTF -DNO_QUEUE_H -DNO_VSYSLOG \
-DNO_PROGNAME -DNO_STRLCPY -DNO_STRLCAT -DNO_STRTONUM \
-DNO_SETPROCTITLE -DNO_QUEUE_H -DNO_TREE_H -DNO_FORKPTY -DNO_FGETLN \
-DBROKEN_GETOPT -DBROKEN_POLL -DNO_PATHS_H
LDFLAGS+= -L/usr/local/lib
endif
ifeq ($(shell uname),IRIX64)
INCDIRS+= -Icompat -I/usr/local/include/ncurses
SRCS+= compat/strlcpy.c compat/strtonum.c compat/daemon.c \
compat/asprintf.c compat/fgetln.c compat/forkpty-irix.c
CFLAGS+= -DNO_STRLCPY -DNO_STRTONUM -DNO_TREE_H -DNO_SETPROCTITLE \
-DNO_DAEMON -DNO_FORKPTY -DNO_PROGNAME -DNO_ASPRINTF -DNO_FGETLN \
-DBROKEN_VSNPRINTF -D_SGI_SOURCE -std=c99
LDFLAGS+= -L/usr/local/lib
LIBS+= -lgen
endif
ifeq ($(shell uname),SunOS)
INCDIRS+= -Icompat -I/usr/local/include/ncurses
SRCS+= compat/strtonum.c compat/daemon.c compat/forkpty-sunos.c \
compat/asprintf.c compat/fgetln.c compat/vis.c
CFLAGS+= -DNO_STRTONUM -DNO_TREE_H -DNO_PATHS_H -DNO_SETPROCTITLE \
-DNO_DAEMON -DNO_FORKPTY -DNO_PROGNAME -DNO_ASPRINTF -DNO_FGETLN
LDFLAGS+= -L/usr/local/lib
LIBS+= -lsocket -lnsl
endif
ifeq ($(shell uname),Darwin)
INCDIRS+= -Icompat
SRCS+= compat/strtonum.c compat/bsd-poll.c compat/vis.c
CFLAGS+= -DNO_STRTONUM -DNO_SETRESUID -DNO_SETRESGID -DNO_SETPROCTITLE \
-DNO_QUEUE_H -DNO_TREE_H -DBROKEN_POLL
endif
ifeq ($(shell uname),Linux)
INCDIRS+= -Icompat
SRCS+= compat/strlcpy.c compat/strlcat.c compat/strtonum.c \
compat/fgetln.c compat/getopt_long.c compat/vis.c
CFLAGS+= $(shell getconf LFS_CFLAGS) -D_GNU_SOURCE \
-DNO_STRLCPY -DNO_STRLCAT -DNO_STRTONUM -DNO_SETPROCTITLE \
-DNO_QUEUE_H -DNO_TREE_H -DUSE_PTY_H -DNO_FGETLN \
-DBROKEN_GETOPT -std=c99
LIBS+= -lcrypt -lutil
endif
OBJS= $(patsubst %.c,%.o,$(SRCS)) OBJS= $(patsubst %.c,%.o,$(SRCS))
all: tmux CLEANFILES= ${PROG} *.o .depend *~ ${PROG}.core *.log compat/*.o index.html
tmux: $(OBJS) CPPFLAGS:= ${INCDIRS} ${CPPFLAGS}
$(CC) $(LDFLAGS) -o tmux $+ $(LIBS)
depend: $(SRCS) all: $(PROG)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
$(PROG): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $+ $(LIBS)
depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
install:
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/bin
$(INSTALLBIN) $(PROG) $(DESTDIR)$(PREFIX)/bin/$(PROG)
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) $(PROG).1 $(DESTDIR)$(PREFIX)/man/man1/$(PROG).1
clean: clean:
rm -f tmux *.o *~ *.core *.log compat/*.o rm -f $(CLEANFILES)
clean-depend:
rm -f .depend
clean-all: clean clean-depend
rm -f config.h config.mk
install: all
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/bin
$(INSTALLBIN) tmux $(DESTDIR)$(PREFIX)/bin/tmux
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) tmux.1 $(DESTDIR)$(PREFIX)/man/man1/tmux.1
-include .depend

160
Makefile
View File

@@ -1,68 +1,158 @@
# $Id: Makefile,v 1.149 2009-09-20 18:54:21 nicm Exp $ # $Id: Makefile,v 1.121 2009-04-21 20:10:22 nicm Exp $
.SUFFIXES: .c .o .SUFFIXES: .c .o .y .h
.PHONY: clean .PHONY: clean update-index.html upload-index.html
VERSION= 1.0 PROG= tmux
VERSION= 0.8
OS!= uname
REL!= uname -r
DATE!= date +%Y%m%d-%H%M
#FDEBUG= 1 #FDEBUG= 1
CC?= cc META?= \002 # C-b
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+=
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c \
screen.c screen-write.c screen-redraw.c \
grid.c grid-view.c \
window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
layout.c key-string.c key-bindings.c resize.c arg.c mode-key.c \
cmd.c cmd-generic.c cmd-string.c cmd-list.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \
cmd-refresh-client.c cmd-kill-window.c cmd-list-clients.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
cmd-rotate-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c util.c names.c attributes.c \
osdep-unknown.c osdep-openbsd.c osdep-freebsd.c osdep-linux.c \
osdep-darwin.c osdep-netbsd.c
CC?= c
INCDIRS+= -I. -I- -I/usr/local/include
CFLAGS+= -DMETA="'${META}'"
.ifdef PROFILE
# Don't use ccache
CC= /usr/bin/gcc
CFLAGS+= -pg -DPROFILE -O0
.endif
.ifdef FDEBUG .ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG CFLAGS+= -g -ggdb -DDEBUG
LDFLAGS+= -Wl,-E
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\""
.else
CFLAGS+= -DBUILD="\"$(VERSION)\""
.endif
#CFLAGS+= -pedantic -std=c99
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align 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 PREFIX?= /usr/local
INSTALLDIR= install -d INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555 INSTALLBIN= install -g bin -o root -m 555
INSTALLMAN= install -g bin -o root -m 444 INSTALLMAN= install -g bin -o root -m 444
SRCS!= echo *.c|sed 's|osdep-[a-z0-9]*.c||g' LDFLAGS+= -L/usr/local/lib
.include "config.mk" .ifdef PROFILE
OBJS= ${SRCS:S/.c/.o/} LDFLAGS+= -pg
.endif
LIBS+= -lutil -lncurses
# FreeBSD and DragonFly
.if ${OS} == "FreeBSD" || ${OS} == "DragonFly"
INCDIRS+= -Icompat
SRCS+= compat/vis.c
CFLAGS+= -DUSE_LIBUTIL_H -DNO_QUEUE_H -DNO_TREE_H
LIBS+= -lcrypt
.endif
# NetBSD
.if ${OS} == "NetBSD"
INCDIRS= -Icompat
SRCS+= compat/strtonum.c compat/vis.c
LIBS+= -lcrypt
CFLAGS+=-DNO_STRTONUM
.endif
OBJS= ${SRCS:S/.c/.o/:S/.y/.o/}
DISTDIR= ${PROG}-${VERSION}
DISTFILES= *.[chyl] Makefile GNUmakefile *.[1-9] NOTES TODO CHANGES FAQ \
`find examples compat -type f -and ! -path '*CVS*'`
CLEANFILES= ${PROG} *.o .depend *~ ${PROG}.core *.log compat/*.o index.html
CPPFLAGS:= ${INCDIRS} ${CPPFLAGS}
.c.o: .c.o:
${CC} ${CPPFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${CC} ${CPPFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
all: tmux .y.o:
${YACC} ${.IMPSRC}
${CC} ${CPPFLAGS} ${CFLAGS} -c y.tab.c -o ${.TARGET}
tmux: ${OBJS} all: ${PROG}
${CC} ${LDFLAGS} -o tmux ${OBJS} ${LIBS}
${PROG}: ${OBJS}
${CC} ${LDFLAGS} -o ${PROG} ${OBJS} ${LIBS}
depend: depend:
mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c} mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
dist: clean
grep '^#FDEBUG=' Makefile
grep '^#FDEBUG=' GNUmakefile
[ "`(grep '^VERSION' Makefile; grep '^VERSION' GNUmakefile)| \
uniq -u`" = "" ]
tar -zc \
-s '/.*/${DISTDIR}\/\0/' \
-f ${DISTDIR}.tar.gz ${DISTFILES}
lint:
lint -chvx ${CFLAGS:M-D*} ${SRCS:M*.c}
clean: clean:
rm -f tmux *.o *~ *.core *.log compat/*.o rm -f ${CLEANFILES}
clean-depend: upload-index.html: update-index.html
rm -f .depend scp index.html images/*.png \
nicm,tmux@web.sf.net:/home/groups/t/tm/tmux/htdocs
rm -f images/small-*
clean-all: clean clean-depend update-index.html:
rm -f config.h config.mk (cd images && \
rm -f small-* && \
for i in *.png; do \
convert "$$i" -resize 200x150 "small-$$i"; \
done \
)
sed "s/%%VERSION%%/${VERSION}/g" index.html.in >index.html
install: all install: all
${INSTALLDIR} ${DESTDIR}${PREFIX}/bin ${INSTALLDIR} ${DESTDIR}${PREFIX}/bin
${INSTALLBIN} tmux ${DESTDIR}${PREFIX}/bin/ ${INSTALLBIN} ${PROG} ${DESTDIR}${PREFIX}/bin/
${INSTALLDIR} ${DESTDIR}${PREFIX}/man/man1 ${INSTALLDIR} ${DESTDIR}${PREFIX}/man/man1
${INSTALLMAN} tmux.1 ${DESTDIR}${PREFIX}/man/man1/ ${INSTALLMAN} ${PROG}.1 ${DESTDIR}${PREFIX}/man/man1/

29
NOTES
View File

@@ -4,10 +4,9 @@ tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen. simple, modern, BSD-licensed alternative to programs such as GNU screen.
This 0.9 release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still This 0.8 release runs on OpenBSD, FreeBSD, Linux and OS X and may still run on
run on Solaris and AIX (although they hasn't been tested in a while). It is Solaris (although it hasn't been tested in a while). It is usable, although
usable, although there remain a number of missing features and some remaining there remain a number of missing features and some remaining bugs are expected.
bugs are expected.
If upgrading from 0.5, PLEASE NOTE the following configuration file changes: it If upgrading from 0.5, PLEASE NOTE the following configuration file changes: it
is now required to pass the -g flag to set-option or set-window-option to set is now required to pass the -g flag to set-option or set-window-option to set
@@ -41,6 +40,11 @@ The following is a summary of major features implemented in this version:
- A configuration file. - A configuration file.
- UTF-8 support. - UTF-8 support.
And major missing features:
- Proper mouse support.
- No support for programs changing termios(4) settings or other tty(4) ioctls.
A more extensive, but rough, todo list is included in the TODO file. 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 tmux also depends on several features of the client terminal (TERM), if these
@@ -51,10 +55,8 @@ xterm-color or rxvt for colour.
tmux supports UTF-8. To use it, the utf8 option must be set on each window; 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 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 tmux(1) and the FAQ file. In addition, when starting tmux or attaching to an
UTF-8-capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment existing session from a UTF-8-capable terminal, the -u flag must be specified.
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: A Vim syntax file is available in the examples directory. To install it:
@@ -72,6 +74,15 @@ A Vim syntax file is available in the examples directory. To install it:
For debugging, running tmux with -v or -vv will generate server and client log For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory. files in the current directory.
The CVS HEAD version of tmux often has additional features from the release
versions; if interested, testing it is encouraged. It can be obtained by
anonymous CVS from SourceForge:
$ cvs -d:pserver:anoncvs@tmux.cvs.sf.net:/cvsroot/tmux co tmux
If running CVS HEAD, please note it is development code and there may be bugs
and undocumented features; please read the CHANGES file for information.
tmux mailing lists are available; visit: tmux mailing lists are available; visit:
https://sourceforge.net/mail/?group_id=200378 https://sourceforge.net/mail/?group_id=200378
@@ -83,4 +94,4 @@ welcome. Please send by email to:
-- Nicholas Marriott <nicm@users.sf.net> -- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.49 2009-07-06 18:53:24 nicm Exp $ $Id: NOTES,v 1.45 2009-04-21 20:06:12 nicm Exp $

147
TODO
View File

@@ -1,21 +1,39 @@
- line mode/char-at-a-time mode a la telnet?
- handle ioctl/termios stuff on window sockets
- figure out once and for all what is going on with backspace and del
backspace should be translated per the termios setting.
del passed through?
- window creation/idle time - window creation/idle time
- profile/optimise, particularly (i suspect) input.c
- could use bsearch all over the place or get rid of smaller tables (clientmsg)
- better errors when creating new windows/sessions (how?) - better errors when creating new windows/sessions (how?)
- implicitly add exec to the commands for new windows (switch to disable it)? - 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 - it would be nice to have multichar commands so you could have C-b K K for
kill-window to limit accidental presses
- commands: - commands:
extend list-clients to list clients attached to a session (-a for all?) extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session? bring back detach-session to detach all clients on a session?
clone-session command to link all windows to a new session
- allow fnmatch for -c, so that you can, eg, detach all clients - allow fnmatch for -c, so that you can, eg, detach all clients
- bind non prefix keys
- garbage collect window history (100 lines at a time?) if it hasn't been used - 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 (need window creation/use times)
- lift SHRT_MAX limits for history? - lift SHRT_MAX limits for history
- better mode features: search - audit copy/scroll and other modes for problems with very small windows
- split clients into three RB trees by fd: attached/unattached/dead?
or tailqs? what would be fastest per-char?
- c/p is still borken in some ways
- better mode features: search, back word, forward word, etc
- flags to centre screen in window - flags to centre screen in window
- better terminal emulation - better terminal emulation (identify, insert mode, some other bits)
- when resizing, use history
- audit for leftover/unused code
- activity/bell should be per-window not per-link? what if it is cur win in - activity/bell should be per-window not per-link? what if it is cur win in
session not being watched? session not being watched?
- tidy up window modes
- next prev word etc in command prompt; also ^K - next prev word etc in command prompt; also ^K
- many more info() displays for various things - many more info() displays for various things
- vi half page scroll
- backspace should perhaps wrap backwards over newlines which were not moved - backspace should perhaps wrap backwards over newlines which were not moved
down by a newline: screen and the OS X terminal does this but xterm and most down by a newline: screen and the OS X terminal does this but xterm and most
others do not. this might be hard: a flag for each grid line (top bit of size others do not. this might be hard: a flag for each grid line (top bit of size
@@ -23,84 +41,63 @@
unwrapping unwrapping
- input.c is too complicated. simplify? - input.c is too complicated. simplify?
- use a better termcap internally instead of screen, perhaps xterm - use a better termcap internally instead of screen, perhaps xterm
- a command to display the status line briefly when it is turned off
- FAQ "Can I have some examples of cool things I can do with tmux?" -- linkw,
more??
- kill all but current pane - kill all but current pane
- fix rxvt cursor fg issue (text under cursor can have non-white fg) - fix rxvt cursor fg issue (text under cursor can have non-white fg)
- key handling sucks a bit and needs to be reworked
- some people find first window being 0 rather than 1 is awkward on the
keyboard. what about a new-window-index option that sets the base at which
tmux starts numbering new windows, then they can do: set -g new-window-index
1; bind 0 selectw -t:10
- some way to change status line colours based on something? command?
- client sx/sy should be in tty, then can let the terminal wrap at edge - client sx/sy should be in tty, then can let the terminal wrap at edge
to allow xterm to pick up it should be one line for its c/p to allow xterm to pick up it should be one line for its c/p
- should be able to move to a hidden pane and it would be moved into view. pane - 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 number in status line/top-right would be cool for this
- support other mouse modes (highlight etc) and use it in copy mode - command to run something without a window at all - output to
window-more. what for? isnt this the same as doing it w/ splitw/neww now?
- command to purge window history? or apply history-limit changes?
- clone session command
- make command sequences more usable: don't require space around ;, handle
errors better
- would be nice if tmux could be the shell (tmux attach, but hard link to tmux
binary as "tmuxsh" or wrapper script?) -- problems with tty dev permissions
- support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically? - 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 - set-option should be set-session-option and should be overall global options
for stuff like mode keys? for stuff like mode keys?
also quiet, utf8 and maybe other flags? - a confirm-before command which asks "Are you sure? (y/n)" before executing
-g is a bit unexpected in conf file command, eg bind-key "&" confirm-before "kill-window"
- clear window title on exit - might be nice if attach-session behaved like switch-client inside an
- the output code (tty.c) could do with optimisation depending on term existing client
capibilities
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- goto line and search history in copy/scroll modes
- clone session command
- make command sequences more usable: don't require space after ;, handle
errors better
- key to switch to copy mode from scroll mode - key to switch to copy mode from scroll mode
- attach should have a flag to create session if it doesn't exist - attach should have a flag to create session if it doesn't exist
- rename split-window -> split-pane?? - clear window title on exit
- fix UTF-8 guesswork on sparc64, improve tty checks - better support for stupid margin terminals. strcmp for cons25 sucks, how can
- choice and more mode would be better per client than per window? these be autodetected?
- hooks to which commands may be attached, for example: tmux add-hook - refer to windows by name etc (duplicates? fnmatch?)
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file - the output code (tty.c) could do with optimisation depending on term
$HOME/.tmux-session.conf capibilities
- get it passing all the vttest tests that don't require resizing the terminal - resize-pane-up/down should be resize-pane -U/-D. ditto up-pane/down-pane
- esc seq to set window title should be documented and should set should be select-pane -U/-D
automatic-rename - layout/split stuff:
- way to set socket path from config file horiz split command, and similar resizing commands as for vert split
- XXX once env stuff is in, default-path and VISUAL/EDITOR should be picked up display the layout in a readable format somewhere
when session is started previous-layout command
- what about utmp etc? can tmux update it like screen? setgid? select-layout command
- H/M/L commands in copy mode with vi-keys, for jumping to the top/middle/last make manual layout a bit less of a hack and make it handle a grid
line on the screen should the layout be a window option???
- split list-windows into separate list-windows and list-panes more layouts
- warts on current naming: better resizing of shells when changing layout
- display-time but message-fg/bg/attr find and fix bug with clear screen after horiz split
- list-* vs show-* speed improvements? -- still too slow over ssh!
- server-info hardcoded 81 for left-vertical is nasty
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-* - test bug sshing from freebsd console (tom iirc?)
- pcvt25 doesn't work properly, why? (bce?) - fix build on solaris 10
- tidy up and prioritise todo list ;-) - rotate-window has redraw bugs... :-/
- it is only possible to specify 8 colours to fg/bg options; should be able to
set 256 as well (hopefully) for 0.8, in no particular order:
- neww and attach can create a session if none exists? - nothing!
would work fine with config file since
- a way for force-width/height to apply to only one pane (how?)
- **** a command to run something without a window and send any output to the
window-more. if no output, info() a line saying "'%s' returned %d". so i can
bind mpc control commands to function keys ;-)
- command to list what is actually running in each window with command line,
pid (need some adaption of the osdep code)
- string option to change/remove the symbols (*-+ etc) in status line
- support for bce
- it would be nice if the start/end line keys in copy mode were aware of
wrapped lines
- per session locking
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
-- idea of a "view" onto a window, need base x/y offsets
for redraw
- a window option which means data is echoed to all panes in a window
- support running tmux from inside tmux [#(), if-shell] --
generic system-like function which may take a callback
also sets up environment (TMUX) and has a timeout
for #(): command schedular, status line queues it with a time, run in
main loop, and uses most recent result -- can also be used for persistent
commands which never exit just continually output
for if-shell, callback??
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- fix line wrapping c&p problems in xterm etc
- a way to address panes by name ("top-left") and position ("0,0")
- ability to specify multiple prefix keys
- commands should be able to succeed or fail and have || or && for command
lists
- support the mouse wheel to scroll through history

194
arg.c Normal file
View File

@@ -0,0 +1,194 @@
/* $Id: arg.c,v 1.5 2008-08-28 17:45:25 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <fnmatch.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
struct client *arg_lookup_client(const char *);
struct session *arg_lookup_session(const char *);
struct client *
arg_lookup_client(const char *name)
{
struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && strcmp(name, c->tty.path) == 0)
return (c);
}
return (NULL);
}
struct session *
arg_lookup_session(const char *name)
{
struct session *s, *newest = NULL;
struct timeval *tv;
u_int i;
tv = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL || fnmatch(name, s->name, 0) != 0)
continue;
if (tv == NULL || timercmp(&s->tv, tv, >)) {
newest = s;
tv = &s->tv;
}
}
return (newest);
}
struct client *
arg_parse_client(const char *arg)
{
struct client *c;
char *arg2;
size_t n;
if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* Try and look up the client name. */
c = arg_lookup_client(arg2);
xfree(arg2);
return (c);
}
return (NULL);
}
struct session *
arg_parse_session(const char *arg)
{
struct session *s;
struct client *c;
char *arg2;
size_t n;
if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
arg2 = xstrdup(arg);
/* Trim a trailing : if any from the argument. */
n = strlen(arg2);
if (arg2[n - 1] == ':')
arg2[n - 1] = '\0';
/* See if the argument matches a session. */
if ((s = arg_lookup_session(arg2)) != NULL) {
xfree(arg2);
return (s);
}
/* If not try a client. */
if ((c = arg_lookup_client(arg2)) != NULL) {
xfree(arg2);
return (c->session);
}
xfree(arg2);
}
return (NULL);
}
int
arg_parse_window(const char *arg, struct session **s, int *idx)
{
char *arg2, *ptr;
const char *errstr;
*idx = -1;
/* Handle no argument or a single :. */
if (arg == NULL || (arg[0] == ':' && arg[1] == '\0')) {
*s = arg_parse_session(NULL);
return (0);
}
/* Find the separator if any. */
arg2 = xstrdup(arg);
ptr = strrchr(arg2, ':');
/*
* If it is first, this means no session name, so use current session
* and try to convert the rest as index.
*/
if (ptr == arg2) {
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}
xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}
/* If missing, try as an index, else look up immediately. */
if (ptr == NULL) {
*idx = strtonum(arg2, 0, INT_MAX, &errstr);
if (errstr == NULL) {
/* This is good as an index; use current session. */
xfree(arg2);
*s = arg_parse_session(NULL);
return (0);
}
*idx = -1;
goto lookup;
}
/* If last, strip it and look up as a session. */
if (ptr[1] == '\0') {
*ptr = '\0';
goto lookup;
}
/* Present but not first and not last. Break and convert both. */
*ptr = '\0';
*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
if (errstr != NULL) {
xfree(arg2);
return (1);
}
lookup:
/* Look up as session. */
*s = arg_parse_session(arg2);
xfree(arg2);
if (*s == NULL)
return (1);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: attributes.c,v 1.2 2009-06-25 15:25:45 nicm Exp $ */ /* $Id: attributes.c,v 1.1 2009-01-27 20:22:33 nicm Exp $ */
/* /*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org> * Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -45,8 +45,7 @@ attributes_tostring(u_char ch)
strlcat(buf, "hidden,", sizeof (buf)); strlcat(buf, "hidden,", sizeof (buf));
if (ch & GRID_ATTR_ITALICS) if (ch & GRID_ATTR_ITALICS)
strlcat(buf, "italics,", sizeof (buf)); strlcat(buf, "italics,", sizeof (buf));
if (*buf) *(strrchr(buf, ',')) = '\0';
*(strrchr(buf, ',')) = '\0';
return (buf); return (buf);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: buffer-poll.c,v 1.16 2009-08-19 09:28:10 nicm Exp $ */ /* $Id: buffer-poll.c,v 1.10 2008-09-09 22:16:36 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,17 +23,39 @@
#include "tmux.h" #include "tmux.h"
/* Set up pollfd for buffers. */
void
buffer_set(
struct pollfd *pfd, int fd, unused struct buffer *in, struct buffer *out)
{
pfd->fd = fd;
pfd->events = POLLIN;
if (BUFFER_USED(out) > 0)
pfd->events |= POLLOUT;
}
/* Fill buffers from socket based on poll results. */ /* Fill buffers from socket based on poll results. */
int int
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out) buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
{ {
ssize_t n; ssize_t n;
#if 0
log_debug("buffer_poll (%ld): fd=%d, revents=%d; out=%zu in=%zu",
(long) getpid(),
pfd->fd, pfd->revents, BUFFER_USED(out), BUFFER_USED(in));
#endif
#ifndef BROKEN_POLL
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP)) if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
return (-1); return (-1);
#endif
if (pfd->revents & POLLIN) { if (pfd->revents & POLLIN) {
buffer_ensure(in, BUFSIZ); buffer_ensure(in, BUFSIZ);
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in)); n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
#if 0
log_debug("buffer_poll: fd=%d, read=%zd", pfd->fd, n);
#endif
if (n == 0) if (n == 0)
return (-1); return (-1);
if (n == -1) { if (n == -1) {
@@ -44,6 +66,9 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
} }
if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) { if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out)); n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
#if 0
log_debug("buffer_poll: fd=%d, write=%zd", pfd->fd, n);
#endif
if (n == -1) { if (n == -1) {
if (errno != EINTR && errno != EAGAIN) if (errno != EINTR && errno != EAGAIN)
return (-1); return (-1);
@@ -52,3 +77,23 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
} }
return (0); return (0);
} }
/* Flush buffer output to socket. */
void
buffer_flush(int fd, struct buffer *in, struct buffer *out)
{
struct pollfd pfd;
while (BUFFER_USED(out) > 0) {
buffer_set(&pfd, fd, in, out);
if (poll(&pfd, 1, INFTIM) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
if (buffer_poll(&pfd, in, out) != 0)
break;
}
}

View File

@@ -1,4 +1,4 @@
/* $Id: buffer.c,v 1.8 2009-08-21 21:09:13 tcunha Exp $ */ /* $Id: buffer.c,v 1.5 2008-08-07 20:20:52 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,6 +47,14 @@ buffer_destroy(struct buffer *b)
xfree(b); xfree(b);
} }
/* Empty a buffer. */
void
buffer_clear(struct buffer *b)
{
b->size = 0;
b->off = 0;
}
/* Ensure free space for size in buffer. */ /* Ensure free space for size in buffer. */
void void
buffer_ensure(struct buffer *b, size_t size) buffer_ensure(struct buffer *b, size_t size)
@@ -83,6 +91,18 @@ buffer_add(struct buffer *b, size_t size)
b->size += size; b->size += size;
} }
/* Reverse buffer add. */
void
buffer_reverse_add(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
b->size -= size;
}
/* Adjust buffer after data removed. */ /* Adjust buffer after data removed. */
void void
buffer_remove(struct buffer *b, size_t size) buffer_remove(struct buffer *b, size_t size)
@@ -96,10 +116,57 @@ buffer_remove(struct buffer *b, size_t size)
b->off += size; b->off += size;
} }
/* Reverse buffer remove. */
void
buffer_reverse_remove(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->off)
fatalx("overflow");
b->size += size;
b->off -= size;
}
/* Insert a section into the buffer. */
void
buffer_insert_range(struct buffer *b, size_t base, size_t size)
{
if (size == 0)
fatalx("zero size");
if (base > b->size)
fatalx("range outside buffer");
buffer_ensure(b, size);
memmove(b->base + b->off + base + size,
b->base + b->off + base, b->size - base);
b->size += size;
}
/* Delete a section from the buffer. */
void
buffer_delete_range(struct buffer *b, size_t base, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("size too big");
if (base + size > b->size)
fatalx("range outside buffer");
memmove(b->base + b->off + base,
b->base + b->off + base + size, b->size - base - size);
b->size -= size;
}
/* Copy data into a buffer. */ /* Copy data into a buffer. */
void void
buffer_write(struct buffer *b, const void *data, size_t size) buffer_write(struct buffer *b, const void *data, size_t size)
{ {
if (size == 0)
fatalx("zero size");
buffer_ensure(b, size); buffer_ensure(b, size);
memcpy(BUFFER_IN(b), data, size); memcpy(BUFFER_IN(b), data, size);
buffer_add(b, size); buffer_add(b, size);
@@ -124,7 +191,17 @@ buffer_write8(struct buffer *b, uint8_t n)
{ {
buffer_ensure(b, 1); buffer_ensure(b, 1);
BUFFER_IN(b)[0] = n; BUFFER_IN(b)[0] = n;
b->size++; buffer_add(b, 1);
}
/* Store a 16-bit value. */
void
buffer_write16(struct buffer *b, uint16_t n)
{
buffer_ensure(b, 2);
BUFFER_IN(b)[0] = n & 0xff;
BUFFER_IN(b)[1] = n >> 8;
buffer_add(b, 2);
} }
/* Extract an 8-bit value. */ /* Extract an 8-bit value. */
@@ -137,3 +214,14 @@ buffer_read8(struct buffer *b)
buffer_remove(b, 1); buffer_remove(b, 1);
return (n); return (n);
} }
/* Extract a 16-bit value. */
uint16_t
buffer_read16(struct buffer *b)
{
uint16_t n;
n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8);
buffer_remove(b, 2);
return (n);
}

22
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.22 2009-08-24 16:27:03 tcunha Exp $ */ /* $Id: cfg.c,v 1.15 2009-03-31 22:23:43 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -17,7 +17,6 @@
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -30,6 +29,7 @@
* argv array and executed as a command. * argv array and executed as a command.
*/ */
char *cfg_string(FILE *, char, int);
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...); void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
@@ -51,7 +51,7 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
} }
int int
load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause) load_cfg(const char *path, char **cause)
{ {
FILE *f; FILE *f;
u_int n; u_int n;
@@ -87,20 +87,16 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
continue; continue;
cfg_cause = NULL; cfg_cause = NULL;
if (ctxin == NULL) { ctx.msgdata = NULL;
ctx.msgdata = NULL; ctx.cursession = NULL;
ctx.curclient = NULL; ctx.curclient = NULL;
ctx.cmdclient = NULL;
} else {
ctx.msgdata = ctxin->msgdata;
ctx.curclient = ctxin->curclient;
ctx.cmdclient = ctxin->cmdclient;
}
ctx.error = cfg_error; ctx.error = cfg_error;
ctx.print = cfg_print; ctx.print = cfg_print;
ctx.info = cfg_print; ctx.info = cfg_print;
ctx.cmdclient = NULL;
cfg_cause = NULL; cfg_cause = NULL;
cmd_list_exec(cmdlist, &ctx); cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist); cmd_list_free(cmdlist);
@@ -116,8 +112,6 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
return (0); return (0);
error: error:
if (line != NULL)
xfree(line);
fclose(f); fclose(f);
xasprintf(&ptr, "%s: %s at line %u", path, *cause, n); xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);

View File

@@ -1,4 +1,4 @@
/* $Id: client-fn.c,v 1.10 2009-08-14 21:04:04 tcunha Exp $ */ /* $Id: client-fn.c,v 1.6 2009-03-04 17:24:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,7 +20,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -64,27 +63,30 @@ client_fill_session(struct msg_command_data *data)
void void
client_write_server( client_write_server(
struct client_ctx *cctx, enum msgtype type, void *buf, size_t len) struct client_ctx *cctx, enum hdrtype type, void *buf, size_t len)
{ {
imsg_compose(&cctx->ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len); struct hdr hdr;
hdr.type = type;
hdr.size = len;
buffer_write(cctx->srv_out, &hdr, sizeof hdr);
if (buf != NULL && len > 0)
buffer_write(cctx->srv_out, buf, len);
} }
void void
client_suspend(void) client_write_server2(struct client_ctx *cctx,
enum hdrtype type, void *buf1, size_t len1, void *buf2, size_t len2)
{ {
struct sigaction act; struct hdr hdr;
memset(&act, 0, sizeof act); hdr.type = type;
sigemptyset(&act.sa_mask); hdr.size = len1 + len2;
act.sa_flags = SA_RESTART; buffer_write(cctx->srv_out, &hdr, sizeof hdr);
act.sa_handler = SIG_DFL; if (buf1 != NULL && len1 > 0)
if (sigaction(SIGTSTP, &act, NULL) != 0) buffer_write(cctx->srv_out, buf1, len1);
fatal("sigaction failed"); if (buf2 != NULL && len2 > 0)
buffer_write(cctx->srv_out, buf2, len2);
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
} }

159
client-msg.c Normal file
View File

@@ -0,0 +1,159 @@
/* $Id: client-msg.c,v 1.18 2009-01-21 22:47:31 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_shutdown(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_exited(struct hdr *, struct client_ctx *, char **);
int client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **);
struct client_msg {
enum hdrtype type;
int (*fn)(struct hdr *, struct client_ctx *, char **);
};
struct client_msg client_msg_table[] = {
{ MSG_DETACH, client_msg_fn_detach },
{ MSG_ERROR, client_msg_fn_error },
{ MSG_EXIT, client_msg_fn_exit },
{ MSG_EXITED, client_msg_fn_exited },
{ MSG_SHUTDOWN, client_msg_fn_shutdown },
{ MSG_SUSPEND, client_msg_fn_suspend },
};
int
client_msg_dispatch(struct client_ctx *cctx, char **error)
{
struct hdr hdr;
struct client_msg *msg;
u_int i;
if (BUFFER_USED(cctx->srv_in) < sizeof hdr)
return (1);
memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr);
if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size)
return (1);
buffer_remove(cctx->srv_in, sizeof hdr);
for (i = 0; i < nitems(client_msg_table); i++) {
msg = client_msg_table + i;
if (msg->type == hdr.type) {
if (msg->fn(&hdr, cctx, error) != 0)
return (-1);
return (0);
}
}
fatalx("unexpected message");
}
int
client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
{
if (hdr->size > SIZE_MAX - 1)
fatalx("bad MSG_ERROR size");
*error = xmalloc(hdr->size + 1);
buffer_read(cctx->srv_in, *error, hdr->size);
(*error)[hdr->size] = '\0';
return (-1);
}
int
client_msg_fn_detach(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_DETACH size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_DETACH;
return (0);
}
int
client_msg_fn_shutdown(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_SHUTDOWN;
return (0);
}
int
client_msg_fn_exit(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_EXIT size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_EXIT;
return (0);
}
int
client_msg_fn_exited(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
if (hdr->size != 0)
fatalx("bad MSG_EXITED size");
return (-1);
}
int
client_msg_fn_suspend(
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
{
struct sigaction act;
if (hdr->size != 0)
fatalx("bad MSG_SUSPEND size");
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
act.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &act, NULL) != 0)
fatal("sigaction failed");
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
return (0);
}

232
client.c
View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.70 2009-09-03 21:06:30 tcunha Exp $ */ /* $Id: client.c,v 1.46 2009-03-31 22:20:42 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,32 +33,23 @@
#include "tmux.h" #include "tmux.h"
void client_send_environ(struct client_ctx *);
void client_handle_winch(struct client_ctx *); void client_handle_winch(struct client_ctx *);
int int
client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags) client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
{ {
struct sockaddr_un sa; struct sockaddr_un sa;
struct stat sb; struct stat sb;
struct msg_identify_data data; struct msg_identify_data data;
struct winsize ws; struct winsize ws;
size_t size; size_t size;
int fd, fd2, mode; int mode;
char *name, *term; struct buffer *b;
#ifdef HAVE_SETPROCTITLE char *name;
char rpathbuf[MAXPATHLEN];
#endif
#ifdef HAVE_SETPROCTITLE
if (realpath(path, rpathbuf) == NULL)
strlcpy(rpathbuf, path, sizeof rpathbuf);
setproctitle("client (%s)", rpathbuf);
#endif
if (lstat(path, &sb) != 0) { if (lstat(path, &sb) != 0) {
if (cmdflags & CMD_STARTSERVER && errno == ENOENT) { if (start_server && errno == ENOENT) {
if ((fd = server_start(path)) == -1) if ((cctx->srv_fd = server_start(path)) == -1)
goto start_failed; goto start_failed;
goto server_started; goto server_started;
} }
@@ -77,14 +68,15 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
goto not_found; goto not_found;
} }
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket"); fatal("socket");
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) { if (connect(
cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
if (errno == ECONNREFUSED) { if (errno == ECONNREFUSED) {
if (unlink(path) != 0 || !(cmdflags & CMD_STARTSERVER)) if (unlink(path) != 0 || !start_server)
goto not_found; goto not_found;
if ((fd = server_start(path)) == -1) if ((cctx->srv_fd = server_start(path)) == -1)
goto start_failed; goto start_failed;
goto server_started; goto server_started;
} }
@@ -92,40 +84,34 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
} }
server_started: server_started:
if ((mode = fcntl(fd, F_GETFL)) == -1) if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
fatal("fcntl failed"); fatal("fcntl failed");
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed"); fatal("fcntl failed");
imsg_init(&cctx->ibuf, fd); cctx->srv_in = buffer_create(BUFSIZ);
cctx->srv_out = buffer_create(BUFSIZ);
if (cmdflags & CMD_SENDENVIRON)
client_send_environ(cctx);
if (isatty(STDIN_FILENO)) { if (isatty(STDIN_FILENO)) {
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)"); fatal("ioctl(TIOCGWINSZ)");
data.version = PROTOCOL_VERSION;
data.flags = flags; data.flags = flags;
data.sx = ws.ws_col; data.sx = ws.ws_col;
data.sy = ws.ws_row; data.sy = ws.ws_row;
*data.tty = '\0';
if (getcwd(data.cwd, sizeof data.cwd) == NULL) if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0'; *data.cwd = '\0';
*data.term = '\0';
if ((term = getenv("TERM")) != NULL) {
if (strlcpy(data.term,
term, sizeof data.term) >= sizeof data.term)
*data.term = '\0';
}
*data.tty = '\0';
if ((name = ttyname(STDIN_FILENO)) == NULL) if ((name = ttyname(STDIN_FILENO)) == NULL)
fatal("ttyname failed"); fatal("ttyname failed");
if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty) if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty)
fatalx("ttyname failed"); fatalx("ttyname failed");
fd2 = dup(STDIN_FILENO); b = buffer_create(BUFSIZ);
imsg_compose(&cctx->ibuf, MSG_IDENTIFY, cmd_send_string(b, getenv("TERM"));
PROTOCOL_VERSION, -1, fd2, &data, sizeof data); client_write_server2(cctx, MSG_IDENTIFY,
&data, sizeof data, BUFFER_OUT(b), BUFFER_USED(b));
buffer_destroy(b);
} }
return (0); return (0);
@@ -139,41 +125,23 @@ not_found:
return (1); return (1);
} }
void
client_send_environ(struct client_ctx *cctx)
{
char **var;
struct msg_environ_data data;
for (var = environ; *var != NULL; var++) {
if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
continue;
client_write_server(cctx, MSG_ENVIRON, &data, sizeof data);
}
}
int int
client_main(struct client_ctx *cctx) client_main(struct client_ctx *cctx)
{ {
struct pollfd pfd; struct pollfd pfd;
int n, nfds; char *error;
int xtimeout; /* Yay for ncurses namespace! */
siginit(); siginit();
logfile("client"); logfile("client");
#ifndef NO_SETPROCTITLE
setproctitle("client");
#endif
/* error = NULL;
* imsg_read in the first client poll loop (before the terminal has xtimeout = INFTIM;
* been initialiased) may have read messages into the buffer after the while (!sigterm) {
* MSG_READY switched to here. Process anything outstanding now so poll
* doesn't hang waiting for messages that have already arrived.
*/
if (client_msg_dispatch(cctx) != 0)
goto out;
for (;;) {
if (sigterm)
client_write_server(cctx, MSG_EXITING, NULL, 0);
if (sigchld) { if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG); waitpid(WAIT_ANY, NULL, WNOHANG);
sigchld = 0; sigchld = 0;
@@ -182,41 +150,36 @@ client_main(struct client_ctx *cctx)
client_handle_winch(cctx); client_handle_winch(cctx);
if (sigcont) { if (sigcont) {
siginit(); siginit();
client_write_server(cctx, MSG_WAKEUP, NULL, 0); client_write_server(cctx, MSG_WAKEUP, NULL, 0);
sigcont = 0; sigcont = 0;
} }
pfd.fd = cctx->ibuf.fd; switch (client_msg_dispatch(cctx, &error)) {
case -1:
goto out;
case 0:
/* May be more in buffer, don't let poll block. */
xtimeout = 0;
break;
default:
/* Out of data, poll may block. */
xtimeout = INFTIM;
break;
}
pfd.fd = cctx->srv_fd;
pfd.events = POLLIN; pfd.events = POLLIN;
if (cctx->ibuf.w.queued > 0) if (BUFFER_USED(cctx->srv_out) > 0)
pfd.events |= POLLOUT; pfd.events |= POLLOUT;
if ((nfds = poll(&pfd, 1, INFTIM)) == -1) { if (poll(&pfd, 1, xtimeout) == -1) {
if (errno == EAGAIN || errno == EINTR) if (errno == EAGAIN || errno == EINTR)
continue; continue;
fatal("poll failed"); fatal("poll failed");
} }
if (nfds == 0)
continue;
if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL)) if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
fatalx("socket error"); goto server_dead;
if (pfd.revents & POLLIN) {
if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) {
cctx->exittype = CCTX_DIED;
break;
}
if (client_msg_dispatch(cctx) != 0)
break;
}
if (pfd.revents & POLLOUT) {
if (msgbuf_write(&cctx->ibuf.w) < 0) {
cctx->exittype = CCTX_DIED;
break;
}
}
} }
out: out:
@@ -224,27 +187,28 @@ out:
printf("[terminated]\n"); printf("[terminated]\n");
return (1); return (1);
} }
switch (cctx->exittype) {
case CCTX_DIED: if (cctx->flags & CCTX_SHUTDOWN) {
printf("[lost server]\n");
return (0);
case CCTX_SHUTDOWN:
printf("[server exited]\n"); printf("[server exited]\n");
return (0); return (0);
case CCTX_EXIT: }
if (cctx->errstr != NULL) {
printf("[error: %s]\n", cctx->errstr); if (cctx->flags & CCTX_EXIT) {
return (1);
}
printf("[exited]\n"); printf("[exited]\n");
return (0); return (0);
case CCTX_DETACH: }
if (cctx->flags & CCTX_DETACH) {
printf("[detached]\n"); printf("[detached]\n");
return (0); return (0);
default:
printf("[unknown error]\n");
return (1);
} }
printf("[error: %s]\n", error);
return (1);
server_dead:
printf("[lost server]\n");
return (0);
} }
void void
@@ -262,69 +226,3 @@ client_handle_winch(struct client_ctx *cctx)
sigwinch = 0; sigwinch = 0;
} }
int
client_msg_dispatch(struct client_ctx *cctx)
{
struct imsg imsg;
struct msg_print_data printdata;
ssize_t n, datalen;
for (;;) {
if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1)
fatalx("imsg_get failed");
if (n == 0)
return (0);
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
switch (imsg.hdr.type) {
case MSG_DETACH:
if (datalen != 0)
fatalx("bad MSG_DETACH size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_DETACH;
break;
case MSG_ERROR:
if (datalen != sizeof printdata)
fatalx("bad MSG_ERROR size");
memcpy(&printdata, imsg.data, sizeof printdata);
printdata.msg[(sizeof printdata.msg) - 1] = '\0';
/* Error string used after exit message from server. */
cctx->errstr = xstrdup(printdata.msg);
imsg_free(&imsg);
return (-1);
case MSG_EXIT:
if (datalen != 0)
fatalx("bad MSG_EXIT size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_EXIT;
break;
case MSG_EXITED:
if (datalen != 0)
fatalx("bad MSG_EXITED size");
imsg_free(&imsg);
return (-1);
case MSG_SHUTDOWN:
if (datalen != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_SHUTDOWN;
break;
case MSG_SUSPEND:
if (datalen != 0)
fatalx("bad MSG_SUSPEND size");
client_suspend();
break;
default:
fatalx("unexpected message");
}
imsg_free(&imsg);
}
}

18
clock.c
View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.8 2009-08-16 19:16:27 tcunha Exp $ */ /* $Id: cmd-break-pane.c,v 1.1 2009-03-07 09:29:54 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,31 +30,41 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_break_pane_entry = { const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp", "break-pane", "breakp",
CMD_TARGET_PANE_USAGE " [-d]", CMD_PANE_WINDOW_USAGE " [-d]",
0, CMD_CHFLAG('d'), CMD_DFLAG,
cmd_target_init, cmd_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_break_pane_exec, cmd_break_pane_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
int int
cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct session *s; struct session *s;
struct window_pane *wp; struct window_pane *wp;
struct window *w; struct window *w;
char *cause; char *cause;
int base_idx;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
return (-1); return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (window_count_panes(wl->window) == 1) { if (window_count_panes(wl->window) == 1) {
ctx->error(ctx, "can't break with only one pane"); ctx->error(ctx, "can't break pane: %d", data->pane);
return (-1); return (-1);
} }
@@ -64,19 +74,18 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl->window->active == NULL) if (wl->window->active == NULL)
wl->window->active = TAILQ_NEXT(wp, entry); wl->window->active = TAILQ_NEXT(wp, entry);
} }
layout_close_pane(wp); window_fit_panes(wl->window);
w = wp->window = window_create1(s->sx, s->sy); w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp; w->active = wp;
window_fit_panes(w);
w->name = default_window_name(w); w->name = default_window_name(w);
layout_init(w);
base_idx = options_get_number(&s->options, "base-index"); wl = session_attach(s, w, -1, &cause); /* can't fail */
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
if (!(data->chflags & CMD_CHFLAG('d'))) if (!(data->flags & CMD_DFLAG))
session_select(s, wl->idx); session_select(s, wl->idx);
server_redraw_session(s); server_redraw_session(s);
return (0); return (0);

View File

@@ -1,152 +0,0 @@
/* $Id: cmd-choose-client.c,v 1.3 2009-09-07 23:59:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <ctype.h>
#include "tmux.h"
/*
* Enter choice mode to choose a client.
*/
int cmd_choose_client_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_client_callback(void *, int);
void cmd_choose_client_free(void *);
const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_choose_client_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_choose_client_data {
struct client *client;
char *template;
};
int
cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_choose_client_data *cdata;
struct winlink *wl;
struct client *c;
u_int i, idx, cur;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0);
cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c == ctx->curclient)
cur = idx;
idx++;
window_choose_add(wl->window->active, i,
"%s: %s [%ux%u %s]%s", c->tty.path,
c->session->name, c->tty.sx, c->tty.sy,
c->tty.termname, c->tty.flags & TTY_UTF8 ? " (utf8)" : "");
}
cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL)
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("detach-client -t '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
cur, cmd_choose_client_callback, cmd_choose_client_free, cdata);
return (0);
}
void
cmd_choose_client_callback(void *data, int idx)
{
struct cmd_choose_client_data *cdata = data;
struct client *c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause;
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
if ((u_int) idx > ARRAY_LENGTH(&clients) - 1)
return;
c = ARRAY_ITEM(&clients, idx);
if (c == NULL || c->session == NULL)
return;
template = cmd_template_replace(cdata->template, c->tty.path, 1);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, "%s", cause);
xfree(cause);
}
xfree(template);
return;
}
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_client_free(void *data)
{
struct cmd_choose_client_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-session.c,v 1.13 2009-09-07 23:59:19 tcunha Exp $ */ /* $Id: cmd-choose-session.c,v 1.6 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -29,22 +27,22 @@
int cmd_choose_session_exec(struct cmd *, struct cmd_ctx *); int cmd_choose_session_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_session_callback(void *, int); void cmd_choose_session_callback(void *, int);
void cmd_choose_session_free(void *);
const struct cmd_entry cmd_choose_session_entry = { const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL, "choose-session", NULL,
CMD_TARGET_WINDOW_USAGE " [template]", CMD_TARGET_WINDOW_USAGE,
CMD_ARG01, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_choose_session_exec, cmd_choose_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
struct cmd_choose_session_data { struct cmd_choose_session_data {
struct client *client; u_int client;
char *template;
}; };
int int
@@ -63,7 +61,7 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0); return (0);
@@ -83,15 +81,10 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL) cdata->client = server_client_index(ctx->curclient);
cdata->template = xstrdup(data->arg);
else
cdata->template = xstrdup("switch-client -t '%%'");
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active, window_choose_ready(
cur, cmd_choose_session_callback, cmd_choose_session_free, cdata); wl->window->active, cur, cmd_choose_session_callback, cdata);
return (0); return (0);
} }
@@ -100,53 +93,15 @@ void
cmd_choose_session_callback(void *data, int idx) cmd_choose_session_callback(void *data, int idx)
{ {
struct cmd_choose_session_data *cdata = data; struct cmd_choose_session_data *cdata = data;
struct session *s; struct client *c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *template, *cause;
if (idx == -1) if (idx != -1 && cdata->client <= ARRAY_LENGTH(&clients) - 1) {
return; c = ARRAY_ITEM(&clients, cdata->client);
if (cdata->client->flags & CLIENT_DEAD) if (c != NULL && (u_int) idx <= ARRAY_LENGTH(&sessions) - 1) {
return; c->session = ARRAY_ITEM(&sessions, idx);
recalculate_sizes();
if ((u_int) idx > ARRAY_LENGTH(&sessions) - 1) server_redraw_client(c);
return;
s = ARRAY_ITEM(&sessions, idx);
if (s == NULL)
return;
template = cmd_template_replace(cdata->template, s->name, 1);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(cdata->client, "%s", cause);
xfree(cause);
} }
xfree(template);
return;
} }
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_session_free(void *data)
{
struct cmd_choose_session_data *cdata = data;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata); xfree(cdata);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-window.c,v 1.17 2009-09-07 23:59:19 tcunha Exp $ */ /* $Id: cmd-choose-window.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,8 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -29,23 +27,22 @@
int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *); int cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_choose_window_callback(void *, int); void cmd_choose_window_callback(void *, int);
void cmd_choose_window_free(void *);
const struct cmd_entry cmd_choose_window_entry = { const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL, "choose-window", NULL,
CMD_TARGET_WINDOW_USAGE " [template]", CMD_TARGET_WINDOW_USAGE,
CMD_ARG01, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_choose_window_exec, cmd_choose_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
struct cmd_choose_window_data { struct cmd_choose_window_data {
struct client *client; u_int session;
struct session *session;
char *template;
}; };
int int
@@ -57,8 +54,6 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl, *wm; struct winlink *wl, *wm;
struct window *w; struct window *w;
u_int idx, cur; u_int idx, cur;
char flag, *title;
const char *left, *right;
if (ctx->curclient == NULL) { if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively"); ctx->error(ctx, "must be run interactively");
@@ -68,7 +63,7 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (0); return (0);
@@ -80,44 +75,17 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx; cur = idx;
idx++; idx++;
flag = ' ';
if (session_alert_has(s, wm, WINDOW_ACTIVITY))
flag = '#';
else if (session_alert_has(s, wm, WINDOW_BELL))
flag = '!';
else if (session_alert_has(s, wm, WINDOW_CONTENT))
flag = '+';
else if (wm == s->curw)
flag = '*';
else if (wm == SLIST_FIRST(&s->lastw))
flag = '-';
title = w->active->screen->title;
if (wm == wl)
title = w->active->base.title;
left = " \"";
right = "\"";
if (*title == '\0')
left = right = "";
window_choose_add(wl->window->active, window_choose_add(wl->window->active,
wm->idx, "%3d: %s%c [%ux%u] (%u panes)%s%s%s", wm->idx, "%3d: %s [%ux%u] (%u panes)", wm->idx, w->name,
wm->idx, w->name, flag, w->sx, w->sy, window_count_panes(w), w->sx, w->sy, window_count_panes(w));
left, title, right);
} }
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);
if (data->arg != NULL) if (session_index(s, &cdata->session) != 0)
cdata->template = xstrdup(data->arg); fatalx("session not found");
else
cdata->template = xstrdup("select-window -t '%%'");
cdata->session = s;
cdata->session->references++;
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active, window_choose_ready(
cur, cmd_choose_window_callback, cmd_choose_window_free, cdata); wl->window->active, cur, cmd_choose_window_callback, cdata);
return (0); return (0);
} }
@@ -126,54 +94,13 @@ void
cmd_choose_window_callback(void *data, int idx) cmd_choose_window_callback(void *data, int idx)
{ {
struct cmd_choose_window_data *cdata = data; struct cmd_choose_window_data *cdata = data;
struct cmd_list *cmdlist; struct session *s;
struct cmd_ctx ctx;
char *target, *template, *cause;
if (idx == -1) if (idx != -1 && cdata->session <= ARRAY_LENGTH(&sessions) - 1) {
return; s = ARRAY_ITEM(&sessions, cdata->session);
if (cdata->client->flags & CLIENT_DEAD) if (s != NULL && session_select(s, idx) == 0)
return; server_redraw_session(s);
if (cdata->session->flags & SESSION_DEAD) recalculate_sizes();
return;
if (cdata->client->session != cdata->session)
return;
xasprintf(&target, "%s:%d", cdata->session->name, idx);
template = cmd_template_replace(cdata->template, target, 1);
xfree(target);
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(cdata->client, "%s", cause);
xfree(cause);
}
xfree(template);
return;
} }
xfree(template);
ctx.msgdata = NULL;
ctx.curclient = cdata->client;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
}
void
cmd_choose_window_free(void *data)
{
struct cmd_choose_window_data *cdata = data;
cdata->session->references--;
cdata->client->references--;
xfree(cdata->template);
xfree(cdata); xfree(cdata);
} }

View File

@@ -1,55 +0,0 @@
/* $Id: cmd-clear-history.c,v 1.7 2009-07-30 21:04:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
/*
* Clear pane history.
*/
int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
CMD_TARGET_PANE_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_clear_history_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct window_pane *wp;
struct grid *gd;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy);
gd->hsize = 0;
return (0);
}

View File

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

View File

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

View File

@@ -1,147 +0,0 @@
/* $Id: cmd-confirm-before.c,v 1.11 2009-08-24 16:24:18 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <ctype.h>
#include <string.h>
#include "tmux.h"
/*
* Asks for confirmation before executing a command.
*/
int cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *);
void cmd_confirm_before_init(struct cmd *, int);
int cmd_confirm_before_callback(void *, const char *);
void cmd_confirm_before_free(void *);
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
CMD_TARGET_CLIENT_USAGE " command",
CMD_ARG1, 0,
cmd_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_confirm_before_data {
struct client *c;
char *cmd;
};
void
cmd_confirm_before_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case '&':
data->arg = xstrdup("kill-window");
break;
case 'x':
data->arg = xstrdup("kill-pane");
break;
}
}
int
cmd_confirm_before_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_confirm_before_data *cdata;
struct client *c;
char *buf, *cmd, *ptr;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
ptr = xstrdup(data->arg);
if ((cmd = strtok(ptr, " \t")) == NULL)
cmd = ptr;
xasprintf(&buf, "Confirm '%s'? (y/n) ", cmd);
xfree(ptr);
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg);
cdata->c = c;
status_prompt_set(cdata->c, buf,
cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
PROMPT_SINGLE);
xfree(buf);
return (1);
}
int
cmd_confirm_before_callback(void *data, const char *s)
{
struct cmd_confirm_before_data *cdata = data;
struct client *c = cdata->c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *cause;
if (s == NULL || *s == '\0')
return (0);
if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
return (0);
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, "%s", cause);
xfree(cause);
}
return (0);
}
ctx.msgdata = NULL;
ctx.curclient = c;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
return (0);
}
void
cmd_confirm_before_free(void *data)
{
struct cmd_confirm_before_data *cdata = data;
if (cdata->cmd != NULL)
xfree(cdata->cmd);
xfree(cdata);
}

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-copy-mode.c,v 1.16 2009-02-25 21:56:46 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,11 +28,13 @@ int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = { const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL, "copy-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE, CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('u'), CMD_UFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_copy_mode_exec, cmd_copy_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
NULL NULL
}; };
@@ -41,14 +43,14 @@ int
cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct window_pane *wp; struct winlink *wl;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
window_pane_set_mode(wp, &window_copy_mode); window_pane_set_mode(wl->window->active, &window_copy_mode);
if (wp->mode == &window_copy_mode && data->chflags & CMD_CHFLAG('u')) if (data->flags & CMD_UFLAG)
window_copy_pageup(wp); window_copy_pageup(wl->window->active);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-delete-buffer.c,v 1.7 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-delete-buffer.c,v 1.4 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_delete_buffer_entry = { const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb", "delete-buffer", "deleteb",
CMD_BUFFER_SESSION_USAGE, CMD_BUFFER_SESSION_USAGE,
0, 0, 0,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_delete_buffer_exec, cmd_delete_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -54,6 +56,6 @@ cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "no buffer %d", data->buffer); ctx->error(ctx, "no buffer %d", data->buffer);
return (-1); return (-1);
} }
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-detach-client.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-detach-client.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_detach_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_detach_client_entry = { const struct cmd_entry cmd_detach_client_entry = {
"detach-client", "detach", "detach-client", "detach",
CMD_TARGET_CLIENT_USAGE, CMD_TARGET_CLIENT_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_detach_client_exec, cmd_detach_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-has-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-has-session.c,v 1.12 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_has_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_has_session_entry = { const struct cmd_entry cmd_has_session_entry = {
"has-session", "has", "has-session", "has",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_has_session_exec, cmd_has_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,151 +0,0 @@
/* $Id: cmd-if-shell.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Executes a tmux command if a shell command returns true.
*/
int cmd_if_shell_parse(struct cmd *, int, char **, char **);
int cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_if_shell_free(struct cmd *);
void cmd_if_shell_init(struct cmd *, int);
size_t cmd_if_shell_print(struct cmd *, char *, size_t);
struct cmd_if_shell_data {
char *cmd;
char *sh_cmd;
};
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"shell-command command",
0, 0,
cmd_if_shell_init,
cmd_if_shell_parse,
cmd_if_shell_exec,
cmd_if_shell_free,
cmd_if_shell_print
};
void
cmd_if_shell_init(struct cmd *self, unused int arg)
{
struct cmd_if_shell_data *data;
self->data = data = xmalloc(sizeof *data);
data->cmd = NULL;
data->sh_cmd = NULL;
}
int
cmd_if_shell_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_if_shell_data *data;
int opt;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "")) != -1) {
switch (opt) {
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 2)
goto usage;
data->sh_cmd = xstrdup(argv[0]);
data->cmd = xstrdup(argv[1]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_if_shell_data *data = self->data;
struct cmd_list *cmdlist;
char *cause;
int ret;
if ((ret = system(data->sh_cmd)) < 0) {
ctx->error(ctx, "system error: %s", strerror(errno));
return (-1);
} else if (ret != 0)
return (0);
if (cmd_string_parse(data->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
ctx->error(ctx, "%s", cause);
xfree(cause);
}
return (-1);
}
if (cmd_list_exec(cmdlist, ctx) < 0) {
cmd_list_free(cmdlist);
return (-1);
}
cmd_list_free(cmdlist);
return (0);
}
void
cmd_if_shell_free(struct cmd *self)
{
struct cmd_if_shell_data *data = self->data;
if (data->cmd != NULL)
xfree(data->cmd);
if (data->sh_cmd != NULL)
xfree(data->sh_cmd);
xfree(data);
}
size_t
cmd_if_shell_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_if_shell_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->sh_cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->sh_cmd);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */ /* $Id: cmd-kill-pane.c,v 1.6 2009-04-01 21:10:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,33 +30,43 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = { const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp", "kill-pane", "killp",
CMD_TARGET_PANE_USAGE, CMD_PANE_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_kill_pane_exec, cmd_kill_pane_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
int int
cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (window_count_panes(wl->window) == 1) {
ctx->error(ctx, "can't kill pane: %d", data->pane);
return (-1); return (-1);
if (window_count_panes(wl->window) == 1) {
/* Only one pane, kill the window. */
server_kill_window(wl->window);
return (0);
} }
layout_close_pane(wp);
window_remove_pane(wl->window, wp); window_remove_pane(wl->window, wp);
server_redraw_window(wl->window); server_redraw_window(wl->window);
layout_refresh(wl->window, 0);
return (0); return (0);
} }

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-kill-session.c,v 1.12 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_kill_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_session_entry = { const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL, "kill-session", NULL,
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_kill_session_exec, cmd_kill_session_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.19 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-kill-window.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_kill_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_window_entry = { const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw", "kill-window", "killw",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_kill_window_exec, cmd_kill_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -42,11 +44,26 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct session *s;
struct client *c;
u_int i;
int destroyed;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
server_kill_window(wl->window); destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
recalculate_sizes();
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-last-window.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-last-window.c,v 1.16 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_last_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_last_window_entry = { const struct cmd_entry cmd_last_window_entry = {
"last-window", "last", "last-window", "last",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_last_window_exec, cmd_last_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-link-window.c,v 1.32 2009-08-16 19:16:27 tcunha Exp $ */ /* $Id: cmd-link-window.c,v 1.28 2009-01-23 16:59:14 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_link_window_entry = { const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw", "link-window", "linkw",
"[-dk] " CMD_SRCDST_WINDOW_USAGE, "[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'), CMD_DFLAG|CMD_KFLAG,
cmd_srcdst_init, cmd_srcdst_init,
cmd_srcdst_parse, cmd_srcdst_parse,
cmd_link_window_exec, cmd_link_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free, cmd_srcdst_free,
cmd_srcdst_print cmd_srcdst_print
}; };
@@ -50,8 +52,19 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL) if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL)
return (-1); return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
if (arg_parse_window(data->dst, &dst, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->dst);
return (-1); return (-1);
}
if (dst == NULL)
dst = ctx->cursession;
if (dst == NULL)
dst = cmd_current_session(ctx);
if (dst == NULL) {
ctx->error(ctx, "session not found: %s", data->dst);
return (-1);
}
wl_dst = NULL; wl_dst = NULL;
if (idx != -1) if (idx != -1)
@@ -60,7 +73,7 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl_dst->window == wl_src->window) if (wl_dst->window == wl_src->window)
return (0); return (0);
if (data->chflags & CMD_CHFLAG('k')) { if (data->flags & CMD_KFLAG) {
/* /*
* Can't use session_detach as it will destroy session * Can't use session_detach as it will destroy session
* if this makes it empty. * if this makes it empty.
@@ -71,14 +84,12 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Force select/redraw if current. */ /* Force select/redraw if current. */
if (wl_dst == dst->curw) { if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d'); data->flags &= ~CMD_DFLAG;
dst->curw = NULL; dst->curw = NULL;
} }
} }
} }
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause); wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) { if (wl_dst == NULL) {
ctx->error(ctx, "create session failed: %s", cause); ctx->error(ctx, "create session failed: %s", cause);
@@ -86,7 +97,7 @@ cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
} }
if (data->chflags & CMD_CHFLAG('d')) if (data->flags & CMD_DFLAG)
server_status_session(dst); server_status_session(dst);
else { else {
session_select(dst, wl_dst->idx); session_select(dst, wl_dst->idx);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-buffers.c,v 1.12 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-list-buffers.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_buffers_entry = { const struct cmd_entry cmd_list_buffers_entry = {
"list-buffers", "lsb", "list-buffers", "lsb",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_list_buffers_exec, cmd_list_buffers_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,33 +48,44 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s; struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
u_int idx; u_int idx;
char tmp[51 * 4 + 1]; char *tmp;
size_t size, len; size_t size, in, out;
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
if (s->sx > 35) { /* leave three for ... */
size = s->sx - 32;
tmp = xmalloc(size + 1);
} else {
size = 0;
tmp = NULL;
}
idx = 0; idx = 0;
while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) { while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
size = pb->size; if (tmp != NULL) {
in = out = 0;
while (out < size && pb->data[in] != '\0') {
if (pb->data[in] > 31 && pb->data[in] != 127)
tmp[out++] = pb->data[in];
in++;
}
tmp[out] = '\0';
if (out == size) {
tmp[out - 1] = '.';
tmp[out - 2] = '.';
tmp[out - 3] = '.';
}
/* Translate the first 50 characters. */ ctx->print(ctx, "%d: %zu bytes: \"%s\"",
len = size; idx - 1, strlen(pb->data), tmp);
if (len > 50) } else
len = 50; ctx->print(ctx, "%d: %zu bytes", idx, strlen(pb->data));
strvisx(tmp, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL);
/*
* If the first 50 characterswere encoded as a longer string,
* or there is definitely more data, add "...".
*/
if (size > 50 || strlen(tmp) > 50) {
tmp[50 - 3] = '\0';
strlcat(tmp, "...", sizeof tmp);
}
ctx->print(ctx, "%u: %zu bytes: \"%s\"", idx - 1, size, tmp);
} }
if (tmp != NULL)
xfree(tmp);
return (0); return (0);
} }

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-commands.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-list-commands.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_list_commands_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_commands_entry = { const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm", "list-commands", "lscm",
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_list_commands_exec, cmd_list_commands_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-sessions.c,v 1.21 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-list-sessions.c,v 1.19 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,11 +31,13 @@ int cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = { const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", "", "list-sessions", "ls", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_list_sessions_exec, cmd_list_sessions_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.40 2009-08-09 17:28:23 tcunha Exp $ */ /* $Id: cmd-list-windows.c,v 1.33 2009-03-28 20:17:29 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_windows_entry = { const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw", "list-windows", "lsw",
CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_list_windows_exec, cmd_list_windows_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,9 +48,8 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
struct window *w; struct window *w;
struct window_pane *wp; struct window_pane *wp;
struct grid *gd; struct grid *gd;
struct grid_line *gl;
u_int i; u_int i;
unsigned long long size; unsigned long long size;
const char *name; const char *name;
@@ -63,22 +64,21 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
gd = wp->base.grid; gd = wp->base.grid;
size = 0; size = 0;
for (i = 0; i < gd->hsize; i++) { for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i]; size += gd->size[i] * sizeof **gd->data;
size += gl->cellsize * sizeof *gl->celldata; size += gd->usize[i] * sizeof **gd->udata;
size += gl->utf8size * sizeof *gl->utf8data;
} }
size += gd->hsize * sizeof *gd->linedata; size += gd->hsize * (sizeof *gd->data);
size += gd->hsize * (sizeof *gd->size);
name = NULL;
if (wp->fd != -1) if (wp->fd != -1)
name = ttyname(wp->fd); name = ttyname(wp->fd);
if (name == NULL) else
name = "unknown"; name = "unknown";
ctx->print(ctx, ctx->print(ctx,
" %s [%ux%u] [history %u/%u, %llu bytes]", " %s [%ux%u] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, gd->hsize, gd->hlimit, size); name, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
} }
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-list.c,v 1.3 2009-02-16 18:57:16 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,44 +28,29 @@ cmd_list_parse(int argc, char **argv, char **cause)
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd *cmd; struct cmd *cmd;
int i, lastsplit; int i, lastsplit;
size_t arglen, new_argc;
char **new_argv;
cmdlist = xmalloc(sizeof *cmdlist); cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist); TAILQ_INIT(cmdlist);
lastsplit = 0; lastsplit = 0;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
arglen = strlen(argv[i]); if (strcmp(argv[i], "\\;") == 0) {
if (arglen == 0 || argv[i][arglen - 1] != ';') argv[i][0] = ';';
continue; argv[i][1] = '\0';
argv[i][arglen - 1] = '\0'; } else if (strcmp(argv[i], ";") == 0) {
cmd = cmd_parse(i - lastsplit, argv + lastsplit, cause);
if (arglen > 1 && argv[i][arglen - 2] == '\\') { if (cmd == NULL)
argv[i][arglen - 2] = ';'; goto bad;
continue; TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
lastsplit = i + 1;
} }
new_argc = i - lastsplit;
new_argv = argv + lastsplit;
if (arglen != 1)
new_argc++;
cmd = cmd_parse(new_argc, new_argv, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
lastsplit = i + 1;
}
if (lastsplit != argc) {
cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
} }
cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
return (cmdlist); return (cmdlist);
bad: bad:
@@ -86,11 +71,46 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
return (0); return (0);
} }
void
cmd_list_send(struct cmd_list *cmdlist, struct buffer *b)
{
struct cmd *cmd;
u_int n;
n = 0;
TAILQ_FOREACH(cmd, cmdlist, qentry)
n++;
buffer_write(b, &n, sizeof n);
TAILQ_FOREACH(cmd, cmdlist, qentry)
cmd_send(cmd, b);
}
struct cmd_list *
cmd_list_recv(struct buffer *b)
{
struct cmd_list *cmdlist;
struct cmd *cmd;
u_int n;
buffer_read(b, &n, sizeof n);
cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist);
while (n-- > 0) {
cmd = cmd_recv(b);
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
}
return (cmdlist);
}
void void
cmd_list_free(struct cmd_list *cmdlist) cmd_list_free(struct cmd_list *cmdlist)
{ {
struct cmd *cmd; struct cmd *cmd;
while (!TAILQ_EMPTY(cmdlist)) { while (!TAILQ_EMPTY(cmdlist)) {
cmd = TAILQ_FIRST(cmdlist); cmd = TAILQ_FIRST(cmdlist);
TAILQ_REMOVE(cmdlist, cmd, qentry); TAILQ_REMOVE(cmdlist, cmd, qentry);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-load-buffer.c,v 1.2 2009-01-27 23:26:15 nicm Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -35,10 +35,12 @@ int cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_load_buffer_entry = { const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb", "load-buffer", "loadb",
CMD_BUFFER_SESSION_USAGE " path", CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, 0, CMD_ARG1,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_load_buffer_exec, cmd_load_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -48,20 +50,20 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_buffer_data *data = self->data; struct cmd_buffer_data *data = self->data;
struct session *s; struct session *s;
struct stat sb; struct stat statbuf;
FILE *f; FILE *f;
u_char *buf; char *buf;
u_int limit; u_int limit;
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
if (stat(data->arg, &sb) < 0) { if (stat(data->arg, &statbuf) < 0) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1); return (-1);
} }
if ((f = fopen(data->arg, "rb")) == NULL) { if ((f = fopen(data->arg, "r")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1); return (-1);
} }
@@ -70,27 +72,27 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
* We don't want to die due to memory exhaustion, hence xmalloc can't * We don't want to die due to memory exhaustion, hence xmalloc can't
* be used here. * be used here.
*/ */
if ((buf = malloc(sb.st_size + 1)) == NULL) { if ((buf = malloc(statbuf.st_size + 1)) == NULL) {
ctx->error(ctx, "malloc error: %s", strerror(errno)); ctx->error(ctx, "malloc error: %s", strerror(errno));
fclose(f);
return (-1); return (-1);
} }
if (fread(buf, 1, sb.st_size, f) != (size_t) sb.st_size) { if (fread(buf, 1, statbuf.st_size, f) != (size_t) statbuf.st_size) {
ctx->error(ctx, "%s: fread error", data->arg); ctx->error(ctx, "%s: fread error", data->arg);
xfree(buf); xfree(buf);
fclose(f); fclose(f);
return (-1); return (-1);
} }
buf[statbuf.st_size] = '\0';
fclose(f); fclose(f);
limit = options_get_number(&s->options, "buffer-limit"); limit = options_get_number(&s->options, "buffer-limit");
if (data->buffer == -1) { if (data->buffer == -1) {
paste_add(&s->buffers, buf, sb.st_size, limit); paste_add(&s->buffers, buf, limit);
return (0); return (0);
} }
if (paste_replace(&s->buffers, data->buffer, buf, sb.st_size) != 0) { if (paste_replace(&s->buffers, data->buffer, buf) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer); ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf); xfree(buf);
return (-1); return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-server.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-lock-server.c,v 1.2 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,15 +30,19 @@
int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *); int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
int cmd_lock_server_callback(void *, const char *);
const struct cmd_entry cmd_lock_server_entry = { const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock", "lock-server", "lock",
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_lock_server_exec, cmd_lock_server_exec,
NULL, NULL,
NULL, NULL,
NULL,
NULL,
}; };
int int

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-move-window.c,v 1.9 2009-08-16 19:16:27 tcunha Exp $ */ /* $Id: cmd-move-window.c,v 1.5 2009-01-23 16:59:14 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_move_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_move_window_entry = { const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew", "move-window", "movew",
"[-dk] " CMD_SRCDST_WINDOW_USAGE, "[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'), CMD_DFLAG|CMD_KFLAG,
cmd_srcdst_init, cmd_srcdst_init,
cmd_srcdst_parse, cmd_srcdst_parse,
cmd_move_window_exec, cmd_move_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free, cmd_srcdst_free,
cmd_srcdst_print cmd_srcdst_print
}; };
@@ -52,8 +54,19 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL) if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
return (-1); return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
if (arg_parse_window(data->dst, &dst, &idx) != 0) {
ctx->error(ctx, "bad window: %s", data->dst);
return (-1); return (-1);
}
if (dst == NULL)
dst = ctx->cursession;
if (dst == NULL)
dst = cmd_current_session(ctx);
if (dst == NULL) {
ctx->error(ctx, "session not found: %s", data->dst);
return (-1);
}
wl_dst = NULL; wl_dst = NULL;
if (idx != -1) if (idx != -1)
@@ -62,7 +75,7 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl_dst->window == wl_src->window) if (wl_dst->window == wl_src->window)
return (0); return (0);
if (data->chflags & CMD_CHFLAG('k')) { if (data->flags & CMD_KFLAG) {
/* /*
* Can't use session_detach as it will destroy session * Can't use session_detach as it will destroy session
* if this makes it empty. * if this makes it empty.
@@ -73,14 +86,12 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
/* Force select/redraw if current. */ /* Force select/redraw if current. */
if (wl_dst == dst->curw) { if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d'); data->flags &= ~CMD_DFLAG;
dst->curw = NULL; dst->curw = NULL;
} }
} }
} }
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause); wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) { if (wl_dst == NULL) {
ctx->error(ctx, "attach window failed: %s", cause); ctx->error(ctx, "attach window failed: %s", cause);
@@ -100,7 +111,7 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_client(c); server_redraw_client(c);
} }
if (data->chflags & CMD_CHFLAG('d')) if (data->flags & CMD_DFLAG)
server_status_session(dst); server_status_session(dst);
else { else {
session_select(dst, wl_dst->idx); session_select(dst, wl_dst->idx);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.66 2009-09-16 12:36:27 nicm Exp $ */ /* $Id: cmd-new-session.c,v 1.40 2009-04-01 18:21:24 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,10 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
/* /*
@@ -30,6 +26,8 @@
int cmd_new_session_parse(struct cmd *, int, char **, char **); int cmd_new_session_parse(struct cmd *, int, char **, char **);
int cmd_new_session_exec(struct cmd *, struct cmd_ctx *); int cmd_new_session_exec(struct cmd *, struct cmd_ctx *);
void cmd_new_session_send(struct cmd *, struct buffer *);
void cmd_new_session_recv(struct cmd *, struct buffer *);
void cmd_new_session_free(struct cmd *); void cmd_new_session_free(struct cmd *);
void cmd_new_session_init(struct cmd *, int); void cmd_new_session_init(struct cmd *, int);
size_t cmd_new_session_print(struct cmd *, char *, size_t); size_t cmd_new_session_print(struct cmd *, char *, size_t);
@@ -44,10 +42,12 @@ struct cmd_new_session_data {
const struct cmd_entry cmd_new_session_entry = { const struct cmd_entry cmd_new_session_entry = {
"new-session", "new", "new-session", "new",
"[-d] [-n window-name] [-s session-name] [command]", "[-d] [-n window-name] [-s session-name] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, 0, CMD_STARTSERVER|CMD_CANTNEST,
cmd_new_session_init, cmd_new_session_init,
cmd_new_session_parse, cmd_new_session_parse,
cmd_new_session_exec, cmd_new_session_exec,
cmd_new_session_send,
cmd_new_session_recv,
cmd_new_session_free, cmd_new_session_free,
cmd_new_session_print cmd_new_session_print
}; };
@@ -111,149 +111,106 @@ int
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_new_session_data *data = self->data; struct cmd_new_session_data *data = self->data;
struct client *c = ctx->cmdclient;
struct session *s; struct session *s;
struct window *w; char *cmd, *cwd, *cause;
struct environ env;
struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
int detached, idx;
u_int sx, sy; u_int sx, sy;
if (ctx->curclient != NULL)
return (0);
if (!data->flag_detached) {
if (c == NULL) {
ctx->error(ctx, "no client to attach to");
return (-1);
}
if (!(c->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
}
if (data->newname != NULL && session_find(data->newname) != NULL) { if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname); ctx->error(ctx, "duplicate session: %s", data->newname);
return (-1); return (-1);
} }
/* cmd = data->cmd;
* There are three cases: if (cmd == NULL)
* cmd = options_get_string(&global_options, "default-command");
* 1. If cmdclient is non-NULL, new-session has been called from the if (c == NULL || c->cwd == NULL)
* command-line - cmdclient is to become a new attached, interactive cwd = options_get_string(&global_options, "default-path");
* client. Unless -d is given, the terminal must be opened and then else
* the client sent MSG_READY. cwd = c->cwd;
*
* 2. If cmdclient is NULL, new-session has been called from an
* existing client (such as a key binding).
*
* 3. Both are NULL, the command was in the configuration file. Treat
* this as if -d was given even if it was not.
*
* In all cases, a new additional session needs to be created and
* (unless -d) set as the current session for the client.
*/
/* Set -d if no client. */ sx = 80;
detached = data->flag_detached; sy = 25;
if (ctx->cmdclient == NULL && ctx->curclient == NULL) if (!data->flag_detached) {
detached = 1; sx = c->tty.sx;
sy = c->tty.sy;
/*
* Save the termios settings, part of which is used for new windows in
* this session.
*
* This is read again with tcgetattr() rather than using tty.tio as if
* detached, tty_open won't be called. Because of this, it must be done
* before opening the terminal as that calls tcsetattr() to prepare for
* tmux taking over.
*/
if (ctx->cmdclient != NULL && ctx->cmdclient->tty.fd != -1) {
if (tcgetattr(ctx->cmdclient->tty.fd, &tio) != 0)
fatal("tcgetattr failed");
tiop = &tio;
} else
tiop = NULL;
/* Open the terminal if necessary. */
if (!detached && ctx->cmdclient != NULL) {
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return (-1);
}
overrides =
options_get_string(&global_s_options, "terminal-overrides");
if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause);
xfree(cause);
return (-1);
}
} }
/* Get the new session working directory. */ if (options_get_number(&global_options, "status")) {
if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) if (sy == 0)
cwd = ctx->cmdclient->cwd; sy = 1;
else else
cwd = options_get_string(&global_s_options, "default-path"); sy--;
/* Find new session size. */
if (detached) {
sx = 80;
sy = 24;
} else if (ctx->cmdclient != NULL) {
sx = ctx->cmdclient->tty.sx;
sy = ctx->cmdclient->tty.sy;
} else {
sx = ctx->curclient->tty.sx;
sy = ctx->curclient->tty.sy;
} }
if (sy > 0 && options_get_number(&global_s_options, "status"))
sy--;
if (sx == 0)
sx = 1;
if (sy == 0)
sy = 1;
/* Figure out the command for the new window. */ if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
if (data->cmd != NULL) ctx->error(ctx, "open terminal failed: %s", cause);
cmd = data->cmd; xfree(cause);
else return (-1);
cmd = options_get_string(&global_s_options, "default-command"); }
/* Construct the environment. */
environ_init(&env);
update = options_get_string(&global_s_options, "update-environment");
if (ctx->cmdclient != NULL)
environ_update(update, &ctx->cmdclient->environ, &env);
/* Create the new session. */ s = session_create(data->newname, cmd, cwd, sx, sy, &cause);
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(
data->newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
if (s == NULL) { if (s == NULL) {
ctx->error(ctx, "create session failed: %s", cause); ctx->error(ctx, "create session failed: %s", cause);
xfree(cause); xfree(cause);
return (-1); return (-1);
} }
environ_free(&env);
/* Set the initial window name if one given. */
if (data->winname != NULL) { if (data->winname != NULL) {
w = s->curw->window; xfree(s->curw->window->name);
s->curw->window->name = xstrdup(data->winname);
xfree(w->name); options_set_number(
w->name = xstrdup(data->winname); &s->curw->window->options, "automatic-rename", 0);
options_set_number(&w->options, "automatic-rename", 0);
} }
/* if (data->flag_detached) {
* Set the client to the new session. If a command client exists, it is if (c != NULL)
* taking this session and needs to get MSG_READY and stay around. server_write_client(c, MSG_EXIT, NULL, 0);
*/ } else {
if (!detached) { c->session = s;
if (ctx->cmdclient != NULL) { server_write_client(c, MSG_READY, NULL, 0);
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0); server_redraw_client(c);
ctx->cmdclient->session = s;
server_redraw_client(ctx->cmdclient);
} else {
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
}
} }
recalculate_sizes(); recalculate_sizes();
return (!detached); /* 1 means don't tell command client to exit */ return (1);
}
void
cmd_new_session_send(struct cmd *self, struct buffer *b)
{
struct cmd_new_session_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->newname);
cmd_send_string(b, data->winname);
cmd_send_string(b, data->cmd);
}
void
cmd_new_session_recv(struct cmd *self, struct buffer *b)
{
struct cmd_new_session_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->newname = cmd_recv_string(b);
data->winname = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
} }
void void

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-layout.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-next-layout.c,v 1.1 2009-04-01 18:21:26 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_next_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_layout_entry = { const struct cmd_entry cmd_next_layout_entry = {
"next-layout", "nextl", "next-layout", "nextl",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_next_layout_exec, cmd_next_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -42,13 +44,11 @@ cmd_next_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
u_int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
layout = layout_set_next(wl->window); layout_next(wl->window);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-next-window.c,v 1.16 2009-03-28 14:08:09 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_next_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_window_entry = { const struct cmd_entry cmd_next_window_entry = {
"next-window", "next", "next-window", "next",
"[-a] " CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('a'), CMD_AFLAG,
cmd_next_window_init, cmd_next_window_init,
cmd_target_parse, cmd_target_parse,
cmd_next_window_exec, cmd_next_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,8 +48,8 @@ cmd_next_window_init(struct cmd *self, int key)
cmd_target_init(self, key); cmd_target_init(self, key);
data = self->data; data = self->data;
if (key == ('n' | KEYC_ESCAPE)) if (key == KEYC_ADDESC('n'))
data->chflags |= CMD_CHFLAG('a'); data->flags |= CMD_AFLAG;
} }
int int
@@ -61,7 +63,7 @@ cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
activity = 0; activity = 0;
if (data->chflags & CMD_CHFLAG('a')) if (data->flags & CMD_AFLAG)
activity = 1; activity = 1;
if (session_next(s, activity) == 0) if (session_next(s, activity) == 0)

View File

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

View File

@@ -1,54 +0,0 @@
/* $Id: cmd-previous-layout.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* 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, 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);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-previous-window.c,v 1.16 2009-03-28 14:08:09 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_previous_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_window_entry = { const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev", "previous-window", "prev",
"[-a] " CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('a'), CMD_AFLAG,
cmd_previous_window_init, cmd_previous_window_init,
cmd_target_parse, cmd_target_parse,
cmd_previous_window_exec, cmd_previous_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,8 +48,8 @@ cmd_previous_window_init(struct cmd *self, int key)
cmd_target_init(self, key); cmd_target_init(self, key);
data = self->data; data = self->data;
if (key == ('p' | KEYC_ESCAPE)) if (key == KEYC_ADDESC('p'))
data->chflags |= CMD_CHFLAG('a'); data->flags |= CMD_AFLAG;
} }
int int
@@ -61,7 +63,7 @@ cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
activity = 0; activity = 0;
if (data->chflags & CMD_CHFLAG('a')) if (data->flags & CMD_AFLAG)
activity = 1; activity = 1;
if (session_previous(s, activity) == 0) if (session_previous(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-refresh-client.c,v 1.10 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-refresh-client.c,v 1.8 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,10 +29,12 @@ int cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_refresh_client_entry = { const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh", "refresh-client", "refresh",
CMD_TARGET_CLIENT_USAGE, CMD_TARGET_CLIENT_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_refresh_client_exec, cmd_refresh_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.29 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-rename-window.c,v 1.26 2009-01-20 19:35:03 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_rename_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_window_entry = { const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew", "rename-window", "renamew",
CMD_TARGET_WINDOW_USAGE " new-name", CMD_TARGET_WINDOW_USAGE " new-name",
CMD_ARG1, 0, CMD_ARG1,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_rename_window_exec, cmd_rename_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -51,7 +53,7 @@ cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx)
xfree(wl->window->name); xfree(wl->window->name);
wl->window->name = xstrdup(data->arg); wl->window->name = xstrdup(data->arg);
options_set_number(&wl->window->options, "automatic-rename", 0); options_set_number(&wl->window->options, "automatic-rename", 0);
server_status_session(s); server_status_session(s);

122
cmd-resize-pane-down.c Normal file
View File

@@ -0,0 +1,122 @@
/* $Id: cmd-resize-pane-down.c,v 1.8 2009-04-02 21:11:52 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Decrease pane size.
*/
void cmd_resize_pane_down_init(struct cmd *, int);
int cmd_resize_pane_down_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_down_entry = {
"resize-pane-down", "resizep-down",
CMD_PANE_WINDOW_USAGE " [adjustment]",
CMD_ARG01,
cmd_resize_pane_down_init,
cmd_pane_parse,
cmd_resize_pane_down_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
};
void
cmd_resize_pane_down_init(struct cmd *self, int key)
{
struct cmd_pane_data *data;
cmd_pane_init(self, key);
data = self->data;
if (key == KEYC_ADDESC(KEYC_DOWN))
data->arg = xstrdup("5");
}
int
cmd_resize_pane_down_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
const char *errstr;
struct window_pane *wp, *wq;
u_int adjust;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (wl->window->layout != 0) {
ctx->error(ctx, "window not in manual layout");
return (-1);
}
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (data->arg == NULL)
adjust = 1;
else {
adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
return (-1);
}
}
/*
* If this is not the last window, keep trying to increase size and
* remove it from the next windows. If it is the last, do so on the
* previous window.
*/
if (TAILQ_NEXT(wp, entry) == NULL) {
if (wp == TAILQ_FIRST(&wl->window->panes)) {
/* Only one pane. */
return (0);
}
wp = TAILQ_PREV(wp, window_panes, entry);
}
while (adjust-- > 0) {
wq = wp;
while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
if (wq->sy > PANE_MINIMUM) {
window_pane_resize(wq, wq->sx, wq->sy - 1);
break;
}
}
if (wq == NULL)
break;
window_pane_resize(wp, wp->sx, wp->sy + 1);
}
window_update_panes(wl->window);
server_redraw_window(wl->window);
return (0);
}

117
cmd-resize-pane-up.c Normal file
View File

@@ -0,0 +1,117 @@
/* $Id: cmd-resize-pane-up.c,v 1.8 2009-04-02 21:11:52 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Increase pane size.
*/
void cmd_resize_pane_up_init(struct cmd *, int);
int cmd_resize_pane_up_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_up_entry = {
"resize-pane-up", "resizep-up",
CMD_PANE_WINDOW_USAGE " [adjustment]",
CMD_ARG01,
cmd_resize_pane_up_init,
cmd_pane_parse,
cmd_resize_pane_up_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
};
void
cmd_resize_pane_up_init(struct cmd *self, int key)
{
struct cmd_pane_data *data;
cmd_pane_init(self, key);
data = self->data;
if (key == KEYC_ADDESC(KEYC_UP))
data->arg = xstrdup("5");
}
int
cmd_resize_pane_up_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
const char *errstr;
struct window_pane *wp, *wq;
u_int adjust;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (wl->window->layout != 0) {
ctx->error(ctx, "window not in manual layout");
return (-1);
}
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (data->arg == NULL)
adjust = 1;
else {
adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
return (-1);
}
}
/*
* If this is not the last window, keep trying to reduce size and add
* to the following window. If it is the last, do so on the previous
* window.
*/
wq = TAILQ_NEXT(wp, entry);
if (wq == NULL) {
if (wp == TAILQ_FIRST(&wl->window->panes)) {
/* Only one pane. */
return (0);
}
wq = wp;
wp = TAILQ_PREV(wq, window_panes, entry);
}
while (adjust-- > 0) {
if (wp->sy <= PANE_MINIMUM)
break;
window_pane_resize(wq, wq->sx, wq->sy + 1);
window_pane_resize(wp, wp->sx, wp->sy - 1);
}
window_update_panes(wl->window);
server_redraw_window(wl->window);
return (0);
}

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rotate-window.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-rotate-window.c,v 1.2 2009-04-21 20:06:46 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,10 +30,12 @@ int cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rotate_window_entry = { const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew", "rotate-window", "rotatew",
"[-DU] " CMD_TARGET_WINDOW_USAGE, "[-DU] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('D')|CMD_CHFLAG('U'), CMD_UPPERUFLAG|CMD_UPPERDFLAG,
cmd_rotate_window_init, cmd_rotate_window_init,
cmd_target_parse, cmd_target_parse,
cmd_rotate_window_exec, cmd_rotate_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -46,8 +48,8 @@ cmd_rotate_window_init(struct cmd *self, int key)
cmd_target_init(self, key); cmd_target_init(self, key);
data = self->data; data = self->data;
if (key == ('o' | KEYC_ESCAPE)) if (key == KEYC_ADDESC('o'))
data->chflags |= CMD_CHFLAG('D'); data->flags |= CMD_UPPERDFLAG;
} }
int int
@@ -57,68 +59,53 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl; struct winlink *wl;
struct window *w; struct window *w;
struct window_pane *wp, *wp2; struct window_pane *wp, *wp2;
struct layout_cell *lc;
u_int sx, sy, xoff, yoff; u_int sx, sy, xoff, yoff;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
w = wl->window; w = wl->window;
if (data->chflags & CMD_CHFLAG('D')) { if (data->flags & CMD_UPPERDFLAG) {
wp = TAILQ_LAST(&w->panes, window_panes); wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
lc = wp->layout_cell;
xoff = wp->xoff; yoff = wp->yoff; xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy; sx = wp->sx; sy = wp->sy;
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL) if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL)
break; break;
wp->layout_cell = wp2->layout_cell;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
window_pane_resize(wp, wp2->sx, wp2->sy); window_pane_resize(wp, wp2->sx, wp2->sy);
} }
wp->layout_cell = lc;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = xoff; wp->yoff = yoff; wp->xoff = xoff; wp->yoff = yoff;
window_pane_resize(wp, sx, sy); window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL) if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
wp = TAILQ_LAST(&w->panes, window_panes); wp = TAILQ_LAST(&w->panes, window_panes);
window_set_active_pane(w, wp); window_set_active_pane(w, wp);
server_redraw_window(w);
} else { } else {
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_TAIL(&w->panes, wp, entry); TAILQ_INSERT_TAIL(&w->panes, wp, entry);
lc = wp->layout_cell;
xoff = wp->xoff; yoff = wp->yoff; xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy; sx = wp->sx; sy = wp->sy;
TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) { TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) {
if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL) if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL)
break; break;
wp->layout_cell = wp2->layout_cell;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
window_pane_resize(wp, wp2->sx, wp2->sy); window_pane_resize(wp, wp2->sx, wp2->sy);
} }
wp->layout_cell = lc;
if (wp->layout_cell != NULL)
wp->layout_cell->wp = wp;
wp->xoff = xoff; wp->yoff = yoff; wp->xoff = xoff; wp->yoff = yoff;
window_pane_resize(wp, sx, sy); window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_NEXT(w->active, entry)) == NULL) if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
window_set_active_pane(w, wp); window_set_active_pane(w, wp);
server_redraw_window(w);
} }
layout_refresh(w, 0);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-save-buffer.c,v 1.8 2009-09-07 23:48:54 tcunha Exp $ */ /* $Id: cmd-save-buffer.c,v 1.4 2009-02-08 13:36:40 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -33,10 +33,12 @@ int cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_save_buffer_entry = { const struct cmd_entry cmd_save_buffer_entry = {
"save-buffer", "saveb", "save-buffer", "saveb",
"[-a] " CMD_BUFFER_SESSION_USAGE " path", "[-a] " CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, CMD_CHFLAG('a'), CMD_AFLAG|CMD_ARG1,
cmd_buffer_init, cmd_buffer_init,
cmd_buffer_parse, cmd_buffer_parse,
cmd_save_buffer_exec, cmd_save_buffer_exec,
cmd_buffer_send,
cmd_buffer_recv,
cmd_buffer_free, cmd_buffer_free,
cmd_buffer_print cmd_buffer_print
}; };
@@ -66,16 +68,16 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
mask = umask(S_IRWXG | S_IRWXO); mask = umask(S_IRWXG | S_IRWXO);
if (data->chflags & CMD_CHFLAG('a')) if (data->flags & CMD_AFLAG)
f = fopen(data->arg, "ab"); f = fopen(data->arg, "a");
else else
f = fopen(data->arg, "wb"); f = fopen(data->arg, "w");
if (f == NULL) { if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1); return (-1);
} }
if (fwrite(pb->data, 1, pb->size, f) != pb->size) { if (fwrite(pb->data, 1, strlen(pb->data), f) != strlen(pb->data)) {
ctx->error(ctx, "%s: fwrite error", data->arg); ctx->error(ctx, "%s: fwrite error", data->arg);
fclose(f); fclose(f);
return (-1); return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-scroll-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-scroll-mode.c,v 1.16 2009-01-27 23:35:44 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,11 +29,13 @@ int cmd_scroll_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_scroll_mode_entry = { const struct cmd_entry cmd_scroll_mode_entry = {
"scroll-mode", NULL, "scroll-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE, CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('u'), CMD_UFLAG,
cmd_scroll_mode_init, cmd_scroll_mode_init,
cmd_target_parse, cmd_target_parse,
cmd_scroll_mode_exec, cmd_scroll_mode_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -48,7 +50,7 @@ cmd_scroll_mode_init(struct cmd *self, int key)
switch (key) { switch (key) {
case KEYC_PPAGE: case KEYC_PPAGE:
data->chflags |= CMD_CHFLAG('u'); data->flags |= CMD_UFLAG;
break; break;
} }
} }
@@ -57,14 +59,14 @@ int
cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct window_pane *wp; struct winlink *wl;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
window_pane_set_mode(wp, &window_scroll_mode); window_pane_set_mode(wl->window->active, &window_scroll_mode);
if (wp->mode == &window_scroll_mode && data->chflags & CMD_CHFLAG('u')) if (data->flags & CMD_UFLAG)
window_scroll_pageup(wp); window_scroll_pageup(wl->window->active);
return (0); return (0);
} }

View File

@@ -1,88 +0,0 @@
/* $Id: cmd-select-layout.c,v 1.8 2009-07-28 23:04:29 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
/*
* Switch window to selected layout.
*/
void cmd_select_layout_init(struct cmd *, int);
int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
CMD_TARGET_WINDOW_USAGE " [layout-name]",
CMD_ARG01, 0,
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
cmd_target_free,
cmd_target_print
};
void
cmd_select_layout_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case ('1' | KEYC_ESCAPE):
data->arg = xstrdup("even-horizontal");
break;
case ('2' | KEYC_ESCAPE):
data->arg = xstrdup("even-vertical");
break;
case ('3' | KEYC_ESCAPE):
data->arg = xstrdup("main-horizontal");
break;
case ('4' | KEYC_ESCAPE):
data->arg = xstrdup("main-vertical");
break;
}
}
int
cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (data->arg == NULL) {
layout = wl->window->lastlayout;
if (layout == -1)
return (0);
} else if ((layout = layout_set_lookup(data->arg)) == -1) {
ctx->error(ctx, "unknown layout or ambiguous: %s", data->arg);
return (-1);
}
layout = layout_set_select(wl->window, layout);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-pane.c,v 1.10 2009-07-30 20:45:20 tcunha Exp $ */ /* $Id: cmd-select-pane.c,v 1.4 2009-04-01 21:10:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,31 +28,42 @@ int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = { const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp", "select-pane", "selectp",
CMD_TARGET_PANE_USAGE, CMD_PANE_WINDOW_USAGE,
0, 0, 0,
cmd_target_init, cmd_pane_init,
cmd_target_parse, cmd_pane_parse,
cmd_select_pane_exec, cmd_select_pane_exec,
cmd_target_free, cmd_pane_send,
cmd_target_print cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
}; };
int int
cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp; struct window_pane *wp;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (!window_pane_visible(wp)) { if (wp->flags & PANE_HIDDEN) {
ctx->error(ctx, "pane not visible: %s", data->target); ctx->error(ctx, "pane %d is hidden", data->pane);
return (-1); return (-1);
} }
window_set_active_pane(wl->window, wp); window_set_active_pane(wl->window, wp);
server_status_window(wl->window); layout_refresh(wl->window, 1);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-prompt.c,v 1.12 2009-08-16 19:29:24 tcunha Exp $ */ /* $Id: cmd-select-prompt.c,v 1.7 2009-02-13 18:57:55 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,10 +33,12 @@ int cmd_select_prompt_callback(void *, const char *);
const struct cmd_entry cmd_select_prompt_entry = { const struct cmd_entry cmd_select_prompt_entry = {
"select-prompt", NULL, "select-prompt", NULL,
CMD_TARGET_CLIENT_USAGE, CMD_TARGET_CLIENT_USAGE,
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_select_prompt_exec, cmd_select_prompt_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -53,7 +55,7 @@ cmd_select_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
if (c->prompt_string != NULL) if (c->prompt_string != NULL)
return (0); return (0);
status_prompt_set(c, "index ", cmd_select_prompt_callback, NULL, c, 0); status_prompt_set(c, "index ", cmd_select_prompt_callback, c, 0);
return (0); return (0);
} }
@@ -66,20 +68,20 @@ cmd_select_prompt_callback(void *data, const char *s)
char msg[128]; char msg[128];
u_int idx; u_int idx;
if (s == NULL || *s == '\0') if (s == NULL)
return (0); return (0);
idx = strtonum(s, 0, UINT_MAX, &errstr); idx = strtonum(s, 0, UINT_MAX, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
xsnprintf(msg, sizeof msg, "Index %s: %s", errstr, s); xsnprintf(msg, sizeof msg, "Index %s: %s", errstr, s);
status_message_set(c, "%s", msg); status_message_set(c, msg);
return (0); return (0);
} }
if (winlink_find_by_index(&c->session->windows, idx) == NULL) { if (winlink_find_by_index(&c->session->windows, idx) == NULL) {
xsnprintf(msg, sizeof msg, xsnprintf(msg, sizeof msg,
"Window not found: %s:%d", c->session->name, idx); "Window not found: %s:%d", c->session->name, idx);
status_message_set(c, "%s", msg); status_message_set(c, msg);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-window.c,v 1.23 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-select-window.c,v 1.21 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_select_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_window_entry = { const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw", "select-window", "selectw",
CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, 0, 0,
cmd_select_window_init, cmd_select_window_init,
cmd_target_parse, cmd_target_parse,
cmd_select_window_exec, cmd_select_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-keys.c,v 1.21 2009-08-20 11:37:46 tcunha Exp $ */ /* $Id: cmd-send-keys.c,v 1.18 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,6 +28,8 @@
int cmd_send_keys_parse(struct cmd *, int, char **, char **); int cmd_send_keys_parse(struct cmd *, int, char **, char **);
int cmd_send_keys_exec(struct cmd *, struct cmd_ctx *); int cmd_send_keys_exec(struct cmd *, struct cmd_ctx *);
void cmd_send_keys_send(struct cmd *, struct buffer *);
void cmd_send_keys_recv(struct cmd *, struct buffer *);
void cmd_send_keys_free(struct cmd *); void cmd_send_keys_free(struct cmd *);
size_t cmd_send_keys_print(struct cmd *, char *, size_t); size_t cmd_send_keys_print(struct cmd *, char *, size_t);
@@ -40,11 +42,13 @@ struct cmd_send_keys_data {
const struct cmd_entry cmd_send_keys_entry = { const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send", "send-keys", "send",
"[-t target-pane] key ...", "[-t target-window] key ...",
0, 0, 0,
NULL, NULL,
cmd_send_keys_parse, cmd_send_keys_parse,
cmd_send_keys_exec, cmd_send_keys_exec,
cmd_send_keys_send,
cmd_send_keys_recv,
cmd_send_keys_free, cmd_send_keys_free,
cmd_send_keys_print cmd_send_keys_print
}; };
@@ -106,21 +110,45 @@ int
cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_send_keys_data *data = self->data; struct cmd_send_keys_data *data = self->data;
struct window_pane *wp; struct winlink *wl;
u_int i; u_int i;
if (data == NULL) if (data == NULL)
return (-1); return (-1);
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
for (i = 0; i < data->nkeys; i++) for (i = 0; i < data->nkeys; i++) {
window_pane_key(wp, ctx->curclient, data->keys[i]); window_pane_key(
wl->window->active, ctx->curclient, data->keys[i]);
}
return (0); return (0);
} }
void
cmd_send_keys_send(struct cmd *self, struct buffer *b)
{
struct cmd_send_keys_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->target);
buffer_write(b, data->keys, data->nkeys * sizeof *data->keys);
}
void
cmd_send_keys_recv(struct cmd *self, struct buffer *b)
{
struct cmd_send_keys_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->target = cmd_recv_string(b);
data->keys = xcalloc(data->nkeys, sizeof *data->keys);
buffer_read(b, data->keys, data->nkeys * sizeof *data->keys);
}
void void
cmd_send_keys_free(struct cmd *self) cmd_send_keys_free(struct cmd *self)
{ {

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.28 2009-09-07 23:59:19 tcunha Exp $ */ /* $Id: cmd-server-info.c,v 1.14 2009-04-02 23:28:16 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <vis.h>
#include "tmux.h" #include "tmux.h"
@@ -35,11 +36,13 @@ int cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = { const struct cmd_entry cmd_server_info_entry = {
"server-info", "info", "server-info", "info",
"", "",
0, 0, 0,
NULL, NULL,
NULL, NULL,
cmd_server_info_exec, cmd_server_info_exec,
NULL, NULL,
NULL,
NULL,
NULL NULL
}; };
@@ -56,9 +59,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct tty_term_code_entry *ent; struct tty_term_code_entry *ent;
struct utsname un; struct utsname un;
struct grid *gd; struct grid *gd;
struct grid_line *gl;
u_int i, j, k; u_int i, j, k;
char out[80]; char out[BUFSIZ];
char *tim; char *tim;
time_t t; time_t t;
u_int lines, ulines; u_int lines, ulines;
@@ -66,11 +68,10 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
tim = ctime(&start_time); tim = ctime(&start_time);
*strchr(tim, '\n') = '\0'; *strchr(tim, '\n') = '\0';
ctx->print(ctx, ctx->print(ctx,
"tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim); "tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(ctx, "socket path %s, debug level %d%s%s", ctx->print(ctx, "socket path %s, debug level %d%s",
socket_path, debug_level, be_quiet ? ", quiet" : "", socket_path, debug_level, be_quiet ? ", quiet" : "");
login_shell ? ", login shell" : "");
if (uname(&un) == 0) { if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s", ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine); un.sysname, un.release, un.version, un.machine);
@@ -82,7 +83,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION); ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION);
ctx->print(ctx, "%u clients, %u sessions", ctx->print(ctx, "%u clients, %u sessions",
ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions)); ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions));
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
ctx->print(ctx, "Clients:"); ctx->print(ctx, "Clients:");
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -90,13 +91,12 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
if (c == NULL || c->session == NULL) if (c == NULL || c->session == NULL)
continue; continue;
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] " ctx->print(ctx, "%2d: %p %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x, references=%u]", i, c->tty.path, "[flags=0x%x/0x%x]", i, c, c->tty.path, c->fd, c->tty.fd,
c->ibuf.fd, c->tty.fd, c->session->name, c->session->name, c->tty.sx, c->tty.sy, c->tty.termname,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags, c->flags, c->tty.flags);
c->tty.flags, c->references);
} }
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
ctx->print(ctx, "Sessions: [%zu/%zu]", ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8)); sizeof (struct grid_cell), sizeof (struct grid_utf8));
@@ -109,35 +109,32 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
tim = ctime(&t); tim = ctime(&t);
*strchr(tim, '\n') = '\0'; *strchr(tim, '\n') = '\0';
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] " ctx->print(ctx, "%2u: %p %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x, references=%u]", i, s->name, "[flags=0x%x]", i, s, s->name, winlink_count(&s->windows),
winlink_count(&s->windows), tim, s->sx, s->sy, s->flags, tim, s->sx, s->sy, s->flags);
s->references);
RB_FOREACH(wl, winlinks, &s->windows) { RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window; w = wl->window;
ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, " ctx->print(ctx, "%4u: %p/%p %s [%ux%u] [flags=0x%x, "
"references=%u, last layout=%d]", wl->idx, w->name, "references=%u, layout=%u]", wl->idx, wl, w, w->name,
w->sx, w->sy, w->flags, w->references, w->sx, w->sy, w->flags, w->references, w->layout);
w->lastlayout);
j = 0; j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0; lines = ulines = size = usize = 0;
gd = wp->base.grid; gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) { for (k = 0; k < gd->hsize + gd->sy; k++) {
gl = &gd->linedata[k]; if (gd->data[k] != NULL) {
if (gl->celldata != NULL) {
lines++; lines++;
size += gl->cellsize * size += gd->size[k] *
sizeof *gl->celldata; sizeof (**gd->data);
} }
if (gl->utf8data != NULL) { if (gd->udata[k] != NULL) {
ulines++; ulines++;
usize += gl->utf8size * usize += gd->usize[k] *
sizeof *gl->utf8data; sizeof (**gd->udata);
} }
} }
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu " ctx->print(ctx, "%6u: %p %s %lu %d %u/%u, %zu "
"bytes; UTF-8 %u/%u, %zu bytes", j, "bytes; UTF-8 %u/%u, %zu bytes", j, wp,
wp->tty, (u_long) wp->pid, wp->fd, lines, wp->tty, (u_long) wp->pid, wp->fd, lines,
gd->hsize + gd->sy, size, ulines, gd->hsize + gd->sy, size, ulines,
gd->hsize + gd->sy, usize); gd->hsize + gd->sy, usize);
@@ -145,7 +142,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
} }
} }
} }
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
ctx->print(ctx, "Terminals:"); ctx->print(ctx, "Terminals:");
SLIST_FOREACH(term, &tty_terms, entry) { SLIST_FOREACH(term, &tty_terms, entry) {
@@ -160,8 +157,10 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ent->code, ent->name); ent->code, ent->name);
break; break;
case TTYCODE_STRING: case TTYCODE_STRING:
strnvis(out, code->value.string, sizeof out, strnvis(out, code->value.string,
VIS_OCTAL|VIS_TAB|VIS_NL); sizeof out, VIS_OCTAL|VIS_WHITE);
out[(sizeof out) - 1] = '\0';
ctx->print(ctx, "%2u: %s: (string) %s", ctx->print(ctx, "%2u: %s: (string) %s",
ent->code, ent->name, out); ent->code, ent->name, out);
break; break;
@@ -177,7 +176,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
} }
} }
} }
ctx->print(ctx, "%s", ""); ctx->print(ctx, "");
return (0); return (0);
} }

View File

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

View File

@@ -1,88 +0,0 @@
/* $Id: cmd-set-environment.c,v 1.2 2009-08-11 14:42:59 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Set an environment variable.
*/
int cmd_set_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv",
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
CMD_ARG12, CMD_CHFLAG('g')|CMD_CHFLAG('r')|CMD_CHFLAG('u'),
NULL,
cmd_target_parse,
cmd_set_environment_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct environ *env;
if (*data->arg == '\0') {
ctx->error(ctx, "empty variable name");
return (-1);
}
if (strchr(data->arg, '=') != NULL) {
ctx->error(ctx, "variable name contains =");
return (-1);
}
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
env = &s->environ;
}
if (data->chflags & CMD_CHFLAG('u')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -u");
return (-1);
}
environ_unset(env, data->arg);
} else if (data->chflags & CMD_CHFLAG('r')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -r");
return (-1);
}
environ_set(env, data->arg, NULL);
} else {
if (data->arg2 == NULL) {
ctx->error(ctx, "no value specified");
return (-1);
}
environ_set(env, data->arg, data->arg2);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.79 2009-09-19 18:53:01 tcunha Exp $ */ /* $Id: cmd-set-option.c,v 1.60 2009-03-21 12:44:06 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,34 +31,28 @@ int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_option_entry = { const struct cmd_entry cmd_set_option_entry = {
"set-option", "set", "set-option", "set",
"[-agu] " CMD_TARGET_SESSION_USAGE " option [value]", CMD_OPTION_SESSION_USAGE,
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'), CMD_GFLAG|CMD_UFLAG,
NULL, NULL,
cmd_target_parse, cmd_option_parse,
cmd_set_option_exec, cmd_set_option_exec,
cmd_target_free, cmd_option_send,
cmd_target_print cmd_option_recv,
cmd_option_free,
cmd_option_print
}; };
const char *set_option_status_keys_list[] = { const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL "emacs", "vi", NULL
}; };
const char *set_option_status_justify_list[] = {
"left", "centre", "right", NULL
};
const char *set_option_bell_action_list[] = { const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL "none", "any", "current", NULL
}; };
const struct set_option_entry set_option_table[] = { const struct set_option_entry set_option_table[NSETOPTION] = {
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list }, { "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "default-command", SET_OPTION_STRING, 0, 0, NULL }, { "default-command", SET_OPTION_STRING, 0, 0, NULL },
{ "default-path", SET_OPTION_STRING, 0, 0, NULL }, { "default-path", SET_OPTION_STRING, 0, 0, NULL },
{ "default-shell", SET_OPTION_STRING, 0, 0, NULL },
{ "default-terminal", SET_OPTION_STRING, 0, 0, NULL },
{ "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
@@ -69,83 +63,68 @@ const struct set_option_entry set_option_table[] = {
{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, { "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles", 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", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, 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-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list },
{ "status-left", SET_OPTION_STRING, 0, 0, NULL }, { "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-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, 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-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 }
}; };
int int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_option_data *data = self->data;
struct session *s; struct session *s;
struct client *c; struct client *c;
struct options *oo; struct options *oo;
const struct set_option_entry *entry, *opt; const struct set_option_entry *entry;
u_int i; u_int i;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_s_options; oo = &global_options;
else { else {
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
oo = &s->options; oo = &s->options;
} }
if (*data->arg == '\0') { if (*data->option == '\0') {
ctx->error(ctx, "invalid option"); ctx->error(ctx, "invalid option");
return (-1); return (-1);
} }
entry = NULL; entry = NULL;
for (opt = set_option_table; opt->name != NULL; opt++) { for (i = 0; i < NSETOPTION; i++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0) if (strncmp(set_option_table[i].name,
data->option, strlen(data->option)) != 0)
continue; continue;
if (entry != NULL) { if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg); ctx->error(ctx, "ambiguous option: %s", data->option);
return (-1); return (-1);
} }
entry = opt; entry = &set_option_table[i];
/* Bail now if an exact match. */ /* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0) if (strcmp(entry->name, data->option) == 0)
break; break;
} }
if (entry == NULL) { if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg); ctx->error(ctx, "unknown option: %s", data->option);
return (-1); return (-1);
} }
if (data->chflags & CMD_CHFLAG('u')) { if (data->flags & CMD_UFLAG) {
if (data->chflags & CMD_CHFLAG('g')) { if (data->flags & CMD_GFLAG) {
ctx->error(ctx, ctx->error(ctx,
"can't unset global option: %s", entry->name); "can't unset global option: %s", entry->name);
return (-1); return (-1);
} }
if (data->arg2 != NULL) { if (data->value != NULL) {
ctx->error(ctx, ctx->error(ctx,
"value passed to unset option: %s", entry->name); "value passed to unset option: %s", entry->name);
return (-1); return (-1);
@@ -156,26 +135,25 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else { } else {
switch (entry->type) { switch (entry->type) {
case SET_OPTION_STRING: case SET_OPTION_STRING:
set_option_string(ctx, oo, entry, set_option_string(ctx, oo, entry, data->value);
data->arg2, data->chflags & CMD_CHFLAG('a'));
break; break;
case SET_OPTION_NUMBER: case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2); set_option_number(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_KEY: case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->arg2); set_option_key(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_COLOUR: case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2); set_option_colour(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_ATTRIBUTES: case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2); set_option_attributes(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_FLAG: case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2); set_option_flag(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_CHOICE: case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2); set_option_choice(ctx, oo, entry, data->value);
break; break;
} }
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-password.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-set-password.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,6 +29,8 @@
int cmd_set_password_parse(struct cmd *, int, char **, char **); int cmd_set_password_parse(struct cmd *, int, char **, char **);
int cmd_set_password_exec(struct cmd *, struct cmd_ctx *); int cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_password_send(struct cmd *, struct buffer *);
void cmd_set_password_recv(struct cmd *, struct buffer *);
void cmd_set_password_free(struct cmd *); void cmd_set_password_free(struct cmd *);
void cmd_set_password_init(struct cmd *, int); void cmd_set_password_init(struct cmd *, int);
size_t cmd_set_password_print(struct cmd *, char *, size_t); size_t cmd_set_password_print(struct cmd *, char *, size_t);
@@ -41,10 +43,12 @@ struct cmd_set_password_data {
const struct cmd_entry cmd_set_password_entry = { const struct cmd_entry cmd_set_password_entry = {
"set-password", "pass", "set-password", "pass",
"[-c] password", "[-c] password",
0, 0, 0,
cmd_set_password_init, cmd_set_password_init,
cmd_set_password_parse, cmd_set_password_parse,
cmd_set_password_exec, cmd_set_password_exec,
cmd_set_password_send,
cmd_set_password_recv,
cmd_set_password_free, cmd_set_password_free,
cmd_set_password_print cmd_set_password_print
}; };
@@ -114,10 +118,30 @@ cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
server_password = NULL; server_password = NULL;
else else
server_password = xstrdup(data->password); server_password = xstrdup(data->password);
log_debug("pw now %s", server_password);
return (0); return (0);
} }
void
cmd_set_password_send(struct cmd *self, struct buffer *b)
{
struct cmd_set_password_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->password);
}
void
cmd_set_password_recv(struct cmd *self, struct buffer *b)
{
struct cmd_set_password_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->password = cmd_recv_string(b);
}
void void
cmd_set_password_free(struct cmd *self) cmd_set_password_free(struct cmd *self)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.38 2009-08-11 14:42:59 nicm Exp $ */ /* $Id: cmd-set-window-option.c,v 1.24 2009-01-30 00:24:49 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,17 +27,24 @@
* Set a window option. * Set a window option.
*/ */
int cmd_set_window_option_parse(struct cmd *, int, char **, char **);
int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *); int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_window_option_send(struct cmd *, struct buffer *);
void cmd_set_window_option_recv(struct cmd *, struct buffer *);
void cmd_set_window_option_free(struct cmd *);
size_t cmd_set_window_option_print(struct cmd *, char *, size_t);
const struct cmd_entry cmd_set_window_option_entry = { const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw", "set-window-option", "setw",
"[-agu] " CMD_TARGET_WINDOW_USAGE " option [value]", CMD_OPTION_WINDOW_USAGE,
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'), CMD_GFLAG|CMD_UFLAG,
NULL, NULL,
cmd_target_parse, cmd_option_parse,
cmd_set_window_option_exec, cmd_set_window_option_exec,
cmd_target_free, cmd_option_send,
cmd_target_print cmd_option_recv,
cmd_option_free,
cmd_option_print
}; };
const char *set_option_mode_keys_list[] = { const char *set_option_mode_keys_list[] = {
@@ -46,7 +53,7 @@ const char *set_option_mode_keys_list[] = {
const char *set_option_clock_mode_style_list[] = { const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL "12", "24", NULL
}; };
const struct set_option_entry set_window_option_table[] = { const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL }, { "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", 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-colour", SET_OPTION_COLOUR, 0, 0, NULL },
@@ -54,76 +61,69 @@ const struct set_option_entry set_window_option_table[] = {
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list }, SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", 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-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", 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-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-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, { "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL }, { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL }, { "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
}; };
int int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_option_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct client *c; struct client *c;
struct options *oo; struct options *oo;
const struct set_option_entry *entry, *opt; const struct set_option_entry *entry;
u_int i; u_int i;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_w_options; oo = &global_window_options;
else { else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
oo = &wl->window->options; oo = &wl->window->options;
} }
if (*data->arg == '\0') { if (*data->option == '\0') {
ctx->error(ctx, "invalid option"); ctx->error(ctx, "invalid option");
return (-1); return (-1);
} }
entry = NULL; entry = NULL;
for (opt = set_window_option_table; opt->name != NULL; opt++) { for (i = 0; i < NSETWINDOWOPTION; i++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0) if (strncmp(set_window_option_table[i].name,
data->option, strlen(data->option)) != 0)
continue; continue;
if (entry != NULL) { if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg); ctx->error(ctx, "ambiguous option: %s", data->option);
return (-1); return (-1);
} }
entry = opt; entry = &set_window_option_table[i];
/* Bail now if an exact match. */ /* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0) if (strcmp(entry->name, data->option) == 0)
break; break;
} }
if (entry == NULL) { if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg); ctx->error(ctx, "unknown option: %s", data->option);
return (-1); return (-1);
} }
if (data->chflags & CMD_CHFLAG('u')) { if (data->flags & CMD_UFLAG) {
if (data->chflags & CMD_CHFLAG('g')) { if (data->flags & CMD_GFLAG) {
ctx->error(ctx, ctx->error(ctx,
"can't unset global option: %s", entry->name); "can't unset global option: %s", entry->name);
return (-1); return (-1);
} }
if (data->arg2 != NULL) { if (data->value != NULL) {
ctx->error(ctx, ctx->error(ctx,
"value passed to unset option: %s", entry->name); "value passed to unset option: %s", entry->name);
return (-1); return (-1);
@@ -134,26 +134,25 @@ cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else { } else {
switch (entry->type) { switch (entry->type) {
case SET_OPTION_STRING: case SET_OPTION_STRING:
set_option_string(ctx, oo, entry, set_option_string(ctx, oo, entry, data->value);
data->arg2, data->chflags & CMD_CHFLAG('a'));
break; break;
case SET_OPTION_NUMBER: case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2); set_option_number(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_KEY: case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->arg2); set_option_key(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_COLOUR: case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2); set_option_colour(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_ATTRIBUTES: case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2); set_option_attributes(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_FLAG: case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2); set_option_flag(ctx, oo, entry, data->value);
break; break;
case SET_OPTION_CHOICE: case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2); set_option_choice(ctx, oo, entry, data->value);
break; break;
} }
} }

View File

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

View File

@@ -1,67 +0,0 @@
/* $Id: cmd-show-environment.c,v 1.1 2009-08-09 17:48:55 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Show environment.
*/
int cmd_show_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv",
"[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'),
cmd_target_init,
cmd_target_parse,
cmd_show_environment_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct environ *env;
struct environ_entry *envent;
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
env = &s->environ;
}
RB_FOREACH(envent, environ, env) {
if (envent->value != NULL)
ctx->print(ctx, "%s=%s", envent->name, envent->value);
else
ctx->print(ctx, "-%s", envent->name);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.16 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-show-options.c,v 1.11 2009-01-27 20:22:33 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_options_entry = { const struct cmd_entry cmd_show_options_entry = {
"show-options", "show", "show-options", "show",
"[-g] " CMD_TARGET_SESSION_USAGE, "[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'), CMD_GFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_show_options_exec, cmd_show_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -47,18 +49,21 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s; struct session *s;
struct options *oo; struct options *oo;
const struct set_option_entry *entry; const struct set_option_entry *entry;
u_int i;
char *vs; char *vs;
long long vn; long long vn;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_s_options; oo = &global_options;
else { else {
if ((s = cmd_find_session(ctx, data->target)) == NULL) if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1); return (-1);
oo = &s->options; oo = &s->options;
} }
for (entry = set_option_table; entry->name != NULL; entry++) { for (i = 0; i < NSETOPTION; i++) {
entry = &set_option_table[i];
if (options_find1(oo, entry->name) == NULL) if (options_find1(oo, entry->name) == NULL)
continue; continue;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-window-options.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-show-window-options.c,v 1.7 2009-01-27 20:22:33 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,10 +32,12 @@ int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_window_options_entry = { const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw", "show-window-options", "showw",
"[-g] " CMD_TARGET_WINDOW_USAGE, "[-g] " CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('g'), CMD_GFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_show_window_options_exec, cmd_show_window_options_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -47,18 +49,21 @@ cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
struct winlink *wl; struct winlink *wl;
struct options *oo; struct options *oo;
const struct set_option_entry *entry; const struct set_option_entry *entry;
u_int i;
char *vs; char *vs;
long long vn; long long vn;
if (data->chflags & CMD_CHFLAG('g')) if (data->flags & CMD_GFLAG)
oo = &global_w_options; oo = &global_window_options;
else { else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
oo = &wl->window->options; oo = &wl->window->options;
} }
for (entry = set_window_option_table; entry->name != NULL; entry++) { for (i = 0; i < NSETWINDOWOPTION; i++) {
entry = &set_window_option_table[i];
if (options_find1(oo, entry->name) == NULL) if (options_find1(oo, entry->name) == NULL)
continue; continue;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-source-file.c,v 1.8 2009-08-24 16:27:03 tcunha Exp $ */ /* $Id: cmd-source-file.c,v 1.5 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -26,6 +26,8 @@
int cmd_source_file_parse(struct cmd *, int, char **, char **); int cmd_source_file_parse(struct cmd *, int, char **, char **);
int cmd_source_file_exec(struct cmd *, struct cmd_ctx *); int cmd_source_file_exec(struct cmd *, struct cmd_ctx *);
void cmd_source_file_send(struct cmd *, struct buffer *);
void cmd_source_file_recv(struct cmd *, struct buffer *);
void cmd_source_file_free(struct cmd *); void cmd_source_file_free(struct cmd *);
void cmd_source_file_init(struct cmd *, int); void cmd_source_file_init(struct cmd *, int);
size_t cmd_source_file_print(struct cmd *, char *, size_t); size_t cmd_source_file_print(struct cmd *, char *, size_t);
@@ -37,10 +39,12 @@ struct cmd_source_file_data {
const struct cmd_entry cmd_source_file_entry = { const struct cmd_entry cmd_source_file_entry = {
"source-file", "source", "source-file", "source",
"path", "path",
0, 0, 0,
cmd_source_file_init, cmd_source_file_init,
cmd_source_file_parse, cmd_source_file_parse,
cmd_source_file_exec, cmd_source_file_exec,
cmd_source_file_send,
cmd_source_file_recv,
cmd_source_file_free, cmd_source_file_free,
cmd_source_file_print cmd_source_file_print
}; };
@@ -90,7 +94,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_source_file_data *data = self->data; struct cmd_source_file_data *data = self->data;
char *cause; char *cause;
if (load_cfg(data->path, ctx, &cause) != 0) { if (load_cfg(data->path, &cause) != 0) {
ctx->error(ctx, "%s", cause); ctx->error(ctx, "%s", cause);
xfree(cause); xfree(cause);
return (-1); return (-1);
@@ -99,6 +103,25 @@ cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0); return (0);
} }
void
cmd_source_file_send(struct cmd *self, struct buffer *b)
{
struct cmd_source_file_data *data = self->data;
buffer_write(b, data, sizeof *data);
cmd_send_string(b, data->path);
}
void
cmd_source_file_recv(struct cmd *self, struct buffer *b)
{
struct cmd_source_file_data *data;
self->data = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
data->path = cmd_recv_string(b);
}
void void
cmd_source_file_free(struct cmd *self) cmd_source_file_free(struct cmd *self)
{ {

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.23 2009-08-09 17:48:55 tcunha Exp $ */ /* $Id: cmd-string.c,v 1.13 2009-02-16 19:29:17 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,11 +19,9 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -35,7 +33,6 @@ int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(const char *, size_t *); void cmd_string_ungetc(const char *, size_t *);
char *cmd_string_string(const char *, size_t *, char, int); char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *); char *cmd_string_variable(const char *, size_t *);
char *cmd_string_expand_tilde(const char *, size_t *);
int int
cmd_string_getc(const char *s, size_t *p) cmd_string_getc(const char *s, size_t *p)
@@ -59,11 +56,21 @@ int
cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause) cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
{ {
size_t p; size_t p;
int ch, i, argc, rval, have_arg; int ch, argc, rval, have_arg;
char **argv, *buf, *t; char **argv, *buf, *t, *u;
const char *whitespace, *equals;
size_t len; size_t len;
if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL)
t = strchr(s, '\0');
if ((u = strchr(s, '=')) != NULL && u < t) {
if (putenv(s) != 0) {
xasprintf(cause, "assignment failed: %s", s);
return (-1);
}
*cmdlist = NULL;
return (0);
}
argv = NULL; argv = NULL;
argc = 0; argc = 0;
@@ -107,7 +114,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = xrealloc(buf, 1, len + strlen(t) + 1); buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1); strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t); len += strlen(t);
xfree(t);
have_arg = 1; have_arg = 1;
break; break;
@@ -137,18 +143,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
if (argc == 0) if (argc == 0)
goto out; goto out;
for (i = 0; i < argc; i++) {
equals = strchr(argv[i], '=');
whitespace = argv[i] + strcspn(argv[i], " \t");
if (equals == NULL || equals > whitespace)
break;
environ_put(&global_environ, argv[i]);
memmove(&argv[i], &argv[i + 1], argc - i - 1);
argc--;
}
if (argc == 0)
goto out;
*cmdlist = cmd_list_parse(argc, argv, cause); *cmdlist = cmd_list_parse(argc, argv, cause);
if (*cmdlist == NULL) if (*cmdlist == NULL)
goto out; goto out;
@@ -159,17 +153,6 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
rval = 0; rval = 0;
goto out; goto out;
case '~':
if (have_arg == 0) {
if ((t = cmd_string_expand_tilde(s, &p)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
break;
}
/* FALLTHROUGH */
default: default:
if (len >= SIZE_MAX - 2) if (len >= SIZE_MAX - 2)
goto error; goto error;
@@ -217,9 +200,6 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
switch (ch = cmd_string_getc(s, p)) { switch (ch = cmd_string_getc(s, p)) {
case EOF: case EOF:
goto error; goto error;
case 'e':
ch = '\033';
break;
case 'r': case 'r':
ch = '\r'; ch = '\r';
break; break;
@@ -239,7 +219,6 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
buf = xrealloc(buf, 1, len + strlen(t) + 1); buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1); strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t); len += strlen(t);
xfree(t);
continue; continue;
} }
@@ -295,7 +274,7 @@ cmd_string_variable(const char *s, size_t *p)
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch; buf[len++] = ch;
for (;;) { for(;;) {
ch = cmd_string_getc(s, p); ch = cmd_string_getc(s, p);
if (ch == EOF || !cmd_string_other(ch)) if (ch == EOF || !cmd_string_other(ch))
break; break;
@@ -328,31 +307,3 @@ error:
xfree(buf); xfree(buf);
return (NULL); return (NULL);
} }
char *
cmd_string_expand_tilde(const char *s, size_t *p)
{
struct passwd *pw;
char *home, *path, *username;
home = NULL;
if (cmd_string_getc(s, p) == '/') {
if ((home = getenv("HOME")) == NULL) {
if ((pw = getpwuid(getuid())) != NULL)
home = pw->pw_dir;
}
} else {
cmd_string_ungetc(s, p);
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
return (NULL);
if ((pw = getpwnam(username)) != NULL)
home = pw->pw_dir;
if (username != NULL)
xfree(username);
}
if (home == NULL)
return (NULL);
xasprintf(&path, "%s/", home);
return (path);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-suspend-client.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-suspend-client.c,v 1.2 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -37,10 +37,12 @@ struct cmd_suspend_client_data {
const struct cmd_entry cmd_suspend_client_entry = { const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc", "suspend-client", "suspendc",
"[-c target-client]", "[-c target-client]",
0, 0, 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_suspend_client_exec, cmd_suspend_client_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-window.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-swap-window.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,12 @@ int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_window_entry = { const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw", "swap-window", "swapw",
"[-d] " CMD_SRCDST_WINDOW_USAGE, "[-d] " CMD_SRCDST_WINDOW_USAGE,
0, CMD_CHFLAG('d'), CMD_DFLAG,
cmd_srcdst_init, cmd_srcdst_init,
cmd_srcdst_parse, cmd_srcdst_parse,
cmd_swap_window_exec, cmd_swap_window_exec,
cmd_srcdst_send,
cmd_srcdst_recv,
cmd_srcdst_free, cmd_srcdst_free,
cmd_srcdst_print cmd_srcdst_print
}; };
@@ -59,7 +61,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl_dst->window = wl_src->window; wl_dst->window = wl_src->window;
wl_src->window = w; wl_src->window = w;
if (!(data->chflags & CMD_CHFLAG('d'))) { if (!(data->flags & CMD_DFLAG)) {
session_select(dst, wl_dst->idx); session_select(dst, wl_dst->idx);
if (src != dst) if (src != dst)
session_select(src, wl_src->idx); session_select(src, wl_src->idx);

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unlink-window.c,v 1.16 2009-07-28 22:12:16 tcunha Exp $ */ /* $Id: cmd-unlink-window.c,v 1.13 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,11 +28,13 @@ int cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_unlink_window_entry = { const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw", "unlink-window", "unlinkw",
"[-k] " CMD_TARGET_WINDOW_USAGE, CMD_TARGET_WINDOW_USAGE,
0, CMD_CHFLAG('k'), 0,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_unlink_window_exec, cmd_unlink_window_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free, cmd_target_free,
cmd_target_print cmd_target_print
}; };
@@ -50,7 +52,7 @@ cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);
if (!(data->chflags & CMD_CHFLAG('k')) && wl->window->references == 1) { if (wl->window->references == 1) {
ctx->error(ctx, "window is only linked to one session"); ctx->error(ctx, "window is only linked to one session");
return (-1); return (-1);
} }

View File

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

790
cmd.c
View File

@@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.115 2009-08-31 22:30:15 tcunha Exp $ */ /* $Id: cmd.c,v 1.89 2009-04-03 17:21:46 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,7 +19,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <fnmatch.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@@ -30,23 +29,17 @@ const struct cmd_entry *cmd_table[] = {
&cmd_attach_session_entry, &cmd_attach_session_entry,
&cmd_bind_key_entry, &cmd_bind_key_entry,
&cmd_break_pane_entry, &cmd_break_pane_entry,
&cmd_choose_client_entry,
&cmd_choose_session_entry, &cmd_choose_session_entry,
&cmd_choose_window_entry, &cmd_choose_window_entry,
&cmd_clear_history_entry,
&cmd_clock_mode_entry, &cmd_clock_mode_entry,
&cmd_command_prompt_entry, &cmd_command_prompt_entry,
&cmd_confirm_before_entry,
&cmd_copy_buffer_entry, &cmd_copy_buffer_entry,
&cmd_copy_mode_entry, &cmd_copy_mode_entry,
&cmd_delete_buffer_entry, &cmd_delete_buffer_entry,
&cmd_detach_client_entry, &cmd_detach_client_entry,
&cmd_display_message_entry,
&cmd_display_panes_entry,
&cmd_down_pane_entry, &cmd_down_pane_entry,
&cmd_find_window_entry, &cmd_find_window_entry,
&cmd_has_session_entry, &cmd_has_session_entry,
&cmd_if_shell_entry,
&cmd_kill_pane_entry, &cmd_kill_pane_entry,
&cmd_kill_server_entry, &cmd_kill_server_entry,
&cmd_kill_session_entry, &cmd_kill_session_entry,
@@ -67,17 +60,16 @@ const struct cmd_entry *cmd_table[] = {
&cmd_next_layout_entry, &cmd_next_layout_entry,
&cmd_next_window_entry, &cmd_next_window_entry,
&cmd_paste_buffer_entry, &cmd_paste_buffer_entry,
&cmd_previous_layout_entry,
&cmd_previous_window_entry, &cmd_previous_window_entry,
&cmd_refresh_client_entry, &cmd_refresh_client_entry,
&cmd_rename_session_entry, &cmd_rename_session_entry,
&cmd_rename_window_entry, &cmd_rename_window_entry,
&cmd_resize_pane_entry, &cmd_resize_pane_down_entry,
&cmd_respawn_window_entry, &cmd_resize_pane_up_entry,
&cmd_respawn_window_entry,
&cmd_rotate_window_entry, &cmd_rotate_window_entry,
&cmd_save_buffer_entry, &cmd_save_buffer_entry,
&cmd_scroll_mode_entry, &cmd_scroll_mode_entry,
&cmd_select_layout_entry,
&cmd_select_pane_entry, &cmd_select_pane_entry,
&cmd_select_prompt_entry, &cmd_select_prompt_entry,
&cmd_select_window_entry, &cmd_select_window_entry,
@@ -85,12 +77,10 @@ const struct cmd_entry *cmd_table[] = {
&cmd_send_prefix_entry, &cmd_send_prefix_entry,
&cmd_server_info_entry, &cmd_server_info_entry,
&cmd_set_buffer_entry, &cmd_set_buffer_entry,
&cmd_set_environment_entry,
&cmd_set_option_entry, &cmd_set_option_entry,
&cmd_set_password_entry, &cmd_set_password_entry,
&cmd_set_window_option_entry, &cmd_set_window_option_entry,
&cmd_show_buffer_entry, &cmd_show_buffer_entry,
&cmd_show_environment_entry,
&cmd_show_options_entry, &cmd_show_options_entry,
&cmd_show_window_options_entry, &cmd_show_window_options_entry,
&cmd_source_file_entry, &cmd_source_file_entry,
@@ -106,89 +96,22 @@ const struct cmd_entry *cmd_table[] = {
NULL NULL
}; };
struct session *cmd_newest_session(struct sessions *);
struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(const char *, int *);
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
int cmd_lookup_index(struct session *, const char *, int *);
int
cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
{
size_t arglen;
int i;
*buf = '\0';
for (i = 0; i < argc; i++) {
if (strlcpy(buf, argv[i], len) >= len)
return (-1);
arglen = strlen(argv[i]) + 1;
buf += arglen;
len -= arglen;
}
return (0);
}
int
cmd_unpack_argv(char *buf, size_t len, int argc, char ***argv)
{
int i;
size_t arglen;
if (argc == 0)
return (0);
*argv = xcalloc(argc, sizeof **argv);
buf[len - 1] = '\0';
for (i = 0; i < argc; i++) {
if (len == 0) {
cmd_free_argv(argc, *argv);
return (-1);
}
arglen = strlen(buf) + 1;
(*argv)[i] = xstrdup(buf);
buf += arglen;
len -= arglen;
}
return (0);
}
void
cmd_free_argv(int argc, char **argv)
{
int i;
if (argc == 0)
return;
for (i = 0; i < argc; i++) {
if (argv[i] != NULL)
xfree(argv[i]);
}
xfree(argv);
}
struct cmd * struct cmd *
cmd_parse(int argc, char **argv, char **cause) cmd_parse(int argc, char **argv, char **cause)
{ {
const struct cmd_entry **entryp, *entry; const struct cmd_entry **entryp, *entry;
struct cmd *cmd; struct cmd *cmd;
char s[BUFSIZ]; char s[BUFSIZ];
int opt, ambiguous = 0; int opt;
*cause = NULL; *cause = NULL;
if (argc == 0) { if (argc == 0)
xasprintf(cause, "no command");
return (NULL); return (NULL);
}
entry = NULL; entry = NULL;
for (entryp = cmd_table; *entryp != NULL; entryp++) { for (entryp = cmd_table; *entryp != NULL; entryp++) {
if ((*entryp)->alias != NULL && if ((*entryp)->alias != NULL &&
strcmp((*entryp)->alias, argv[0]) == 0) { strcmp((*entryp)->alias, argv[0]) == 0) {
ambiguous = 0;
entry = *entryp; entry = *entryp;
break; break;
} }
@@ -196,15 +119,13 @@ cmd_parse(int argc, char **argv, char **cause)
if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0) if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0)
continue; continue;
if (entry != NULL) if (entry != NULL)
ambiguous = 1; goto ambiguous;
entry = *entryp; entry = *entryp;
/* Bail now if an exact match. */ /* Bail now if an exact match. */
if (strcmp(entry->name, argv[0]) == 0) if (strcmp(entry->name, argv[0]) == 0)
break; break;
} }
if (ambiguous)
goto ambiguous;
if (entry == NULL) { if (entry == NULL) {
xasprintf(cause, "unknown command: %s", argv[0]); xasprintf(cause, "unknown command: %s", argv[0]);
return (NULL); return (NULL);
@@ -265,6 +186,53 @@ cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
return (cmd->entry->exec(cmd, ctx)); return (cmd->entry->exec(cmd, ctx));
} }
void
cmd_send(struct cmd *cmd, struct buffer *b)
{
const struct cmd_entry **entryp;
u_int n;
n = 0;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
if (*entryp == cmd->entry)
break;
n++;
}
if (*entryp == NULL)
fatalx("command not found");
buffer_write(b, &n, sizeof n);
if (cmd->entry->send != NULL)
cmd->entry->send(cmd, b);
}
struct cmd *
cmd_recv(struct buffer *b)
{
const struct cmd_entry **entryp;
struct cmd *cmd;
u_int m, n;
buffer_read(b, &m, sizeof m);
n = 0;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
if (n == m)
break;
n++;
}
if (*entryp == NULL)
fatalx("command not found");
cmd = xmalloc(sizeof *cmd);
cmd->entry = *entryp;
if (cmd->entry->recv != NULL)
cmd->entry->recv(cmd, b);
return (cmd);
}
void void
cmd_free(struct cmd *cmd) cmd_free(struct cmd *cmd)
{ {
@@ -282,621 +250,141 @@ cmd_print(struct cmd *cmd, char *buf, size_t len)
return (cmd->entry->print(cmd, buf, len)); return (cmd->entry->print(cmd, buf, len));
} }
/* void
* Figure out the current session. Use: 1) the current session, if the command cmd_send_string(struct buffer *b, const char *s)
* context has one; 2) the session containing the pty of the calling client, if {
* any 3) the session specified in the TMUX variable from the environment (as size_t n;
* passed from the client); 3) the newest session.
*/ if (s == NULL) {
n = 0;
buffer_write(b, &n, sizeof n);
return;
}
n = strlen(s) + 1;
buffer_write(b, &n, sizeof n);
buffer_write(b, s, n);
}
char *
cmd_recv_string(struct buffer *b)
{
char *s;
size_t n;
buffer_read(b, &n, sizeof n);
if (n == 0)
return (NULL);
s = xmalloc(n);
buffer_read(b, s, n);
s[n - 1] = '\0';
return (s);
}
struct session * struct session *
cmd_current_session(struct cmd_ctx *ctx) cmd_current_session(struct cmd_ctx *ctx)
{ {
struct msg_command_data *data = ctx->msgdata; struct msg_command_data *data = ctx->msgdata;
struct client *c = ctx->cmdclient; struct timeval *tv;
struct session *s; struct session *s, *newest = NULL;
struct sessions ss;
struct winlink *wl;
struct window_pane *wp;
u_int i; u_int i;
int found;
if (ctx->curclient != NULL && ctx->curclient->session != NULL) if (ctx->cursession != NULL)
return (ctx->curclient->session); return (ctx->cursession);
/*
* If the name of the calling client's pty is know, build a list of the
* sessions that contain it and if any choose either the first or the
* newest.
*/
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;
found = 0;
RB_FOREACH(wl, winlinks, &s->windows) {
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
if (strcmp(wp->tty, c->tty.path) == 0) {
found = 1;
break;
}
}
if (found)
break;
}
if (found)
ARRAY_ADD(&ss, s);
}
s = cmd_newest_session(&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 != NULL && data->pid != -1) {
if (data->pid != getpid()) if (data->pid != getpid()) {
ctx->error(ctx, "wrong server: %ld", (long) data->pid);
return (NULL); return (NULL);
if (data->idx > ARRAY_LENGTH(&sessions)) }
if (data->idx > ARRAY_LENGTH(&sessions)) {
ctx->error(ctx, "index out of range: %d", data->idx);
return (NULL); return (NULL);
if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL) }
if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL) {
ctx->error(ctx, "session doesn't exist: %u", data->idx);
return (NULL); return (NULL);
}
return (s); return (s);
} }
return (cmd_newest_session(&sessions)); tv = NULL;
} for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
/* Find the newest session. */ if (s != NULL && (tv == NULL || timercmp(&s->tv, tv, >))) {
struct session * newest = ARRAY_ITEM(&sessions, i);
cmd_newest_session(struct sessions *ss)
{
struct session *s, *snewest;
struct timeval *tv = NULL;
u_int i;
snewest = NULL;
for (i = 0; i < ARRAY_LENGTH(ss); i++) {
if ((s = ARRAY_ITEM(ss, i)) == NULL)
continue;
if (tv == NULL || timercmp(&s->tv, tv, >)) {
snewest = s;
tv = &s->tv; tv = &s->tv;
} }
} }
return (newest);
return (snewest);
} }
/* Find the target client or report an error and return NULL. */
struct client * struct client *
cmd_find_client(struct cmd_ctx *ctx, const char *arg) cmd_find_client(struct cmd_ctx *ctx, const char *arg)
{ {
struct client *c; struct client *c;
char *tmparg;
size_t arglen;
/* A NULL argument means the current client. */
if (arg == NULL) if (arg == NULL)
return (ctx->curclient); c = ctx->curclient;
tmparg = xstrdup(arg); else {
if ((c = arg_parse_client(arg)) == NULL) {
/* Trim a single trailing colon if any. */ if (arg != NULL)
arglen = strlen(tmparg); ctx->error(ctx, "client not found: %s", arg);
if (arglen != 0 && tmparg[arglen - 1] == ':') else
tmparg[arglen - 1] = '\0'; ctx->error(ctx, "no client found");
}
/* Find the client, if any. */ }
c = cmd_lookup_client(tmparg);
/* If no client found, report an error. */
if (c == NULL)
ctx->error(ctx, "client not found: %s", tmparg);
xfree(tmparg);
return (c); return (c);
} }
/*
* Lookup a client by device path. Either of a full match and a match without a
* leading _PATH_DEV ("/dev/") is accepted.
*/
struct client *
cmd_lookup_client(const char *name)
{
struct client *c;
const char *path;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
continue;
path = c->tty.path;
/* Check for exact matches. */
if (strcmp(name, path) == 0)
return (c);
/* Check without leading /dev if present. */
if (strncmp(path, _PATH_DEV, (sizeof _PATH_DEV) - 1) != 0)
continue;
if (strcmp(name, path + (sizeof _PATH_DEV) - 1) == 0)
return (c);
}
return (NULL);
}
/* Lookup a session by name. If no session is found, NULL is returned. */
struct session *
cmd_lookup_session(const char *name, int *ambiguous)
{
struct session *s, *sfound;
u_int i;
*ambiguous = 0;
/*
* Look for matches. Session names must be unique so an exact match
* can't be ambigious and can just be returned.
*/
sfound = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
/* Check for an exact match and return it if found. */
if (strcmp(name, s->name) == 0)
return (s);
/* Then check for pattern matches. */
if (strncmp(name, s->name, strlen(name)) == 0 ||
fnmatch(name, s->name, 0) == 0) {
if (sfound != NULL) {
*ambiguous = 1;
return (NULL);
}
sfound = s;
}
}
return (sfound);
}
/*
* Lookup a window or return -1 if not found or ambigious. First try as an
* index and if invalid, use fnmatch or leading prefix. Return NULL but fill in
* idx if the window index is a valid number but there is now window with that
* index.
*/
struct winlink *
cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
{
struct winlink *wl, *wlfound;
const char *errstr;
u_int idx;
*ambiguous = 0;
/* First see if this is a valid window index in this session. */
idx = strtonum(name, 0, INT_MAX, &errstr);
if (errstr == NULL) {
if ((wl = winlink_find_by_index(&s->windows, idx)) != NULL)
return (wl);
}
/* Look for exact matches, error if more than one. */
wlfound = NULL;
RB_FOREACH(wl, winlinks, &s->windows) {
if (strcmp(name, wl->window->name) == 0) {
if (wlfound != NULL) {
*ambiguous = 1;
return (NULL);
}
wlfound = wl;
}
}
if (wlfound != NULL)
return (wlfound);
/* Now look for pattern matches, again error if multiple. */
wlfound = NULL;
RB_FOREACH(wl, winlinks, &s->windows) {
if (strncmp(name, wl->window->name, strlen(name)) == 0 ||
fnmatch(name, wl->window->name, 0) == 0) {
if (wlfound != NULL) {
*ambiguous = 1;
return (NULL);
}
wlfound = wl;
}
}
if (wlfound != NULL)
return (wlfound);
return (NULL);
}
/*
* Find a window index - if the window doesn't exist, check if it is a
* potential index and return it anyway.
*/
int
cmd_lookup_index(struct session *s, const char *name, int *ambiguous)
{
struct winlink *wl;
const char *errstr;
u_int idx;
if ((wl = cmd_lookup_window(s, name, ambiguous)) != NULL)
return (wl->idx);
if (*ambiguous)
return (-1);
idx = strtonum(name, 0, INT_MAX, &errstr);
if (errstr == NULL)
return (idx);
return (-1);
}
/* Find the target session or report an error and return NULL. */
struct session * struct session *
cmd_find_session(struct cmd_ctx *ctx, const char *arg) cmd_find_session(struct cmd_ctx *ctx, const char *arg)
{ {
struct session *s; struct session *s;
struct client *c;
char *tmparg;
size_t arglen;
int ambiguous;
/* A NULL argument means the current session. */
if (arg == NULL) if (arg == NULL)
return (cmd_current_session(ctx)); s = cmd_current_session(ctx);
tmparg = xstrdup(arg); else {
if ((s = arg_parse_session(arg)) == NULL) {
/* Trim a single trailing colon if any. */ if (arg != NULL)
arglen = strlen(tmparg); ctx->error(ctx, "session not found: %s", arg);
if (arglen != 0 && tmparg[arglen - 1] == ':') else
tmparg[arglen - 1] = '\0'; ctx->error(ctx, "no session found");
}
/* Find the session, if any. */
s = cmd_lookup_session(tmparg, &ambiguous);
/* If it doesn't, try to match it as a client. */
if (s == NULL && (c = cmd_lookup_client(tmparg)) != NULL)
s = c->session;
/* If no session found, report an error. */
if (s == NULL) {
if (ambiguous)
ctx->error(ctx, "more than one session: %s", tmparg);
else
ctx->error(ctx, "session not found: %s", tmparg);
} }
xfree(tmparg);
return (s); return (s);
} }
/* Find the target session and window or report an error and return NULL. */
struct winlink * struct winlink *
cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
{ {
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
const char *winptr; int idx;
char *sessptr = NULL;
int ambiguous = 0;
/* wl = NULL;
* Find the current session. There must always be a current session, if if (arg_parse_window(arg, &s, &idx) != 0) {
* it can't be found, report an error. ctx->error(ctx, "bad window: %s", arg);
*/
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
return (NULL); return (NULL);
} }
if (s == NULL)
/* A NULL argument means the current session and window. */ s = ctx->cursession;
if (arg == NULL) { if (s == NULL)
if (sp != NULL) s = cmd_current_session(ctx);
*sp = s; if (s == NULL)
return (s->curw);
}
/* Time to look at the argument. If it is empty, that is an error. */
if (*arg == '\0')
goto not_found;
/* Find the separating colon and split into window and session. */
winptr = strchr(arg, ':');
if (winptr == NULL)
goto no_colon;
winptr++; /* skip : */
sessptr = xstrdup(arg);
*strchr(sessptr, ':') = '\0';
/* Try to lookup the session if present. */
if (*sessptr != '\0') {
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL)
goto no_session;
}
if (sp != NULL)
*sp = s;
/*
* Then work out the window. An empty string is the current window,
* otherwise try to look it up in the session.
*/
if (*winptr == '\0')
wl = s->curw;
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL)
goto not_found;
if (sessptr != NULL)
xfree(sessptr);
return (wl);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
wl = s->curw;
}
if (sp != NULL)
*sp = s;
return (wl);
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
else
ctx->error(ctx, "session not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (NULL);
not_found:
if (ambiguous)
ctx->error(ctx, "multiple windows: %s", arg);
else
ctx->error(ctx, "window not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (NULL);
}
/*
* Find the target session and window index, whether or not it exists in the
* session. Return -2 on error or -1 if no window index is specified. This is
* used when parsing an argument for a window target that may not exist (for
* example if it is going to be created).
*/
int
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
{
struct session *s;
const char *winptr;
char *sessptr = NULL;
int idx, ambiguous = 0;
/*
* Find the current session. There must always be a current session, if
* it can't be found, report an error.
*/
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
return (-2);
}
/* A NULL argument means the current session and "no window" (-1). */
if (arg == NULL) {
if (sp != NULL)
*sp = s;
return (-1);
}
/* Time to look at the argument. If it is empty, that is an error. */
if (*arg == '\0')
goto not_found;
/* Find the separating colon. If none, assume the current session. */
winptr = strchr(arg, ':');
if (winptr == NULL)
goto no_colon;
winptr++; /* skip : */
sessptr = xstrdup(arg);
*strchr(sessptr, ':') = '\0';
/* Try to lookup the session if present. */
if (sessptr != NULL && *sessptr != '\0') {
if ((s = cmd_lookup_session(sessptr, &ambiguous)) == NULL)
goto no_session;
}
if (sp != NULL)
*sp = s;
/*
* Then work out the window. An empty string is a new window otherwise
* try to look it up in the session.
*/
if (*winptr == '\0')
idx = -1;
else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
ctx->error(ctx, "invalid index: %s", arg);
idx = -2;
}
if (sessptr != NULL)
xfree(sessptr);
return (idx);
no_colon:
/* No colon in the string, first try as a window then as a session. */
if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
goto no_session;
idx = -1;
}
if (sp != NULL)
*sp = s;
return (idx);
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
else
ctx->error(ctx, "session not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (-2);
not_found:
if (ambiguous)
ctx->error(ctx, "multiple windows: %s", arg);
else
ctx->error(ctx, "window not found: %s", arg);
if (sessptr != NULL)
xfree(sessptr);
return (-2);
}
/*
* Find the target session, window and pane number or report an error and
* return NULL. The pane number is separated from the session:window by a .,
* such as mysession:mywindow.0.
*/
struct winlink *
cmd_find_pane(struct cmd_ctx *ctx,
const char *arg, struct session **sp, struct window_pane **wpp)
{
struct session *s;
struct winlink *wl;
const char *period;
char *winptr, *paneptr;
const char *errstr;
u_int idx;
/* Get the current session. */
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
return (NULL); return (NULL);
}
if (sp != NULL) if (sp != NULL)
*sp = s; *sp = s;
/* A NULL argument means the current session, window and pane. */ if (idx == -1)
if (arg == NULL) {
*wpp = s->curw->window->active;
return (s->curw);
}
/* Look for a separating period. */
if ((period = strrchr(arg, '.')) == NULL)
goto no_period;
/* Pull out the window part and parse it. */
winptr = xstrdup(arg);
winptr[period - arg] = '\0';
if (*winptr == '\0')
wl = s->curw; wl = s->curw;
else if ((wl = cmd_find_window(ctx, winptr, sp)) == NULL) else
goto error; wl = winlink_find_by_index(&s->windows, idx);
if (wl == NULL)
/* Find the pane section and look it up. */ ctx->error(ctx, "window not found: %s:%d", s->name, idx);
paneptr = winptr + (period - arg) + 1;
if (*paneptr == '\0')
*wpp = wl->window->active;
else {
idx = strtonum(paneptr, 0, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "pane %s: %s", errstr, paneptr);
goto error;
}
*wpp = window_pane_at_index(wl->window, idx);
if (*wpp == NULL) {
ctx->error(ctx, "no such pane: %u", idx);
goto error;
}
}
xfree(winptr);
return (wl); return (wl);
no_period:
/* Try as a pane number alone. */
idx = strtonum(arg, 0, INT_MAX, &errstr);
if (errstr != NULL)
goto lookup_window;
/* Try index in the current session and window. */
if ((*wpp = window_pane_at_index(s->curw->window, idx)) == NULL)
goto lookup_window;
return (s->curw);
lookup_window:
/* Try as a window and use the active pane. */
if ((wl = cmd_find_window(ctx, arg, sp)) != NULL)
*wpp = wl->window->active;
return (wl);
error:
xfree(winptr);
return (NULL);
}
/* Replace the first %% or %idx in template by s. */
char *
cmd_template_replace(char *template, const char *s, int idx)
{
char ch;
char *buf, *ptr;
int replaced;
size_t len;
if (strstr(template, "%") == NULL)
return (xstrdup(template));
buf = xmalloc(1);
*buf = '\0';
len = 0;
replaced = 0;
ptr = template;
while (*ptr != '\0') {
switch (ch = *ptr++) {
case '%':
if (*ptr < '1' || *ptr > '9' || *ptr - '0' != idx) {
if (*ptr != '%' || replaced)
break;
replaced = 1;
}
ptr++;
len += strlen(s);
buf = xrealloc(buf, 1, len + 1);
strlcat(buf, s, len + 1);
continue;
}
buf = xrealloc(buf, 1, len + 2);
buf[len++] = ch;
buf[len] = '\0';
}
return (buf);
} }

View File

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

221
compat.h
View File

@@ -1,221 +0,0 @@
/* $Id: compat.h,v 1.17 2009-09-03 20:54:39 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HAVE_U_INT
typedef uint8_t u_int8_t;
typedef uint16_t u_int16_t;
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t;
#endif
#ifndef HAVE_PATHS_H
#define _PATH_BSHELL "/bin/sh"
#define _PATH_TMP "/tmp/"
#define _PATH_DEVNULL "/dev/null"
#define _PATH_TTY "/dev/tty"
#define _PATH_DEV "/dev/"
#endif
#ifdef HAVE_QUEUE_H
#include <sys/queue.h>
#else
#include "compat/queue.h"
#endif
#ifdef HAVE_TREE_H
#include <sys/tree.h>
#else
#include "compat/tree.h"
#endif
#ifdef HAVE_BITSTRING_H
#include <bitstring.h>
#else
#include "compat/bitstring.h"
#endif
#ifdef HAVE_POLL
#include <poll.h>
#else
#define POLLNVAL 0
#define POLLHUP 0
#include "compat/bsd-poll.h"
#endif
#ifdef HAVE_GETOPT
#include <getopt.h>
#endif
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_FORKPTY
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#endif
#ifdef HAVE_VIS
#include <vis.h>
#else
#include "compat/vis.h"
#endif
#ifndef HAVE_IMSG
#include "compat/imsg.h"
#endif
#ifdef HAVE_LOGIN_CAP
#include <login_cap.h>
#endif
#ifdef HAVE_BROKEN_CMSG_FIRSTHDR
/* Broken on OS X. */
#undef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(mhdr) \
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(mhdr)->msg_control : \
(struct cmsghdr *)NULL)
#endif
#ifndef INFTIM
#define INFTIM -1
#endif
#ifndef WAIT_ANY
#define WAIT_ANY -1
#endif
#ifndef SUN_LEN
#define SUN_LEN(sun) (sizeof (sun)->sun_path)
#endif
#ifndef __dead
#define __dead __attribute__ ((__noreturn__))
#endif
#ifndef __packed
#define __packed __attribute__ ((__packed__))
#endif
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#ifndef timeradd
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#endif
#ifndef PASS_MAX
#define PASS_MAX 128
#endif
#ifndef TTY_NAME_MAX
#define TTY_NAME_MAX 32
#endif
#ifndef _PW_BUF_LEN
#define _PW_BUF_LEN 1024
#endif
#ifndef HAVE_BZERO
#define bzero(buf, len) memset((buf), 0, (len));
#endif
#ifndef HAVE_STRCASESTR
/* strcasestr.c */
char *strcasestr(const char *, const char *);
#endif
#ifndef HAVE_STRSEP
/* strsep.c */
char *strsep(char **, const char *);
#endif
#ifndef HAVE_STRTONUM
/* strtonum.c */
long long strtonum(const char *, long long, long long, const char **);
#endif
#ifndef HAVE_STRLCPY
/* strlcpy.c */
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
/* strlcat.c */
size_t strlcat(char *, const char *, size_t);
#endif
#ifndef HAVE_DAEMON
/* daemon.c */
int daemon(int, int);
#endif
#ifndef HAVE_FORKPTY
/* forkpty.c */
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
#ifndef HAVE_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_GETOPT
/* getopt.c */
extern int BSDopterr;
extern int BSDoptind;
extern int BSDoptopt;
extern int BSDoptreset;
extern char *BSDoptarg;
int BSDgetopt(int, char *const *, const char *);
#define getopt(ac, av, o) BSDgetopt(ac, av, o)
#define opterr BSDopterr
#define optind BSDoptind
#define optopt BSDoptopt
#define optreset BSDoptreset
#define optarg BSDoptarg
#endif

View File

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

View File

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

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