Compare commits

...

908 commits
2.0 ... master

Author SHA1 Message Date
neil
ac919516f4 add DragonflyBSD by https://github.com/vmactions/dragonflybsd-vm 2022-08-06 21:30:02 -04:00
neil
6cb27ead4e fix NetBSD.yml 2022-08-06 21:30:02 -04:00
neil
15001bfa77 fix 2022-08-06 21:30:02 -04:00
neil
3efc8496cc fix Ubuntu.yml 2022-08-06 21:30:02 -04:00
neil
2ff8bc134d fix Ubuntu.yml 2022-08-06 21:30:02 -04:00
neil
9a1aa9ae9d add Ubuntu.yml 2022-08-06 21:30:02 -04:00
neil
17fcc8b76d fix MacOS.yml 2022-08-06 21:30:02 -04:00
neil
7c0bbf3e16 fix MacOS.yml 2022-08-06 21:30:02 -04:00
neil
05a849ba2b fix MacOS.yml 2022-08-06 21:30:02 -04:00
neil
fde4b58228 add MacOS.yml 2022-08-06 21:30:02 -04:00
neil
17d4a8a7df fix OpenBSD.yml 2022-08-06 21:30:02 -04:00
neil
ef11a7b30e fix OpenBSD.yml 2022-08-06 21:30:02 -04:00
neil
577e04df6c fix 2022-08-06 21:30:02 -04:00
neil
b1079b4393 add OpenBSD build by https://github.com/vmactions/openbsd-vm 2022-08-06 21:30:02 -04:00
neil
a258907cf8 add NetBSD test by https://github.com/vmactions/netbsd-vm 2022-08-06 21:30:02 -04:00
neil
169eb64b99 Add FreeBSD build by https://github.com/vmactions/freebsd-vm 2022-08-06 21:30:02 -04:00
Max Schmitt
be4a88507e chore: add FUNDING.yml 2022-03-05 23:28:29 -05:00
n0vember
c9ec7af632 add basic information for -a option in man page and help text 2021-03-21 15:39:14 -04:00
Sergio de Almeida Cipriano Junior
808b564564 Update manpage 2021-03-21 15:38:58 -04:00
Sergio de Almeida Cipriano Junior
e5ce3f04d2 Fix typo in ssh client 2021-03-21 15:38:58 -04:00
hpcbjdic
8123fa34f8 enable redefinition of TMUX_CONF
Without the added #ifndef / #endif it's not possible to _actually_ redefine TMUX_CONF by means of the compiler flag -DTMUX_CONF=... as done by the build system.
The same patch has also been applied to tmux, cf. master at https://github.com/tmux/tmux/blob/master/tmux.h.
2021-03-21 13:45:58 -04:00
Björn Jacke
f6a4ae6042 client: set IPTOS_LOWDELAY on TCP connection
this helps edge routers to prioritize our interactive network traffic.
2021-02-20 17:12:25 -05:00
Nicolas Viennot
cbec43f56d Better debugging when keys are not matching 2020-04-14 18:22:04 -04:00
Klemens Nanni
339e6c4357 Include <errno.h> for global errno
At least on OpenBSD the symbol `errno` is otherwise not defined;  it is
used in the `SSO()` macro and `send_authorized_keys()` function.
2020-04-12 15:17:50 -04:00
Nicolas Viennot
9e3e39d66d Avoid initializing stdout twice
Closes #190
2020-03-11 11:30:33 -04:00
Damian Szymański
ba6ac3a363 Update paths in build_static_release script (#178) 2019-12-06 06:43:04 -05:00
Nicolas Viennot
46564a0311
Merge pull request #177 from travis-ci/master
Add build on s390x and ppc64le
2019-12-04 20:32:22 -05:00
Damian Szymański
cc01f3f13a
Add build on s390x and ppc64le 2019-11-29 14:08:06 +01:00
Nicolas Viennot
f0a4707ef3 Update dockerfile for size 2019-11-28 16:35:48 -05:00
Nicolas Viennot
5e00bfa5e1 Rephrase 2019-11-16 17:09:38 -05:00
Nicolas Viennot
f895fe01b1 Rename account-key -> api-key 2019-11-10 22:27:23 -05:00
Nicolas Viennot
9fe8b32293 Add foreground tip 2019-11-10 16:40:36 -05:00
Nicolas Viennot
7e02dba7ef Minor refactor 2019-11-10 16:40:36 -05:00
Nicolas Viennot
bfa3c104d7 Refactor static builds 2019-11-10 16:12:12 -05:00
Nicolas Viennot
e5f6e68fad Unify tmate-debug.c with tmate-ssh-server 2019-11-10 16:12:12 -05:00
Nicolas Viennot
9fc6e96444 Send uname 2019-11-10 16:12:12 -05:00
Nicolas Viennot
86ec8d1ad6 Better crash messages 2019-11-10 03:59:12 -05:00
Nicolas Viennot
2b86031308 Fix keepalive bug 2019-11-10 03:58:59 -05:00
Nicolas Viennot
2b14611544 Polish session messages 2019-11-07 13:45:10 -05:00
Nicolas Viennot
d3c8808b0f Version bump 2019-11-07 11:38:54 -05:00
Nicolas Viennot
8b62c54748 Fix typo 2019-11-07 11:29:28 -05:00
Nicolas Viennot
ba860b8f45 Cleanup warnings 2019-11-07 10:14:03 -05:00
Nicolas Viennot
1600a81e58 Also add crash info on SIGABRT 2019-11-07 10:14:03 -05:00
Nicolas Viennot
0272757aa5 Clarify user message 2019-11-07 10:13:45 -05:00
Nicolas Viennot
9781946a70 Show initial message in copy mode 2019-11-05 21:39:16 -05:00
Nicolas Viennot
442143cd90 Show message when restarting shell 2019-11-05 21:39:16 -05:00
Nicolas Viennot
c71307ed5c Fix reconnection hanging bugs 2019-11-05 20:30:49 -05:00
Nicolas Viennot
fa49dc980d Provide a better CLI help (-h) 2019-11-05 20:30:49 -05:00
Nicolas Viennot
206c0f38b4 Set boot options via tmux commands 2019-11-05 20:30:40 -05:00
Nicolas Viennot
19341bc544 Add authorized_keys option -a 2019-11-05 20:30:11 -05:00
Nicolas Viennot
c78198dc59 Add command line arguments to set the account_key/session_names
-k account_key -n session_name -r session_name_ro
2019-11-04 18:36:10 -05:00
Nicolas Viennot
c63c8fbf90 Only use tmate.conf, not .tmux.conf
Fixes #108
2019-11-04 18:36:10 -05:00
Nicolas Viennot
6e84bab68c Add foreground mode with -F 2019-11-04 18:36:10 -05:00
Nicolas Viennot
7f693a97ae Add options for customizing session names (WIP) 2019-10-21 02:36:52 -04:00
Nicolas Viennot
4efe25d91d During SSH authentication, try the none auth method first 2019-10-15 03:11:26 -04:00
Nicolas Viennot
7262aead73 Bump to version 2.3.1 2019-10-12 21:10:03 -04:00
Nicolas Viennot
7153958e99 Allow the use of C.UTF-8 locale 2019-10-12 21:10:03 -04:00
Nicolas Viennot
74ff522983 Build static build releases on travis-ci 2019-10-12 20:38:36 -04:00
Nicolas Viennot
44635e752d Use docker to build static releases
Static builds are possible with the musl C library.
glibc is capricious when it comes to static linking and DNS support (and
other things).
2019-10-12 13:50:27 -04:00
Nicolas Viennot
d654ff2219 Send TMATE_READY message when the config files are done loading
This fixes bug where webhooks are not registering correctly, leading to
a disconnect and reconnect.
2019-09-18 23:35:07 -04:00
Nicolas Viennot
3e5d919b14 Bump to version 2.3.0 2019-07-31 21:02:18 -04:00
Andreas Schneider
4e7caeb536 ssh-client: Use ssh_get_server_publickey() if possible 2019-07-30 09:57:28 -04:00
Andreas Schneider
e25ab3cc8b ssh-client: Add missing ecdsa keytypes of libssh 0.9 2019-07-30 09:39:25 -04:00
Christian Hesse
299c7c670c add new channel after authentication
With libssh commit 8a885f0b ("channels: Add check if we are authenticated
before we create a channel") connection fails if channel is added before
successful authentication. So add the channel after authentication.

Fixes #154
2019-07-30 09:38:02 -04:00
Andreas Schneider
fd4ac27d59 ssh-client: Don't use keys from the ssh-agent
Fixes #138

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-04-09 08:15:07 -04:00
Nicolas Viennot
32d48cbc9d Update ed25519 server key (not yet in production) 2019-04-07 10:30:41 -04:00
Andreas Schneider
b01c6ecebd configure: Require libssh >= 0.8.4
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-04-07 10:30:41 -04:00
Andreas Schneider
b645ce15cb ssh-client: Add support for ed25519 keys
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-04-07 10:30:41 -04:00
Andreas Schneider
2ffcbbd185 ssh-client: Use SHA256 finger prints
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2019-04-07 10:30:41 -04:00
Nicolas Viennot
72ddb7eb08
Merge pull request #139 from teancom/update-man
Update MAN page to properly reference tmate where applicable
2018-12-01 12:28:52 -05:00
David Bishop
25f6a934cf Update MAN page to properly reference tmate where applicable
While there are still plenty of places where tmate uses tmux, including
config files and environment variables, I have updated the various
examples to use tmate where applicable.
2018-10-23 17:39:10 -06:00
Natanael Copa
3f6c6d4447 Fix building with or without backtrace(3)
backtrace(3) and execinfo.h are GNU extensions and may or may not be
available, and they may be provided via libexecinfo.

Fix detection of libexecinfo and allow building without any support of
backtrace, in which case we let kernel create core dump.

Fixes #116 #117
2017-09-28 08:56:41 -04:00
Nicolas Viennot
608763a41a Attempt to fix environment related crash
Fixes #89
2016-06-14 17:08:58 -04:00
Nicolas Viennot
b27f3bacc0 Crash fix in search prev/next match
Fixes #87
2016-06-10 18:00:50 -04:00
Nicolas Viennot
27169b7c07 Add missing incldues for FreeBSD 2016-06-05 12:54:25 -04:00
Nicolas Viennot
fe81322cc4 Keep alive the socket to make reconnections work properly 2016-04-21 16:20:27 -04:00
Nicolas Viennot
d433fe6956 nits 2016-03-29 01:42:07 -04:00
Nicolas Viennot
e840ff7582 Version Bump 2016-03-28 23:30:07 -04:00
Nicolas Viennot
c9813a8c42 Provide better reconnection error message 2016-03-28 23:30:07 -04:00
Nicolas Viennot
46a29037d4 strip static builds
Fixes #79
2016-03-28 23:30:07 -04:00
Nicolas Viennot
d41b06dea2 sync tmate-protocol.h 2016-03-28 16:28:11 -04:00
Nicolas Viennot
71d31e60e6 Be less strict over msgpack message size 2016-03-28 16:27:09 -04:00
Nicolas Viennot
02694d2a96 Send commands with their arguments in an array 2016-03-28 02:18:09 -04:00
Nicolas Viennot
c88870b0a3 Revert "Escape sent commands"
This reverts commit 37c71cfe15.
2016-03-28 01:22:48 -04:00
Nicolas Viennot
78305a7077 Cleanup socket 2016-03-27 13:09:04 -04:00
Nicolas Viennot
1ade196fb2 Default tmate messages to 15s 2016-03-27 13:09:04 -04:00
Nicolas Viennot
9b5bb8390c better error message 2016-03-27 02:29:43 -04:00
Nicolas Viennot
b88f66192f Merge remote-tracking branch 'tmux/master' 2016-03-27 02:15:29 -04:00
Nicolas Viennot
37c71cfe15 Escape sent commands 2016-03-27 02:06:56 -04:00
Nicolas Viennot
474487c33e Replay commands 2016-03-27 01:10:23 -04:00
Nicolas Viennot
a7c5507464 snapshot 2016-03-27 00:30:20 -04:00
Nicolas Viennot
cdfb6d7ef1 Reconnect wip 2016-03-26 19:00:16 -04:00
Nicholas Marriott
5658b628b9 Look for utempter_add_record to be sure we have the new utempter API, the old
utempter API was also using utempter.h.
2016-03-26 20:17:17 +00:00
Nicholas Marriott
b429a00cce Add to TODO. 2016-03-20 08:14:14 +00:00
Thomas Adam
410ccce4a3 Merge branch 'obsd-master' 2016-03-18 16:01:15 +00:00
nicm
312a7a1e62 Make scrolling behaviour more sensible and maintain cursor position, as
if the same had been done line-by-line. From Michal Mazurek.
2016-03-18 14:27:24 +00:00
Thomas Adam
ed598e9fe1 Merge branch 'obsd-master' 2016-03-18 08:01:18 +00:00
nicm
fa97b0a95b Instead of reusing MouseUp at the finish of a drag, add a new key
MouseDragEnd. It can be useful to bind them separately in copy mode.
2016-03-18 07:28:27 +00:00
Nicholas Marriott
3dfc79fb09 Tweak a comment. 2016-03-17 15:11:40 +00:00
Nicolas Viennot
cc20e826e0 Add webhook options 2016-03-11 14:11:48 -05:00
Nicolas Viennot
9742aeaf9b Send a ready packet when initialization is done 2016-03-11 14:11:28 -05:00
Nicolas Viennot
0d4aaa6def Fix compile warning 2016-03-11 13:28:49 -05:00
Nicolas Viennot
87794a3adb Merge remote-tracking branch 'tmux/master' 2016-03-11 13:26:22 -05:00
Thomas Adam
5fc5c03dad Merge branch 'obsd-master'
Conflicts:
	tmux.c
2016-03-05 17:58:12 +00:00
nicm
0d6de44a37 If setlocale("en_US.UTF-8") succeeds, then don't do the check for UTF-8
locale since if it isn't UTF-8 the system is broken anyway. If it fails,
try "" and check for UTF-8 with nl_langinfo(CODESET) rather than
wcwidth(). Based on a diff from schwarze@, nl_langinfo also suggested by
stsp@.
2016-03-05 16:08:38 +00:00
Thomas Adam
81f78f0da7 Merge branch 'obsd-master' 2016-03-05 10:01:09 +00:00
nicm
c38e0a4bbc Do not use c->cwd or s->cwd if it is NULL, found by Ben Boeckel. 2016-03-05 07:47:52 +00:00
nicm
1f0b317088 Although we always have en_US.UTF-8 on OpenBSD, some platforms do not,
so fall back to setlocale(LC_CTYPE, ""). tmux requires a UTF-8 locale,
so check with wcwidth() on a UTF-8 character after setlocale().
2016-03-05 07:44:31 +00:00
Thomas Adam
6c35d17800 Merge branch 'obsd-master' 2016-03-03 16:01:11 +00:00
nicm
df0983af39 show-* and set-* need to handle a missing target. 2016-03-03 14:15:22 +00:00
nicm
fa81d838da Accept clients as sessions in cmd_find_get_session. 2016-03-03 14:14:46 +00:00
Thomas Adam
45d62482da Merge branch 'obsd-master' 2016-03-03 14:01:10 +00:00
nicm
bcb41a09b3 RGB colours shouldn't be mixed up with aixterm colours, return before
that happens when working out if they are supported.
2016-03-03 12:58:15 +00:00
Nicholas Marriott
9e2fbb31ec +wchar.h 2016-03-02 18:19:13 +00:00
Nicholas Marriott
985504ff2c Merge branch 'next' 2016-03-02 18:16:51 +00:00
Thomas Adam
e304673c65 Merge branch 'obsd-master'
Conflicts:
	utf8.c
2016-03-02 18:10:51 +00:00
nicm
b8a102d26f Handle wcwidth() and mbtowc() failures in better style and drop
characters where we can't find the width (wcwidth() fails) on input, the
same as we drop invalid UTF-8. Suggested by schwarze@.
2016-03-02 15:36:02 +00:00
nicm
d980d965dd Limit x, y and b to 0x7ff for UTF-8 mouse input, suggested by schwarze@. 2016-03-02 15:33:36 +00:00
nicm
f0239a8fe9 Remove some more unused variables, and use RB_FOREACH_SAFE in
key_bindings_unref_table.
2016-03-01 12:06:07 +00:00
nicm
2e4503ad4e Redraw status on mode entry and exit. 2016-03-01 12:05:15 +00:00
nicm
54ea8f74ae When a mouse drag is finished, fire a MouseUp key press, instead of
doing the drag end in code. From Stephen Coakley.
2016-03-01 12:04:43 +00:00
nicm
e647eeb0c9 Remove unused variables, from Michal Mazurek. 2016-03-01 12:02:54 +00:00
nicm
26945d7956 Use system wcwidth() instead of carrying around UTF-8 width tables. 2016-03-01 12:02:08 +00:00
nicm
c7851e0ee7 Fix break-pane synopsis and some other tmux.1 bits. 2016-03-01 11:58:45 +00:00
Nicholas Marriott
a011b67f56 Remove unused variables. 2016-02-19 16:45:35 +00:00
Nicholas Marriott
c3f93e7178 Add to TODO. 2016-02-19 16:45:15 +00:00
Nicholas Marriott
931b1c6d59 Merge branch 'master' into next 2016-02-19 13:37:18 +00:00
Nicholas Marriott
e9d369a09e Fixed fgetln(3) implementation (from Joerg Jung) which does not depend on *BSD
fgets(3) semantics.
2016-02-19 13:35:46 +00:00
Nicholas Marriott
6adf561507 Redraw status on mode entry and exit. 2016-02-19 13:29:59 +00:00
Nicholas Marriott
95adc0e6ba When a mouse drag is finished, fire a MouseUp key press, instead of doing the
drag end in code. From Stephen Coakley.
2016-02-19 13:28:03 +00:00
Nicholas Marriott
02753ba9ea Remove unused variables, from Michal Mazurek. 2016-02-19 13:15:22 +00:00
Nicholas Marriott
acc1090e77 Use system wcwidth() instead of carrying around UTF-8 width tables. 2016-02-19 13:14:17 +00:00
Nicholas Marriott
fc864529f5 Remove malloc_options debug bit (already gone from OpenBSD). 2016-02-19 13:11:10 +00:00
Nicholas Marriott
782dd941da Fire SIGCHLD after utempter_add_record since it probably eats it. 2016-02-17 23:21:58 +00:00
Thomas Adam
ba8290aeae Merge branch 'obsd-master' 2016-02-12 14:01:14 +00:00
nicm
4f6bc0a0a9 Expand client formats in run-shell. 2016-02-12 12:24:52 +00:00
Thomas Adam
f7c8f1ae29 xmalloc: define __bounded__ where necessary 2016-02-07 00:04:46 +00:00
Thomas Adam
ba97ae1737 EXTRA_DIST: add example_tmux.conf / xmalloc.h 2016-02-06 19:04:21 +00:00
Thomas Adam
7669cfb330 Merge branch 'obsd-master' 2016-02-05 12:01:10 +00:00
nicm
bc0c9c7920 Do not wrap cursor at start or end of history, from Michal Mazurek. 2016-02-05 10:20:06 +00:00
Nicholas Marriott
07c23ccc05 Merge branch 'master' of github.com:tmux/tmux 2016-02-05 10:08:55 +00:00
Nicholas Marriott
2130a07b70 Add to TODO. 2016-02-05 10:08:39 +00:00
Thomas Adam
26f899be10 Merge branch 'obsd-master' 2016-02-04 16:01:13 +00:00
nicm
bdb8bb790e Set up -t flag properly when passing new-session -A off to
attach-session, GitHub issue 295.
2016-02-04 14:11:20 +00:00
Thomas Adam
8760f877e1 Merge branch 'obsd-master' 2016-01-31 16:01:09 +00:00
nicm
97882f9ce2 Clear RGB flags during selection. 2016-01-31 14:11:49 +00:00
Thomas Adam
5fce21728e Merge branch 'obsd-master' 2016-01-31 12:01:09 +00:00
nicm
fa64b89ad7 Whoops, need this for the previous reverse trim commit too. 2016-01-31 09:57:41 +00:00
nicm
49e9f93738 Add RGB escape sequences for capture-pane -e. 2016-01-31 09:57:09 +00:00
nicm
8028560f82 Support negative trim values (#{=-10:pane_title}) to trim from the end,
suggested by Kevin Brubeck Unhammer.
2016-01-31 09:54:46 +00:00
nicm
225a384dbb Fix new-session with -t after command flags changes, reported by Michael Graczyk. 2016-01-31 09:52:01 +00:00
Nicholas Marriott
404379049a examples/ has gone, so delete some text about it. 2016-01-29 15:45:32 +00:00
Nicholas Marriott
2a1bb91bf7 Remove old examples in favour of one example configuration file. 2016-01-29 14:53:28 +00:00
Nicholas Marriott
a33bb3e876 Link to the bash(1) completion file from README rather than including it in
examples.
2016-01-29 14:40:30 +00:00
Thomas Adam
8cf1504ba6 Merge branch 'obsd-master' 2016-01-29 12:01:16 +00:00
nicm
427b820426 Support for RGB colour, using the extended cell mechanism to avoid
wasting unnecessary space. The 'Tc' flag must be set in the external
TERM entry (using terminal-overrides or a custom terminfo entry), if not
tmux will map to the closest of the 256 or 16 colour palettes.

Mostly from Suraj N Kurapati, based on a diff originally by someone else.
2016-01-29 11:13:56 +00:00
Nicholas Marriott
1d6bd50343 libevent.org URL. 2016-01-29 10:58:08 +00:00
Nicolas Viennot
405cd82a82 Don't abort on unknown messages 2016-01-23 01:07:25 -05:00
Nicolas Viennot
64e14eaff5 Avoid crashes when the ssh connction dies
We might want to deal with reconnections soon
2016-01-23 00:52:35 -05:00
Nicholas Marriott
ca29dc9abc Update my email address. 2016-01-19 18:07:25 +00:00
Thomas Adam
dc42c35f1f Merge branch 'obsd-master' 2016-01-19 18:01:15 +00:00
nicm
b5b5221c13 Split out getting the current state from the target search so it can be
replaced if we already know the current.
2016-01-19 16:01:30 +00:00
nicm
995af0e2b7 I no longer use my SourceForge address so replace it. 2016-01-19 15:59:12 +00:00
Thomas Adam
5d21faa99c Merge branch 'obsd-master' 2016-01-16 02:01:10 +00:00
nicm
c9815307eb Add hooks for alerts (bell, silence, activity), from Thomas Adam. 2016-01-16 00:36:53 +00:00
Nicolas Viennot
c1846177fc Cleanup hacks around ev_ssh.ev_flags
Fixes #69

Fix suggested by Leon M. George <leon@georgemail.eu>
2016-01-15 16:03:57 -05:00
Thomas Adam
506adf3764 Merge branch 'obsd-master' 2016-01-15 12:01:11 +00:00
nicm
d551ab8e5c Clear the environment properly by looping until it is empty rather than
looping over it (which may skip entries), from Brad King.
2016-01-15 11:33:41 +00:00
nicm
68d797587e A couple of missing printflike attributes, from Andrey Starodubtsev. 2016-01-15 11:31:47 +00:00
Nicolas Viennot
6dc58ab6de Lower the required glib version to 2.8 for static builds 2016-01-11 02:54:09 -08:00
Nicolas Viennot
a2520da195 Fix static compilation (libc should be dynamically linked) 2016-01-10 14:17:06 -08:00
Nicolas Viennot
3a73f17354 Allow static linking 2016-01-09 22:00:28 -05:00
Nicolas Viennot
a397be388c Simplify find_window_pane() code 2016-01-05 17:52:15 -05:00
Thomas Adam
ea9873e60e Merge branch 'obsd-master' 2016-01-02 18:01:12 +00:00
nicm
cfb78654c2 clock-mode needs CMD_PANE. 2016-01-02 17:16:25 +00:00
Nicolas Viennot
0a3bd83b19 Use a session termination message 2016-01-02 11:03:04 -05:00
Nicolas Viennot
924eb01299 nits 2016-01-02 10:04:29 -05:00
Nicolas Viennot
81022ee8c7 Only use IPv4/IPv6 when we can use them 2016-01-02 09:45:34 -05:00
Nicolas Viennot
a87d3af309 Reusing protocol code from tmate-slave 2016-01-01 17:02:23 -05:00
Nicolas Viennot
a60da0db1e Merge remote-tracking branch 'tmux/master' 2016-01-01 14:18:07 -05:00
Thomas Adam
051cf5437a Merge branch 'obsd-master' 2016-01-01 10:01:11 +00:00
nicm
311be04d61 Don't rely on a calculation wrapping when applying message-limit, and
break out of the loop early. From Nicolas Viennot.
2016-01-01 08:04:20 +00:00
Nicolas Viennot
aef7470418 Fix status message 2015-12-31 19:55:12 -05:00
Nicolas Viennot
2e0d82648f Fix message log appends
The following has been improved:
1) Previous code had "u_int first" which is incorrect as
   "first = c->message_next - limit" would result in negative values,
   resulting in dropping the first limit messages.
2) Avoid to traverse the entire list of message to prune messages.
2015-12-31 19:53:22 -05:00
Nicolas Viennot
4c5522f7fa ssh key passphrase fix 2015-12-31 19:52:19 -05:00
Nicolas Viennot
55e6a774a8 improve err msg 2015-12-31 19:52:19 -05:00
Nicolas Viennot
fc46660c96 make sure ssh passphrase doesn't get synced 2015-12-31 19:52:19 -05:00
Nicolas Viennot
058906c242 nits 2015-12-31 19:52:19 -05:00
Nicolas Viennot
e61d3aa18f Fix pipe buffer offset 2015-12-31 19:52:19 -05:00
Thomas Adam
5e59c301b7 Merge branch 'obsd-master' 2015-12-31 20:01:09 +00:00
nicm
7e67db79dc Remove an extra unzoom call which was probably a merge error. 2015-12-31 18:34:47 +00:00
nicm
f84d32ca5e Use saved pipe buffer offset when writing to pipe, from Nicolas Viennot. 2015-12-31 18:14:13 +00:00
Nicolas Viennot
5ee65eec5d Remove comments 2015-12-31 12:28:26 -05:00
Nicolas Viennot
d5bd2e40f0 Default to 500 messages (we care about them) 2015-12-31 12:27:14 -05:00
Nicolas Viennot
66e4f554c3 Layout fixes 2015-12-31 11:35:36 -05:00
Nicolas Viennot
a104b160b2 Receive raw tmux keycodes 2015-12-30 16:04:06 -05:00
Nicolas Viennot
862182df4a sync emacs/vi mode 2015-12-29 21:30:33 -05:00
Thomas Adam
5dd0e82809 Merge branch 'obsd-master' 2015-12-28 16:01:09 +00:00
nicm
2a1f27eb1a Couple of trivial style nits. 2015-12-28 14:02:52 +00:00
Nicolas Viennot
d721b42306 missing AC_DEFINE(IS_LINUX) 2015-12-27 23:31:58 -05:00
Nicholas Marriott
e15a8a7c46 Keith Smiley is going to maintain the vim syntax file. 2015-12-24 16:59:12 +00:00
Nicolas Viennot
49f07dca50 fix options 2015-12-23 23:19:55 -05:00
Nicolas Viennot
76ab267a35 fix options 2015-12-23 23:19:03 -05:00
Nicolas Viennot
75cb217c22 Early tmate init for the key bindings 2015-12-23 23:18:35 -05:00
Nicolas Viennot
2680e4fa04 master.tmate.io -> ssh.tmate.io 2015-12-23 23:17:35 -05:00
Nicolas Viennot
1b4ab580f3 early SIGSEGV 2015-12-23 23:04:56 -05:00
Nicolas Viennot
42ac90ca49 log file rename 2015-12-23 22:58:22 -05:00
Nicolas Viennot
c04755361c randomize the socket name
(single session for now)
2015-12-23 22:56:29 -05:00
Nicolas Viennot
47340d3203 Make sure tmate can't nest when ran under an older tmux 2015-12-23 22:41:41 -05:00
Nicolas Viennot
16e1b82cb8 fix options scope 2015-12-23 05:58:09 -05:00
Nicolas Viennot
834fbfed0a change log files prefix tmux- to tmate- 2015-12-23 05:57:43 -05:00
Nicolas Viennot
9b2778c439 Merge with latest tmux 2015-12-23 05:46:44 -05:00
Nicolas Viennot
f0d60cb1c8 update libssh/msgpack APIs 2015-12-23 04:37:06 -05:00
Nicolas Viennot
1670d15e8a detect libssh/msgpack during ./configure 2015-12-23 04:36:57 -05:00
Alexander Bergmann
915b3a0255 Remove libssh and msgpack package forks and use system libraries. 2015-12-23 04:36:48 -05:00
Thomas Adam
ed65535c41 Merge branch 'obsd-master' 2015-12-23 02:01:14 +00:00
nicm
60cbdf9ccd Repair switch-client -l and switch-client with a window target. 2015-12-23 00:12:57 +00:00
Thomas Adam
5083e93957 Merge branch 'obsd-master' 2015-12-21 10:01:08 +00:00
nicm
f2ec911b8a Detach the right session with -d. 2015-12-21 09:20:13 +00:00
Nicholas Marriott
c83d6ee0b1 Merge branch 'master' of github.com:tmux/tmux 2015-12-20 11:26:12 +00:00
Nicholas Marriott
83c96d2685 No need to set cwd on Cygwin now, from Yuya Adachi. 2015-12-20 11:25:13 +00:00
Thomas Adam
58b3d66229 Merge branch 'obsd-master' 2015-12-19 10:01:08 +00:00
nicm
bdbec099cc Make input off flag (selectp -d) apply to synchronize-panes too. 2015-12-19 08:43:04 +00:00
Thomas Adam
2ad9caad3f Merge branch 'obsd-master' 2015-12-18 00:01:08 +00:00
nicm
a337403868 As well as setting up the state, actually use it in cmd_find_target. 2015-12-17 23:08:22 +00:00
Thomas Adam
e0cae08c04 Merge branch 'obsd-master' 2015-12-17 00:01:08 +00:00
nicm
99e9a4c786 send-keys -R should reset the input parser to ground state (so it can be
used to escape from, for example, printf '\033]2;').
2015-12-16 22:05:35 +00:00
Thomas Adam
7c94dae702 Merge branch 'obsd-master' 2015-12-16 22:01:08 +00:00
nicm
021c64310d Add infrastructure to work out the best target given a pane or window
alone and use it to add pane_died and pane_exited hooks.
2015-12-16 21:50:37 +00:00
nicm
8eb1a7d5dc showenv and setenv need to be CANFAIL. 2015-12-16 21:47:00 +00:00
Thomas Adam
f7a6482e6b Merge branch 'obsd-master' 2015-12-15 16:01:12 +00:00
nicm
909b737289 Copy state directly rather than dereferencing wl (which could be NULL). 2015-12-15 14:32:55 +00:00
Thomas Adam
e5caf64815 Merge branch 'obsd-master' 2015-12-15 14:01:12 +00:00
nicm
ac9778395f Some hooks API changes to fire a hook while waiting another cmdq and
infrastructure that will be needed soon.
2015-12-15 13:43:07 +00:00
Thomas Adam
1a33ea9671 Merge branch 'obsd-master' 2015-12-15 02:01:14 +00:00
nicm
9d88d82d5e Allow list-keys and list-commands to be run without a running server. 2015-12-15 00:52:17 +00:00
nicm
6f417ec943 We changed somewhat recently to us the pty when tmux was run inside
itself to work out the current pane. This is confusing in many cases
(particularly notable is that "tmux neww\; splitw" would not split the
new window), and the few advantages do not make up for the confusion.

So drop this behaviour and return to using the current window and pane;
keep the pty check but only use it to limit the list of possible current
sessions.
2015-12-15 00:45:02 +00:00
nicm
56d097cfe0 Don't copy marked pane when can just point to it. 2015-12-15 00:11:24 +00:00
Thomas Adam
6ab17e3e15 Merge branch 'obsd-master' 2015-12-15 00:01:08 +00:00
nicm
12da13c9d1 Make the marked pane a cmd_find_state. 2015-12-15 00:00:01 +00:00
nicm
d5999f8b5c Use cmd_find_clear_state instead of an extra function doing the same. 2015-12-14 23:30:58 +00:00
Thomas Adam
bc6137f9e4 Merge branch 'obsd-master' 2015-12-14 01:30:15 +00:00
nicm
a585a1b81a Remove some stray debug code. 2015-12-14 00:32:19 +00:00
nicm
a3129fd4e8 Instead of combined flags for -c, -s, -t, split into different sets
using an enum and simplify the parsing code.
2015-12-14 00:31:54 +00:00
Thomas Adam
5caec3020d Merge branch 'obsd-master' 2015-12-13 23:46:58 +00:00
Thomas Adam
f4adcfa0e2 Merge branch 'obsd-master' 2015-12-13 22:01:08 +00:00
nicm
ecfeee2e82 Use member names in cmd_entry definitions so I stop getting confused
about the order.
2015-12-13 21:53:57 +00:00
nicm
899bee0056 Actually I thought cmd_get_state_client was unnecessary but it will be
needed.
2015-12-13 21:17:37 +00:00
Thomas Adam
00da99f2c4 Merge branch 'obsd-master' 2015-12-13 20:01:09 +00:00
nicm
72948d9f1d -c needs to be able for fail for display-message. 2015-12-13 18:31:47 +00:00
nicm
66d1193a00 Remove an unnecessary function. 2015-12-13 18:27:47 +00:00
nicm
fd47084224 show-options and environment need CANFAIL flag. 2015-12-13 18:15:13 +00:00
Thomas Adam
d37a580085 Merge branch 'obsd-master' 2015-12-13 18:01:11 +00:00
nicm
50f8ead4e6 Don't log an error when doing the first check for move-window. 2015-12-13 17:58:26 +00:00
nicm
9f5aca62a9 Use struct cmd_find_state directly and remove cmd_state_flag, also
change so that winlink is set even if an index is too.
2015-12-13 17:55:14 +00:00
nicm
9b7697db62 Change cmd_find_target to use a state struct from the caller. 2015-12-13 16:44:35 +00:00
nicm
208e2dad1e If command returns error, report it. 2015-12-13 16:11:42 +00:00
Thomas Adam
ae5ddfdc1a Merge branch 'obsd-master' 2015-12-13 16:01:13 +00:00
nicm
ff599f4004 Remove the cmd_find_{session,window,pane,index} functions (which are
just wrappers around cmd_find_target) and just use cmd_find_target
directly.
2015-12-13 15:32:12 +00:00
nicm
9d191a6093 Move logging into cmd_find_target rather than each function. 2015-12-13 15:00:37 +00:00
nicm
4a4daf1303 Instead of every command resolving the target (-t or -s) itself, prepare
the state (client, session, winlink, pane) for it it before entering the
command. Each command provides some flags that tell the prepare step
what it is expecting.

This is a requirement for having hooks on commands (for example, if you
hook "select-window -t1:2", the hook command should to operate on window
1:2 not whatever it thinks is the current window), and should allow some
other target improvements.

The old cmd_find_* functions remain for the moment but that layer will
be dropped later.

Joint work with Thomas Adam.
2015-12-13 14:32:38 +00:00
Nicholas Marriott
92f187d1c2 Need to use pkg-config --static when doing a static build. 2015-12-12 22:04:25 +00:00
Thomas Adam
845a664bb2 Merge branch 'obsd-master' 2015-12-12 20:01:15 +00:00
nicm
5ed17e84fa Add key-table option to set the default key table for a session, allows
different key bindings for different sessions and a few other things.
2015-12-12 18:32:24 +00:00
nicm
6a50cf89b4 Return after changing key table. 2015-12-12 18:28:47 +00:00
nicm
39cf9c9d31 Allow prefix and prefix2 to be set to None to disable (useful if you
would rather bind the prefix in the root table).
2015-12-12 18:19:00 +00:00
Nicholas Marriott
5a5db02b85 Merge branch 'master' of github.com:tmux/tmux 2015-12-11 19:59:08 +00:00
Nicholas Marriott
38cc1a1843 Look for ncurses with PKG_CONFIG, and remove libtinfo because it just causes
confusion.
2015-12-11 19:58:41 +00:00
Thomas Adam
2a6b215328 Merge branch 'obsd-master' 2015-12-11 18:01:11 +00:00
nicm
88bc8f3528 Style nits and line wrapping of function declarations. 2015-12-11 16:37:21 +00:00
nicm
f2be3ad46f Mention {src,dst}-{window,pane} where we define target-{window,pane}. 2015-12-11 16:27:01 +00:00
Thomas Adam
2a3456cd3b Merge branch 'obsd-master' 2015-12-11 16:01:16 +00:00
nicm
bd5918760e We cannot do hooks_find and then hooks_remove because it might have come
from the parent (global) tree, instead make it remove by name like options.

While here, also tidy up a few bits of options and hooks handling (use
RB_FOREACH_SAFE, and a helper function for the free).
2015-12-11 15:46:57 +00:00
Thomas Adam
4909a70174 Merge branch 'obsd-master' 2015-12-11 13:24:45 +00:00
nicm
d7e11d0af7 Check alerts when session changes, from Patrick Palka. 2015-12-11 12:39:47 +00:00
nicm
01831da5f5 Add cmdq as an argument to format_create and add a format for the
command name (will also be used for more later).
2015-12-11 12:27:36 +00:00
Thomas Adam
af8134a6ff Merge branch 'obsd-master' 2015-12-08 10:01:16 +00:00
Nicholas Marriott
a988c36ccb Add to .mailmap, and sort. 2015-12-08 08:46:06 +00:00
nicm
e0f26dcda3 Remove format_create_flags and just pass flags to format_create. 2015-12-08 08:34:18 +00:00
nicm
8f671d3eef Spacing nits. 2015-12-08 08:14:04 +00:00
Thomas Adam
3182728b70 Merge branch 'obsd-master' 2015-12-08 07:12:13 +00:00
Thomas Adam
5862f59ed7 Conflicts:
Makefile
2015-12-08 07:11:09 +00:00
jmc
1f94274b92 Ed was meant to be El; 2015-12-08 06:42:07 +00:00
nicm
d2fb0efcd1 Add hooks infrastructure, basic commands (set-hook, show-hooks) and a
couple of not very useful client hooks. This will eventually let
commands be run at various points and on notifications. Joint work with
Thomas Adam.
2015-12-08 01:10:31 +00:00
mmcc
dbfce2a4d8 Use ^= instead of a verbose alternative. ok nicm@ 2015-12-08 00:51:17 +00:00
Nicholas Marriott
98994a8bb1 termios(4) 2015-12-08 00:49:10 +00:00
Nicholas Marriott
b580a55191 pty(7) -> pty(4) 2015-12-08 00:48:22 +00:00
Nicholas Marriott
ff16836d1d pty is in section 4 2015-12-08 00:47:27 +00:00
Nicholas Marriott
5411033f66 Update tmux.vim from Teubel Gyorgy. 2015-12-07 12:54:34 +00:00
Nicholas Marriott
8383409e88 Merge branch 'master' of github.com:tmux/tmux 2015-12-07 12:51:20 +00:00
Nicholas Marriott
d20a3ef57c Update .mailmap file. 2015-12-07 12:51:06 +00:00
Thomas Adam
bac8c72381 Merge branch 'obsd-master' 2015-12-07 10:01:09 +00:00
nicm
b9563340b7 Fix bell indicators across detach, reported by Torbjorn Lonnemark, diff
from Thomas Adam.
2015-12-07 09:47:41 +00:00
Thomas Adam
8ae9329aa8 Merge branch 'obsd-master' 2015-12-05 14:01:09 +00:00
claudio
0417f1f2be EAGAIN handling for imsg_read. OK henning@ benno@ 2015-12-05 13:18:24 +00:00
Nicholas Marriott
4d5cab4085 Merge branch 'master' of github.com:tmux/tmux 2015-12-03 14:43:33 +00:00
Nicholas Marriott
3cdb2f0bb7 Add to TODO. 2015-12-03 14:43:24 +00:00
Thomas Adam
66bad2e979 Merge branch 'obsd-master' 2015-12-03 00:01:08 +00:00
nicm
7236838dea Mark new active pane changed after pane lost in window, and after
break-pane. Reported by tim@.
2015-12-02 23:09:22 +00:00
Thomas Adam
eb5ee80c74 Merge branch 'obsd-master' 2015-12-01 10:01:13 +00:00
nicm
a785a7f700 Do not deref wp if window_get_active_at returns NULL which can happen on
very large terminals, from Michael Graczyk.
2015-12-01 09:41:03 +00:00
Thomas Adam
742976893e Merge branch 'obsd-master' 2015-11-29 18:01:08 +00:00
guenther
1d331c7e62 Delete a duplicated line
ok jmc@
2015-11-29 17:06:59 +00:00
Thomas Adam
9fe8b28746 Merge branch 'obsd-master' 2015-11-27 15:41:28 +00:00
nicm
6a2ca34216 Do not set a limit on the length of commands when printing them. 2015-11-27 15:06:43 +00:00
Nicholas Marriott
3b83bda29c Add to TODO. 2015-11-25 23:35:24 +00:00
Thomas Adam
a1bc339340 log_open() isn't conditional on proctitle 2015-11-25 16:51:17 +00:00
Thomas Adam
260de2cb5e Remove logfile() 2015-11-25 16:48:47 +00:00
Thomas Adam
890d8da2e3 Merge branch 'obsd-master'
Conflicts:
	log.c
	proc.c
	tmux.c
2015-11-25 16:37:30 +00:00
nicm
ac8678aefe Don't print error if none to print. 2015-11-25 07:58:55 +00:00
nicm
62d3af17f9 Make environ_set va_args and use it to tidy up some calls. Also add a
missing word in manpage (from jmc).
2015-11-24 23:46:15 +00:00
nicm
3ff46b2e43 Shell command from -c doesn't have to be global, pass it as an argument. 2015-11-24 23:22:51 +00:00
nicm
dca93c56e0 Do lock failures slightly better, return a special value so we don't
unlink the wrong thing.
2015-11-24 23:01:51 +00:00
nicm
73e30cbda8 Actually show something (even if it not that helpful) if the server
fails to start (for example if it can't create the socket), rather than
hanging or showing nothing.
2015-11-24 22:45:44 +00:00
nicm
c18fbefe93 Document socket_path format. 2015-11-24 22:27:59 +00:00
nicm
c913fb99b6 Tidy the code that works out the socket path, and just use the full path
in the global socket_path rather than copying it.
2015-11-24 22:27:22 +00:00
nicm
8976dac9e0 Remove malloc_options DEBUG bit. 2015-11-24 22:09:53 +00:00
nicm
bef217b241 Switch a fprintf to a fatal, and wrap some long lines. 2015-11-24 22:04:36 +00:00
nicm
1e2df2d464 Remove the -I part of show-messages which isn't really that useful; the
server start time can now be accessed with a new start_time format (use:
tmux display -p '#{t:start_time}')
2015-11-24 21:52:06 +00:00
nicm
9fd3318dd8 All kill-session -C to clear alerts in all windows, suggested by Aaron
U'Ren.
2015-11-24 21:50:06 +00:00
nicm
4e3015a892 Log some system and libevent information at startup. 2015-11-24 21:32:36 +00:00
nicm
bdbbd9711c Show libevent version in showmsgs -I. 2015-11-24 21:23:44 +00:00
nicm
9cccb8c115 Make the log stuff a bit tidier with some helper functions. 2015-11-24 21:19:46 +00:00
nicm
4ec61bef46 Fix usage of detach-client. 2015-11-24 20:40:51 +00:00
Nicholas Marriott
0a2ef2b932 Merge branch 'master' of github.com:tmux/tmux 2015-11-24 18:50:24 +00:00
Nicholas Marriott
7b085136a7 -sys/queue.h in proc.c, and nuke the unnecessary C++ header guards stuff and
sys/cdefs.h in vis.h (it causes problems on some platforms). Reported by
someone on GitHub, issue 212.
2015-11-24 18:48:07 +00:00
Thomas Adam
534f9e3ab1 Merge branch 'obsd-master' 2015-11-24 10:01:13 +00:00
nicm
b32ce34cf2 Don't allow options in table without scope set. 2015-11-24 09:34:55 +00:00
Thomas Adam
3f47ff6ecd Merge branch 'obsd-master' 2015-11-24 00:01:16 +00:00
nicm
2adf3f42ee Partly revert previous, it is harmless to keep support for UTF-8 mouse
mode inside tmux, just no longer support it for tmux itself.
2015-11-23 23:47:57 +00:00
Thomas Adam
b642b3c8e3 Merge branch 'obsd-master' 2015-11-23 21:21:12 +00:00
Thomas Adam
d63de1e407 Merge branch 'obsd-master'
Conflicts:
	server.c
	tmux.c
2015-11-23 21:20:54 +00:00
nicm
32e510bd70 Remove support for the UTF-8 mouse extension. This was a briefly used,
poor idea that was fairly quickly replaced by SGR mouse input (which is
now widespread). It is impossible to tell the difference between UTF-8
and non-UTF-8 mouse input; since the mouse-utf8 option was removed tmux
has not handled it correctly in any case; and it is ridiculous to have
three different forms of mouse input.
2015-11-23 20:53:09 +00:00
nicm
28e72ae34d Don't leak extddata, memset after freeing it, not before. From Patrick
Palka.
2015-11-22 19:42:57 +00:00
nicm
01a2ddf3f8 Add getpw to pledge, makes tmux work in YP environments, discovered by
matthieu, ok deraadt
2015-11-22 19:41:19 +00:00
tim
4fcc02ee9d If display-time is set to 0, show status messages until a key is pressed;
OK nicm@
2015-11-22 18:28:01 +00:00
Thomas Adam
78a00c845c Merge branch 'obsd-master'
Conflicts:
	tmux.h
2015-11-21 14:24:33 +00:00
Nicholas Marriott
2c482939fd Move tmux.h below system includes. 2015-11-21 08:03:18 +00:00
nicm
933929cd62 Memory leaks and an uninitialized part of utf8_data, from Patrick Palka. 2015-11-20 22:02:54 +00:00
nicm
40fefe2cbc The alerts callback should be fired for bells even if bell-action is
none because it also affects the status line bell indicator (and
bell-action does not). Fixes a problem reported by tim@.
2015-11-20 16:33:46 +00:00
nicm
fce56c56ef Instead of separate tables for different types of options, give each
option a scope type (server, session, window) in one table.
2015-11-20 12:01:19 +00:00
nicm
374e273df5 Only assume pasting with at least two characters, reduces problems for
people who can type ^B c very fast, or who are using tmux inside
something else that buffers.
2015-11-19 22:46:46 +00:00
Thomas Adam
cf688db4b5 Merge branch 'obsd-master' 2015-11-19 16:01:12 +00:00
nicm
98967c5ec9 The activity flag could already be set, so queue the callback always (if
not already queued) rather than only if the flag is being added. Fixes a
problem reported by tim@
2015-11-19 14:55:25 +00:00
Thomas Adam
45b4e337cb Merge branch 'obsd-master' 2015-11-18 18:01:13 +00:00
nicm
82760a9960 Use format_expand_time for display-message. 2015-11-18 16:49:13 +00:00
Nicholas Marriott
c15487318b unused -> __unused. 2015-11-18 16:45:44 +00:00
Nicholas Marriott
a58eaec540 Merge branch 'master' of github.com:tmux/tmux 2015-11-18 16:42:25 +00:00
Thomas Adam
7fe8edc396 Merge branch 'obsd-master' 2015-11-18 16:01:23 +00:00
Nicholas Marriott
8b4b3ff4fc Add __unused, will be needed shortly. 2015-11-18 14:37:08 +00:00
nicm
577c0e3e5a Use __unused rather than rolling our own. 2015-11-18 14:27:44 +00:00
nicm
5a5b950e8b Add s/foo/bar/: prefix for formats to substitute bar for foo. 2015-11-18 14:13:55 +00:00
Nicholas Marriott
f8a1f8843c Add -Wno-attributes. 2015-11-18 14:10:48 +00:00
Nicholas Marriott
9bba26f8c5 Add reallocarray prototype. 2015-11-18 14:09:17 +00:00
Thomas Adam
8fa822b521 Merge branch 'obsd-master' 2015-11-18 14:01:12 +00:00
nicm
64571368dc Sync the entire xmalloc.[ch] with the other users, but with the addition
of xrealloc, xvasprintf, xvsnprintf.
2015-11-18 13:06:54 +00:00
Nicholas Marriott
93742ed5df Merge branch 'master' of github.com:tmux/tmux 2015-11-18 12:55:22 +00:00
Nicholas Marriott
a77960c540 Add reallocarray to compat. 2015-11-18 12:54:29 +00:00
Thomas Adam
4b703d3049 Merge branch 'obsd-master' 2015-11-18 10:01:11 +00:00
nicm
ca5e6bf5f2 Don't update activity time twice for new sessions, and add some logging. 2015-11-18 09:22:29 +00:00
Thomas Adam
44cad8f4ed Merge branch 'obsd-master' 2015-11-17 20:01:12 +00:00
tobias
d0505fd042 Merge xmalloc.[ch] files across base, skipping OpenSSH for now.
ok nicm
2015-11-17 18:25:03 +00:00
Thomas Adam
349a62ed4f Merge branch 'obsd-master' 2015-11-17 00:01:09 +00:00
nicm
775fb562bd 0x7f is a valid key. 2015-11-16 22:57:51 +00:00
Thomas Adam
1686a15fb6 Merge branch 'obsd-master' 2015-11-16 00:01:10 +00:00
nicm
661d0dfac9 Make key_code unsigned long long not uint64_t which is more portable for
printf formats, and move UTF8_SIZE define down to near the rest of the
UTF-8 bits.
2015-11-15 22:50:38 +00:00
Thomas Adam
8213558cc7 Merge branch 'obsd-master'
Conflicts:
	server.c
	tmux.c
2015-11-15 22:49:25 +00:00
nicm
a582b62287 Accidentally turned off pledge, turn it back on. 2015-11-15 14:32:48 +00:00
Thomas Adam
bb820fa761 Merge branch 'obsd-master' 2015-11-14 14:01:08 +00:00
nicm
14d90e4901 The character is an int so use %x not %hhx. 2015-11-14 12:20:19 +00:00
nicm
3db0d50df4 The private use area at U+E000 to U+F8FF is not very useful if it is
width 0, make it width 1 instead.
2015-11-14 12:03:23 +00:00
Thomas Adam
f12d7f0d4b Merge branch 'obsd-master' 2015-11-14 12:01:09 +00:00
nicm
205d15e82d All these return values from utf8_* are confusing, use an enum. 2015-11-14 11:45:43 +00:00
Thomas Adam
7b4b78b419 Merge branch 'obsd-master' 2015-11-14 11:38:52 +00:00
Thomas Adam
7b749eff35 Merge branch 'obsd-master'
Conflicts:
	server.c
	tmux.c
2015-11-14 11:38:30 +00:00
nicm
f401791a56 Rename a variable in utf8_combine for consistency and use 0xfffd for
unknown Unicode.
2015-11-14 11:13:44 +00:00
nicm
dab63b029e Couple of assignments to remove compiler warnings. 2015-11-14 10:57:59 +00:00
nicm
64333e3ef8 Be more strict about invalid UTF-8. 2015-11-14 10:56:31 +00:00
nicm
c56b81a2ce Push stdout and stderr to clients more aggressively, and add an event to
continue if the send fails.
2015-11-14 09:41:06 +00:00
Nicholas Marriott
23266e8e09 Merge branch 'master' of github.com:tmux/tmux 2015-11-14 09:04:41 +00:00
Nicholas Marriott
31d880f751 Update the TODO file. 2015-11-14 09:04:13 +00:00
nicm
908e6bb68f Log more of UTF-8 input. 2015-11-14 08:25:12 +00:00
Thomas Adam
276ca5f04c Merge branch 'obsd-master' 2015-11-13 18:01:13 +00:00
nicm
c4893d8efd Log option names in fatal() for missing option. 2015-11-13 16:06:43 +00:00
Nicholas Marriott
1016f112bf Merge branch 'master' of github.com:tmux/tmux 2015-11-13 16:06:11 +00:00
Nicholas Marriott
b7397bf413 utf8 option is gone. 2015-11-13 16:05:58 +00:00
Thomas Adam
45a10dde95 Merge branch 'obsd-master' 2015-11-13 14:01:10 +00:00
nicm
88aa1c8dc3 Two spacing and spelling nits. 2015-11-13 12:18:52 +00:00
Thomas Adam
e2917b2627 Merge branch 'obsd-master' 2015-11-13 10:43:07 +00:00
Thomas Adam
3df4959f51 Merge branch 'obsd-master'
Conflicts:
	Makefile
2015-11-13 10:42:45 +00:00
nicm
531869bd92 Add window_visible_layout which ignores zoomed panes and use it for
control mode (which needs to know all panes), from George Nachman.
2015-11-13 10:00:26 +00:00
nicm
c5689a5a40 Long overdue change to the way we store cells in the grid: now, instead
of storing a full grid_cell with UTF-8 data and everything, store a new
type grid_cell_entry. This can either be the cell itself (for ASCII
cells), or an offset into an extended array (per line) for UTF-8
data.

This avoid a large (8 byte) overhead on non-UTF-8 cells (by far the
majority for most users) without the complexity of the shadow array we
had before. Grid memory without any UTF-8 is about half.

The disadvantage that cells can no longer be modified in place and need
to be copied out of the grid and back but it turned out to be lot less
complicated than I expected.
2015-11-13 08:09:28 +00:00
Thomas Adam
a7027ed8e5 Merge branch 'obsd-master' 2015-11-13 00:01:15 +00:00
nicm
e71a915412 Rename overly-long utf8data to ud throughout. 2015-11-12 22:04:37 +00:00
Thomas Adam
b2f19c9d06 Merge branch 'obsd-master' 2015-11-12 16:01:09 +00:00
nicm
f2d03f4fdd grid_put_utf8 is unused, remove it. 2015-11-12 14:50:57 +00:00
Thomas Adam
4f88344df3 Merge branch 'obsd-master' 2015-11-12 14:01:14 +00:00
nicm
a209ea3953 Add utf8_padcstr and use it to align columns in list-keys. 2015-11-12 12:43:36 +00:00
jmc
1da7475d0e tweak previous; ok nicm 2015-11-12 12:36:34 +00:00
nicm
d6daf37df4 Tidy utf8.c a little: build table on first use, and make utf8_width take
a u_int rather than splitting and then combining again in utf8_split.
2015-11-12 12:19:57 +00:00
Thomas Adam
5f483499f3 Merge branch 'obsd-master' 2015-11-12 12:01:17 +00:00
nicm
0cc812ae34 tmux is UTF-8, so if $TMUX is set (tmux running in tmux), the client is
UTF-8. Also try to make the existing checks more readable.
2015-11-12 11:24:08 +00:00
nicm
c41673f3fa If we know the terminal outside tmux is not UTF-8, replace UTF-8 in
error messages and whatnot with underscores the same as we do when we
draw UTF-8 characters as part of the screen.
2015-11-12 11:10:50 +00:00
nicm
1b86f520ea Nuke the utf8 and status-utf8 options and make tmux only a UTF-8
terminal. We still support non-UTF-8 terminals outside tmux, but inside
it is always UTF-8 (as when the utf8 and status-utf8 options were on).
2015-11-12 11:09:11 +00:00
nicm
a0f3999ce7 Remove the mouse_utf8_flag format as well. 2015-11-12 11:07:10 +00:00
nicm
69e0b8326a Support UTF-8 key bindings by expanding the key type from int to
uint64_t and converting UTF-8 to Unicode on input and the reverse on
output. (This allows key bindings, there are still omissions - the
largest being that the various prompts do not accept UTF-8.)
2015-11-12 11:05:34 +00:00
Thomas Adam
333da3b64b Merge branch 'obsd-master' 2015-11-12 10:01:09 +00:00
nicm
7062b0e65d Default history-file should be "" not NULL, from Greg Onufe. 2015-11-12 08:19:18 +00:00
Thomas Adam
f2e4aa8d1c Merge branch 'obsd-master' 2015-11-12 00:01:10 +00:00
nicm
00c34df186 Drop mouse-utf8 option and always turn on UTF-8 mouse if the client says
it supports UTF-8.
2015-11-11 23:23:33 +00:00
Thomas Adam
35fd6d134a Merge branch 'obsd-master'
Conflicts:
	utf8.c
2015-11-11 08:14:36 +00:00
nicm
6f3475c6c7 If realpath() fails just try the original path. 2015-11-10 22:33:47 +00:00
nicm
005e462e01 Handle absolute paths properly, and don't use resolved path in
realpath() fails.
2015-11-10 22:29:33 +00:00
nicm
dcdccf8333 Same bug as last commit, but in the other copy of the loop in this file... 2015-11-05 23:32:21 +00:00
schwarze
e9b58d9de4 Update the internal wcwidth(3) table of tmux(1) to match the data
in /usr/src/share/locale/ctype/en_US.UTF-8.src, with one single
exception:  Keep U+00AD SOFT HYPHEN at width 1 rather than moving
it to width 0, a tradition already observed in the old
https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c .
While here, manually rebalance the btree for optimal lookup speed.
OK nicm@
2015-11-05 16:44:25 +00:00
Thomas Adam
896581628d Merge branch 'obsd-master' 2015-11-05 12:01:08 +00:00
nicm
5577535891 Pass through right click if mouse is on, from Patrick Palka. 2015-11-05 11:05:30 +00:00
Thomas Adam
696826913c Merge branch 'obsd-master' 2015-11-03 16:01:11 +00:00
nicm
455284f1c0 Detach the client we are looping over, from Thomas Adam. 2015-11-03 15:07:36 +00:00
Thomas Adam
c975de2e07 Merge branch 'obsd-master'
Conflicts:
	server.c
2015-10-31 23:56:35 +00:00
nicm
ba7fb49fb9 Fall back silently to ~ or / rather than checking -c with access(), this
was the old behaviour.
2015-10-31 14:51:15 +00:00
nicm
b0a99e85b6 Don't shift version out of peerid, it is needed later. 2015-10-31 13:43:38 +00:00
nicm
abb4e9e2fa The output log is only useful once and it means creating a file, so open
it once at startup instead of in every call to tty_open.
2015-10-31 13:12:03 +00:00
Thomas Adam
17f6c3be8e Merge branch 'obsd-master' 2015-10-31 10:01:12 +00:00
nicm
01defc9f49 Because pledge(2) does not allow us to pass directory file descriptors
around, we can't use file descriptors for the working directory because
we will be unable to pass it to a privileged process to tell it where to
read or write files or spawn children. So move tmux back to using
strings for the current working directory. We try to check it exists
with access() when it is set but ultimately fall back to ~ if it fails
at time of use (or / if that fails too).
2015-10-31 08:13:58 +00:00
Thomas Adam
e8bb385d6d Merge branch 'obsd-master' 2015-10-29 10:01:09 +00:00
nicm
45f3cea263 Break version check into a separate function, and limit version to 8 bits. 2015-10-29 09:35:31 +00:00
Thomas Adam
a5e4d3a2d8 Merge branch 'obsd-master' 2015-10-28 12:01:11 +00:00
nicm
bf9c933cae Like options, move the environ struct into environ.c. 2015-10-28 09:51:55 +00:00
Thomas Adam
da1f6fc2c8 Merge branch 'obsd-master'
Conflicts:
	Makefile
	client.c
	server-client.c
	server.c
	tmux.c
	tmux.h
2015-10-27 23:27:26 +00:00
nicm
44657bf932 Move struct options into options.c. 2015-10-27 15:58:42 +00:00
nicm
67c3a014b9 No more TMPDIR. 2015-10-27 14:51:35 +00:00
nicm
07b0ea03c3 Break the common process set up, event loop and imsg dispatch code
between server and client out into a separate internal API. This will
make it easier to add another process.
2015-10-27 13:23:24 +00:00
Thomas Adam
147b5ae514 Merge branch 'obsd-master' 2015-10-27 10:01:13 +00:00
nicm
9952201ca7 Count brackets in #{?...} so that nested conditional formats work, from
Daniel De Graaf.
2015-10-27 09:28:31 +00:00
nicm
17c2c4219d The format callback may not always succeed, so we need to check for
NULL. From Patrick Palka.
2015-10-27 09:18:06 +00:00
nicm
3fc001d0a2 Use copy-mode -et= in WheelUpPane binding, from Patrick Palka. 2015-10-27 09:15:21 +00:00
Thomas Adam
9c69a79f9a Merge branch 'obsd-master' 2015-10-27 00:01:09 +00:00
nicm
640c6fdd5f If a mouse event has no key binding, pass it through to the pane it
happened in, not the active pane like normal key presses. Fixes problems
seen by Enrico Ghirardi.
2015-10-26 23:16:18 +00:00
nicm
380a1ea8ef Default bindings for mouse wheel on status line to change window (like
we had before), from Patrick Palka.
2015-10-26 23:06:18 +00:00
nicm
b85be36d1c Handle unknown keys more gracefully, return a string instead of NULL. 2015-10-26 22:03:04 +00:00
Thomas Adam
54a3ed751e Merge branch 'obsd-master' 2015-10-26 18:01:12 +00:00
nicm
a22fe33aa0 Some extra logging of where keys are actually going. 2015-10-26 17:17:06 +00:00
Thomas Adam
e95df0bc39 Merge branch 'obsd-master' 2015-10-26 02:01:09 +00:00
jmc
c582f7d177 space before punctuation; 2015-10-26 00:15:37 +00:00
Thomas Adam
ca29903c82 Merge branch 'obsd-master' 2015-10-26 00:01:10 +00:00
nicm
e65306d8e7 Extend the modifiers allowed before formats: as well as the existing
#{=10:...}  length limit, add #{t:...} to convert a time_t format to a
string, #{b:...} for basename and #{d:...} for dirname. Remove all the
foo_string time formats as they can now be replaced by "t:", for example
#{window_activity_string} becomes #{t:window_activity}.
2015-10-25 22:29:17 +00:00
Nicholas Marriott
c14fb5b633 -sys/types.h 2015-10-25 09:38:08 +00:00
Thomas Adam
ad437f13d5 Add missing headers for getpid() 2015-10-25 09:34:56 +00:00
Thomas Adam
4681415a15 Merge branch 'master' of github.com:tmux/tmux 2015-10-25 09:33:11 +00:00
Nicholas Marriott
7930cb54c0 ifdef __OpenBSD__ around pledge(). 2015-10-25 09:31:46 +00:00
Thomas Adam
91f53d590b __OpenBSD__ around pledge() 2015-10-25 09:31:07 +00:00
Thomas Adam
3e0d31c4e9 Merge branch 'obsd-master' 2015-10-25 09:22:20 +00:00
Thomas Adam
4acc8d0ff5 Merge branch 'obsd-master'
Conflicts:
	cmd-find.c
2015-10-25 09:21:37 +00:00
nicm
3faa51a0ca Pass output from jobs through format_expand() so they are expanded again
(this was the previous behaviour).
2015-10-25 08:59:26 +00:00
deraadt
3034a71488 Let's see if anyone screams about not being able to specify $TMPDIR
for their tmux sockets.

(Over the years, I have seen $TMPDIR set up worse than /tmp many times,
and don't know how this practice infected other parts of the system.
Nothing uses tmpdir(3), nor a huge-temporary-file program like sort.)
ok nicm
2015-10-25 07:48:16 +00:00
nicm
2e2b8a95bd Pasting mouse escape sequences is unlikely, so skip them when working
out whether the user is pasting.
2015-10-23 23:46:36 +00:00
nicm
26a55ddcf9 Remove some unnecessary checks before free(). 2015-10-23 16:30:15 +00:00
nicm
1a4ddfa8a7 If $TMUX is set, and we are unsure about the session, use it. 2015-10-23 16:29:07 +00:00
nicm
5383b047d1 tmux can call pledge() in main with large set and then reduce it
slightly in the server to "stdio rpath wpath cpath fattr unix recvfd
proc exec tty ps".
2015-10-23 16:07:29 +00:00
nicm
14da999408 Format for scroll position, from Jorge Morante. 2015-10-23 16:02:21 +00:00
nicm
63a3fd3c0f Use tty_term_flag not _has for XT, and make -2 force direct use of
256-colour escape sequences (so setaf/setab can be bypassed if needed).
2015-10-23 15:52:54 +00:00
Thomas Adam
8c39813665 Merge branch 'obsd-master' 2015-10-22 14:01:12 +01:00
nicm
3ebcf25149 If the pane is still on all_window_panes but not actually connected to
window or session (which can happen if it is killed during a command
sequence and something else has a reference), fall back to the best
effort. Fixes "tmux killw\; detach" for Rudis Muiznieks.
2015-10-22 11:23:00 +00:00
nicm
a05c27a7e1 Unzoom before -LRUD, reported by Andy Weidenbaum. 2015-10-22 11:19:31 +00:00
Thomas Adam
6bc3902f5d Merge branch 'obsd-master' 2015-10-22 12:01:09 +01:00
nicm
c2c2d44c72 Log identify messages. 2015-10-22 11:00:51 +00:00
nicm
515dfea4b7 This should not be changed. 2015-10-22 10:48:30 +00:00
nicm
31fd071faa Rename shutdown to exit. 2015-10-22 10:46:24 +00:00
Thomas Adam
0bfa615997 Merge branch 'obsd-master' 2015-10-21 16:01:08 +01:00
nicm
60ca29df64 client_key_table was missing. 2015-10-21 13:14:36 +00:00
Thomas Adam
35f582583a Merge branch 'obsd-master' 2015-10-21 14:01:09 +01:00
nicm
ddbc4a0f6c By popular demand add a default binding for mouse wheel up to scroll
into history (if the mouse is, on of course).
2015-10-21 11:13:47 +00:00
Thomas Adam
1f4a5b5dfe Merge branch 'obsd-master' 2015-10-21 00:01:19 +01:00
nicm
076034345a Use client pointer not file descriptor in logging. 2015-10-20 21:12:08 +00:00
Thomas Adam
af2d48f4d2 Merge branch 'obsd-master' 2015-10-20 16:01:11 +01:00
nicm
8c8cddbe02 The table could change when retrying so don't save it at start of
server_client_handle_key.
2015-10-20 14:19:27 +00:00
Thomas Adam
bbdc08780c Merge branch 'obsd-master' 2015-10-18 22:01:08 +01:00
nicm
174a2ad731 Pass current directory as a string rather than a file descriptor because
pledge doesn't let us pass directory file descriptors.
2015-10-18 20:42:42 +00:00
Thomas Adam
7c78b2b756 Start working on tmux 2.2 2015-10-18 18:19:08 +01:00
Thomas Adam
310f0a960c Update for 2.1 release. 2015-10-18 18:10:43 +01:00
Nicholas Marriott
6c3ade76df __OpenBSD__ around pledge(). 2015-10-17 20:16:12 +01:00
Thomas Adam
487285b325 Merge branch 'obsd-master' 2015-10-17 20:01:08 +01:00
nicm
9c601ebde8 Add pledge "stdio unix sendfd proc exec tty" to tmux client process,
"sendfd" is dropped after first message from the server.
2015-10-17 18:30:43 +00:00
Nicholas Marriott
0273d809d0 Merge branch 'master' of github.com:tmux/tmux 2015-10-17 18:48:45 +01:00
Nicholas Marriott
e0527d7731 time.h is not needed now tzset() is not in log.c. 2015-10-17 18:48:22 +01:00
Thomas Adam
a204595e4c Merge branch 'obsd-master' 2015-10-16 10:01:09 +01:00
nicm
cf89abb013 Don't free after calling paste_set but do after evbuffer_add, from Theo
Buehler.
2015-10-16 07:43:29 +00:00
Nicholas Marriott
c06c14fb29 Some header fixes. 2015-10-15 21:42:17 +01:00
Nicholas Marriott
716550021e Merge branch 'master' of github.com:tmux/tmux 2015-10-15 09:25:21 +01:00
Nicholas Marriott
f199fb6a2b Fix available_fds when there is no AF_INET, reported by Mathieu Arnold. 2015-10-15 09:24:25 +01:00
Thomas Adam
f69e09a67e Merge branch 'obsd-master' 2015-10-11 02:01:14 +01:00
guenther
241fd72f75 Userspace doesn't need to use SUN_LEN(): connect() and bind() must accept
sizeof(struct sockaddr_un), so do the simple, portable thing

ok beck@ deraadt@
2015-10-11 00:26:23 +00:00
Thomas Adam
5b13dafbab Merge branch 'obsd-master' 2015-10-07 12:01:21 +01:00
nicm
7340d5adfd Couple of memory leaks in error paths, from Frederik Vanderstraeten. 2015-10-07 09:52:58 +00:00
Thomas Adam
7120ab2f16 Merge branch 'obsd-master' 2015-09-26 02:01:16 +01:00
nicm
695a591f8e Adding colors=256 to *256color* was always pretty stupid and now it
won't work (without adding setaf@:setab@ too).
2015-09-25 23:30:24 +00:00
nicm
03d7dba5d8 If the terminal has colors=256, only try to use setaf/setab if they
exist, reported by Filipe Brandenburger.
2015-09-25 23:30:12 +00:00
Thomas Adam
20c3adca41 Merge branch 'obsd-master' 2015-09-25 18:01:09 +01:00
nicm
28f23f18e9 Free the history when it is cleared, based on a diff from Carlo Cannas. 2015-09-25 15:53:07 +00:00
Thomas Adam
b0372840e7 Merge branch 'obsd-master' 2015-09-24 14:01:10 +01:00
nicm
2a62917444 Don't leak fd and path on failure. 2015-09-24 12:06:20 +00:00
nicm
69ea6b9373 Do not leak log file descriptor. 2015-09-24 12:03:58 +00:00
Thomas Adam
ed17760a52 Merge branch 'obsd-master' 2015-09-24 10:01:09 +01:00
nicm
ddb2d1221b Assign flag not number for flag types (we got away with it so far
because that are a union). From Filipe Brandenburger.
2015-09-24 07:02:18 +00:00
Nicholas Marriott
06d4553a15 Merge branch 'master' of github.com:tmux/tmux 2015-09-23 14:27:11 +01:00
Nicholas Marriott
1caebaa49a Add to TODO. 2015-09-23 14:26:53 +01:00
Thomas Adam
7e9b87f396 Merge branch 'obsd-master' 2015-09-23 00:01:09 +01:00
nicm
dc66795e35 Don't update last session when the session is unchanged, from Sina Siadat. 2015-09-22 21:56:16 +00:00
Thomas Adam
d6d05883ad Merge branch 'obsd-master' 2015-09-21 12:01:11 +01:00
nicm
d5f223a3fe Reset the alerts timer always on activity, from Thomas Adam. 2015-09-21 09:34:52 +00:00
Thomas Adam
983357603a Merge branch 'obsd-master' 2015-09-18 12:01:07 +01:00
nicm
6b709e655e -l should apply to the new not the old pane with -b, from "MadMaverick9"
on GitHub.
2015-09-18 09:55:22 +00:00
Thomas Adam
c624382929 Merge branch 'obsd-master' 2015-09-17 16:01:08 +01:00
nicm
8b5d5dca9f Redraw both src and dst sessions in break-pane. 2015-09-17 14:11:55 +00:00
Thomas Adam
a3bce7a322 Merge branch 'obsd-master' 2015-09-17 00:01:08 +01:00
nicm
c1d0b6a6ee Log when cmdq_continue is called. 2015-09-16 22:41:00 +00:00
nicm
232a0ffc34 Give some variables less silly names. 2015-09-16 22:40:27 +00:00
nicm
ecb257f0ef A few minor style nits. 2015-09-16 22:40:05 +00:00
nicm
d1b73be6e1 Hoist some common code out of both branches of an if/else. 2015-09-16 22:29:30 +00:00
nicm
a4b4b29987 Rename cmd_q dead flag to a general flags bitmask (will be more flags later). 2015-09-16 22:24:54 +00:00
Nicholas Marriott
57ad1f6ddf Merge branch 'master' of github.com:tmux/tmux 2015-09-15 13:57:57 +01:00
Nicholas Marriott
54bd761286 Add BCE to TODO. 2015-09-15 13:57:46 +01:00
Thomas Adam
b5d789a531 Merge branch 'obsd-master' 2015-09-14 16:01:08 +01:00
Nicholas Marriott
166aa97f75 No more $Id$. 2015-09-14 15:59:21 +01:00
Thomas Adam
d47789620b Add missing <time.h> 2015-09-14 14:39:51 +01:00
nicm
16ee4de5df Remove some extra blank lines. 2015-09-14 13:22:02 +00:00
Thomas Adam
4afe26fa82 Merge branch 'obsd-master' 2015-09-14 14:01:09 +01:00
nicm
62bb6e37e0 Should add buffer if no -b. 2015-09-14 12:52:22 +00:00
nicm
216ddf3da5 Move tzset() from log_open to main. 2015-09-14 12:12:24 +00:00
nicm
8da6de3e66 Style nit, int for flags not u_int. 2015-09-14 11:57:22 +00:00
Thomas Adam
74b958ecbe Merge branch 'obsd-master'
Conflicts:
	Makefile
2015-09-14 12:42:19 +01:00
nicm
af16ce6ad9 When the active pane changes, redraw panes if the style has
changed. From Cam Hutchison.
2015-09-14 11:34:50 +00:00
nicm
16efa84838 Make refresh-client force update of jobs, from Sina Siadat. 2015-09-14 10:25:52 +00:00
nicm
901c2eb20a Add copy-mode -e to exit copy mode when scrolling off the bottom, useful
for quick view of history, from Cam Hutchison.
2015-09-13 13:31:40 +00:00
nicm
ede0f2f633 Set woken flag when flushing so that the channel is freed, while here
use the same loop construct for both loops.
2015-09-13 10:45:55 +00:00
nicm
a3de5dbab1 Merge delete-buffer into cmd-set-buffer.c and change the paste buffer
API so it has one paste_free() rather than free_top and free_name
(everywhere that uses it already has the right pointer).
2015-09-11 14:41:50 +00:00
Nicholas Marriott
ef35c9f765 Add --enable-coverage for gcov. 2015-09-11 13:16:35 +01:00
Nicholas Marriott
66c4ed98d6 Fix bad merge. 2015-09-10 14:59:16 +01:00
Nicholas Marriott
eb1084754c Merge branch 'master' of github.com:tmux/tmux 2015-09-10 12:42:25 +01:00
Nicholas Marriott
79e5b62907 osdep_event_init not event_init. 2015-09-10 12:41:49 +01:00
Thomas Adam
1fd756066c Merge branch 'obsd-master' 2015-09-10 12:01:08 +01:00
nicm
cfabe30bec Add session_last_attached time and format, from Sina Siadat. 2015-09-10 08:58:14 +00:00
Thomas Adam
5af2f68a2c Merge branch 'obsd-master' 2015-09-09 14:01:08 +01:00
nicm
67ee995cc1 No need to keep global options around for client which doesn't use them. 2015-09-09 12:09:21 +00:00
Thomas Adam
fe536457cc Fix includes
Let compat/ work out the includes; otherwise works on OpenBSD.
2015-09-06 21:29:36 +01:00
Thomas Adam
76688d2040 Merge branch 'obsd-master'
Conflicts:
	cfg.c
	tmux.c
2015-09-06 20:47:50 +01:00
nicm
aceae73b9a Change wait-for to work when the signal comes before the wait, also use
some helper functions and add some logging.
2015-09-04 12:02:44 +00:00
nicm
82326dcbe2 A couple of style nits. 2015-09-03 14:30:23 +00:00
nicm
6c10fc659a Log pane which received input data. 2015-09-02 17:52:57 +00:00
nicm
38e3baab2a A one line helper function is a little silly. 2015-09-02 17:43:25 +00:00
nicm
8121127606 We no longer need the terminal service class, so don't bother asking for it. 2015-09-02 17:37:54 +00:00
nicm
a45164f2e0 Fix indentation of grid_string_cells_fg. 2015-09-02 17:12:07 +00:00
Nicholas Marriott
2ebef95994 Sync up vis.* for stravis(). 2015-09-01 21:08:19 +01:00
nicm
93b946ee50 Tweak some error messages/comments. 2015-09-01 19:50:09 +00:00
nicm
66a2720c56 Log the whole new input buffer once rather than each byte. 2015-09-01 19:16:00 +00:00
nicm
364a885b0c Pass logging through vis(3). 2015-09-01 19:14:43 +00:00
nicm
fa3d4fab85 Fix a spelling error, sesson -> session. 2015-09-01 18:50:16 +00:00
nicm
69a2d46ee5 Remove dead_clients which is no longer used. 2015-09-01 11:13:39 +00:00
nicm
952ba84611 Work out config file when needed not at startup. 2015-09-01 10:10:59 +00:00
nicm
83157c02d6 Move initial conf load into cfg.c. 2015-09-01 10:01:56 +00:00
nicm
2a836bc306 All the cmd_*_entry declarations do not need to be in tmux.h. 2015-09-01 09:48:34 +00:00
Nicholas Marriott
2c6ea705fd Bring back pane_current_path. 2015-08-31 19:57:37 +01:00
nicm
6a539c00df Path from $TMUX does not need to be global anymore. 2015-08-30 22:56:36 +00:00
nicm
c6e9160c67 Login shell can be a client flag, and move the exec code into client.c. 2015-08-30 22:40:25 +00:00
nicm
dd92b6e83d Event base does not need to be global. 2015-08-30 22:19:07 +00:00
Thomas Adam
29f2120e5b Linux: get_proc_name() -> osdep_get_name() 2015-08-30 21:47:50 +01:00
Thomas Adam
cb89f2f2a1 Merge branch 'obsd-master'
Conflicts:
	Makefile
	format.c
2015-08-30 21:44:01 +01:00
nicm
b87dc608d9 Some style nits and dead assignments. 2015-08-30 15:43:40 +00:00
nicm
5047670693 Remove some old prototypes and unused functions. 2015-08-29 23:55:55 +00:00
nicm
52bbac506c struct args_entry can go into arguments.c. 2015-08-29 23:19:52 +00:00
nicm
373ef850e0 paste_send_pane can be merged into cmd-paste-buffer.c now. 2015-08-29 09:36:46 +00:00
nicm
b569585000 Move struct paste_buffer out of tmux.h. 2015-08-29 09:25:00 +00:00
nicm
b9f0571780 We already loop over the windows in server_client_loop, so don't do it
again in server_loop just to check names.
2015-08-29 08:54:41 +00:00
nicm
b5aaefc727 Move alerts onto events rather than checking every loop. 2015-08-29 08:30:54 +00:00
nicm
5267ce8ff4 Treat entering or leaving a mode as pane changed. 2015-08-29 00:39:18 +00:00
nicm
b7861f34ba Better take on reducing the name timer. Again check for name changes in
the main loop after events that may have changed the pane, but do so at
most once every 500 millis. If the pane changed too soon, use a timer to
ensure that a check happens later.
2015-08-29 00:29:15 +00:00
nicm
73bd816076 Microseconds in log time. 2015-08-29 00:24:44 +00:00
nicm
d9b3133321 Only set default title to hostname on screens that are being used for a
window pane, no point in calling gethostname() for temporary screens.
2015-08-28 17:11:12 +00:00
nicm
5f122af556 Make a few more expensive (ish) formats functions instead of inline. 2015-08-28 17:01:42 +00:00
nicm
983ebb2689 Allow formats to be specified as functions (in the code) so they are
only evaluated on demand rather than each time a format tree is
constructed. Use this for expensive formats like pane_current_command.
2015-08-28 16:46:40 +00:00
nicm
55b8d74561 Revert previous; we do need a timer, until I have a better idea. We
can't do the name check every loop, because that is too expensive, and
we can't make sure it only happens infrequently because we have no idea
when the next change will happen.
2015-08-28 16:10:46 +00:00
nicm
e2100c5f5f We now only checking for name changes when the active pane has changed,
but that can only happen when we have already been woken up by a read
event, so there is no need for a timer, we can just check the changed
flag on the end of that read event (we already loop over the windows to
check for bells etc anyway).
2015-08-28 15:51:48 +00:00
Thomas Adam
486421ceff Merge branch 'obsd-master' 2015-08-28 16:01:09 +01:00
nicm
b0940bdf54 Check changed flag after restarting timer. 2015-08-28 13:26:41 +00:00
nicm
f957db81d9 Remove unused prototypes. 2015-08-28 13:21:25 +00:00
nicm
ed2a486f46 Don't leak name when freeing session, from Kuang-che Wu. 2015-08-28 13:16:03 +00:00
nicm
f6a0f8730e Per-session timers for locking, and remove the global one-second timer. 2015-08-28 13:12:20 +00:00
Thomas Adam
84eabb2658 Merge branch 'obsd-master' 2015-08-28 14:01:11 +01:00
nicm
57cc4d45d5 Make session_update_activity more useful and use it in more places. 2015-08-28 13:01:03 +00:00
nicm
675def0396 Remove the lock-server option which is a bit redundant, it isn't that
different without it.
2015-08-28 12:31:55 +00:00
nicm
6419f66523 Give clock mode its own timer. 2015-08-28 12:25:42 +00:00
nicm
75d10058a4 Run status update on a per-client timer at status-interval. 2015-08-28 12:16:28 +00:00
nicm
18d4802a7b Log time with message. 2015-08-28 12:15:54 +00:00
nicm
b6618b631b Move format job cleanup onto its own timer. 2015-08-28 11:38:27 +00:00
Thomas Adam
31c027a37a Merge branch 'obsd-master' 2015-08-28 12:01:07 +01:00
nicm
ee9f708500 Allow environment variables in #{}. 2015-08-28 10:06:52 +00:00
Thomas Adam
031d7ce840 Merge branch 'obsd-master' 2015-08-28 10:01:08 +01:00
nicm
25faca41eb Error messages should not have a trailing period. 2015-08-28 07:55:43 +00:00
nicm
fc58e44f89 Only do the automatic-rename dance if the pane has changed (seen output,
or new active pane).
2015-08-28 07:49:24 +00:00
Thomas Adam
ce20572ace Merge branch 'obsd-master' 2015-08-25 18:01:07 +01:00
nicm
2ffbd5b5f0 When searching for tabs, start from screen width, fixes out-of-bounds
read found by Kuang-che Wu.
2015-08-25 15:00:05 +00:00
Thomas Adam
429f86397b Merge branch 'obsd-master' 2015-08-25 02:01:16 +01:00
nicm
3219e0314e In grid_duplicate_lines, if the line is empty (cellsize == 0) then clear
the destination celldata pointer rather than leaving a stale copy of the
source pointer (which may later be freed). Fixes a crash found by
Kuang-che Wu.
2015-08-24 22:49:13 +00:00
Nicolas Viennot
3be116bb6e -rdynamic only for gcc
Closes #56
2015-08-17 11:58:27 -04:00
Thomas Adam
65b45c9c32 Merge branch 'obsd-master' 2015-08-16 12:01:06 +01:00
nicm
58b659a26e Come out of copy mode when history is cleared. 2015-08-16 08:57:34 +00:00
Nicholas Marriott
f5357ed940 Handle \ at EOL from Daniel Hahler. 2015-08-15 09:53:19 +01:00
Thomas Adam
778612d152 Merge branch 'obsd-master' 2015-08-13 18:01:07 +01:00
nicm
46aa92420a right-up should be right-of, also rename the values too. 2015-08-13 15:02:23 +00:00
Thomas Adam
6447404cc2 Merge branch 'obsd-master' 2015-08-12 12:01:09 +01:00
nicm
13b7fd82c1 Rename left/right/up/down relative to active pane to add -of suffix
(left-of/right-of/etc) to remove conflict with left/right meaning
leftmost or rightmost pane. From Ben Boeckel.
2015-08-12 08:55:20 +00:00
Nicholas Marriott
3c9b8a28c6 Merge branch 'master' of github.com:tmux/tmux 2015-08-07 15:08:26 +01:00
Nicholas Marriott
736d8350e9 +history-file, from Ben Boeckel. 2015-08-07 15:06:17 +01:00
Thomas Adam
73b4d098ce Merge branch 'obsd-master' 2015-07-29 14:01:09 +01:00
nicm
5ec3621101 status_out and associated data structures are no longer used. 2015-07-29 11:56:02 +00:00
Thomas Adam
a568aaa0c0 Merge branch 'obsd-master' 2015-07-28 18:01:08 +01:00
nicm
b254115acd Tidy up the way terminals are described and move some structs out of tmux.h. 2015-07-28 15:18:10 +00:00
Thomas Adam
ff18787b2c Merge branch 'obsd-master' 2015-07-27 10:01:08 +01:00
nicm
d33adc4fd0 Make -q suppress ambiguous option warnings too, from Cam Hutchison. 2015-07-27 08:45:45 +00:00
Nicholas Marriott
e4cdc9fa0b Merge branch 'master' of github.com:tmux/tmux 2015-07-24 09:10:21 +01:00
Nicholas Marriott
669059aa19 Fix a warning, from Kosta Zertsekel. 2015-07-24 09:06:15 +01:00
Thomas Adam
18a64ad52d Merge branch 'obsd-master' 2015-07-20 18:01:10 +01:00
nicm
92af3766ec Add an option (history-file) for a file to save/restore command prompt
history, from Olof-Joachim Frahm.
2015-07-20 15:50:04 +00:00
Thomas Adam
dedd9edf7f Merge branch 'obsd-master' 2015-07-20 12:01:07 +01:00
nicm
d4ce210713 Correct the tsl/fsl sequence to ]0 not ]2 (from Marcel Korpel). While
here, Xr xterm and remove some advice about elinks that is better
elsewhere.
2015-07-20 10:34:11 +00:00
Nicholas Marriott
e6facdcb0c Merge branch 'master' of github.com:tmux/tmux 2015-07-19 08:10:07 +01:00
Nicholas Marriott
96dcbe217b Update tmux.vim from Ben Boeckel. 2015-07-19 08:07:55 +01:00
Thomas Adam
e45f42db29 Merge branch 'obsd-master' 2015-07-17 16:01:07 +01:00
nicm
bad8d0fd20 Do not call window_unzoom from window_destroy because it will try to add
a notification which will get confused because the reference count is
already zero and end up back in window_destroy and a double
free. Instead, just destroy the layouts directly. Noticed by Thomas
Adam.
2015-07-17 13:09:07 +00:00
Thomas Adam
b886393042 Merge branch 'obsd-master' 2015-07-17 10:01:09 +01:00
nicm
3192178f15 Initialize client fd to -1 as well, from Bobby Powers. 2015-07-17 06:53:47 +00:00
Nicholas Marriott
8c96e2a6d9 Implement osdep_get_name and osdep_get_cwd for AIX, from J Raynor. 2015-07-15 08:46:35 +01:00
Nicholas Marriott
5ffb869e1a Merge branch 'master' of github.com:tmux/tmux 2015-07-14 08:15:05 +01:00
Nicholas Marriott
bed3069fd7 Add _LINUX_SOURCE_COMPAT on AIX. 2015-07-14 08:14:35 +01:00
Thomas Adam
dcc28434f4 Merge branch 'obsd-master' 2015-07-13 20:01:08 +01:00
nicm
8dcea2cc14 Reset G0/G1 state when resetting everything else with send-keys -R. 2015-07-13 18:45:18 +00:00
nicm
4e637b1b61 Ignore environment variables that are too long to send to the server. 2015-07-13 18:10:26 +00:00
Thomas Adam
07aef38591 Merge branch 'obsd-master' 2015-07-13 18:01:09 +01:00
nicm
e45d624df2 Fix line endings. 2015-07-13 15:51:31 +00:00
nicm
c7374c31c4 Initialize cwd fd to -1 so that we don't close fd 0 if the client is
destroyed before it is changed. Also allow ttyname() to fail. Fixes
problems when running out of file descriptors reported by Bruno Sutic.
2015-07-13 15:49:31 +00:00
nicm
81069f66f9 Add a format to show if client is a control client. From Bruno Sutic. 2015-07-13 15:37:26 +00:00
Thomas Adam
38d4d69639 Merge branch 'obsd-master' 2015-07-13 16:01:09 +01:00
nicm
6308c48efd Add a -s flag to show-environment to output Bourne shell commands a la
ssh-agent. Mostly from Cam Hutchison with some changes by me.
2015-07-13 13:36:29 +00:00
nicm
cc768d77ec Revert to marking lines as wrapped on newlines, fixes problems with
capturep -J.
2015-07-13 13:28:50 +00:00
Nicholas Marriott
73f9f0334c Check for flock in libbsd for AIX, and remove some getopt.h includes. From J
Raynor.
2015-07-13 14:19:50 +01:00
Nicholas Marriott
28c33f67bc Merge branch 'master' of github.com:tmux/tmux 2015-07-12 19:47:47 +01:00
Nicholas Marriott
235e0bd65a Update imsg*.[ch] from OpenBSD, including bzero->memset. 2015-07-12 19:46:58 +01:00
Thomas Adam
9a0ce98c54 Merge branch 'obsd-master' 2015-07-06 16:01:10 +01:00
nicm
b298478435 Update environment with -E when attach-session used on an already
attached session or switch-client used on the current session. From Cam
Hutchison.
2015-07-06 14:24:57 +00:00
Thomas Adam
78723af99f README: Clarify SYNCING is under the ISC 2015-06-28 12:01:19 +01:00
Nicholas Marriott
8b8a007e8e Merge branch 'master' of github.com:tmux/tmux 2015-06-20 08:45:19 +01:00
Nicholas Marriott
8abcea18a2 Remove monitor-content options which have been removed, from Guy Hughes. 2015-06-20 08:43:55 +01:00
Thomas Adam
0ef3e28609 Merge branch 'obsd-master' 2015-06-19 02:01:10 +01:00
nicm
f557c7d8ca Use the SRCDST define for usage. 2015-06-18 23:56:01 +00:00
nicm
b43b13faf9 Use xsnprintf. 2015-06-18 23:55:24 +00:00
nicm
164ba041c9 Remove a stray : and tweak paragraph. 2015-06-18 23:53:56 +00:00
Thomas Adam
86018a3947 Merge branch 'obsd-master' 2015-06-17 22:01:13 +01:00
nicm
85120b37ea Change break-pane to take target and source panes (-t and -s) in line
with other commands, from Thomas Adam.
2015-06-17 19:56:08 +00:00
Thomas Adam
21a2ccc5f1 Merge branch 'obsd-master' 2015-06-17 20:01:12 +01:00
nicm
84f0622c85 Break cmdq_continue inner loop into a helper function. 2015-06-17 17:02:15 +00:00
Thomas Adam
a584e11d6b Merge branch 'obsd-master' 2015-06-17 18:01:07 +01:00
nicm
0ff335961e Move the shuffle code from new-window -a into a function and add a -a
flag for move-window too. From Thomas Adam.
2015-06-17 16:50:28 +00:00
nicm
021cdbe1c0 Use an explicit job state instead of avoid closing our side of the
socketpair and setting it to -1 to mark when the other side is
closed. This avoids closing it while the libevent bufferevent still has
it (it could try to add it to the polled set which some mechanisms don't
like). Fixes part a problem reported by Bruno Sutic.
2015-06-17 16:44:49 +00:00
Thomas Adam
9fdc3a069a Merge branch 'obsd-master' 2015-06-15 14:01:09 +01:00
nicm
d96ab34019 Add window_activity format, from Thomas Adam based on a diff originally
from propos6 at gmail dot com.
2015-06-15 10:58:01 +00:00
Thomas Adam
37005d04a9 Merge branch 'obsd-master' 2015-06-14 12:01:10 +01:00
nicm
29c29e7717 Add a format for client PID (client_pid) and server PID (pid). Diff for
client_pid from Thomas Adam.
2015-06-14 10:07:44 +00:00
Thomas Adam
48a46e066e Merge branch 'obsd-master' 2015-06-10 16:01:08 +01:00
Nicholas Marriott
ba665e24e3 Merge branch 'master' of github.com:tmux/tmux 2015-06-10 15:41:35 +01:00
Nicholas Marriott
dca084e703 Don't leak dotfd if fchdir fails. From ettl dot martin78 at gmail dot com. 2015-06-10 15:39:23 +01:00
nicm
bbc0898060 wp->tty is a char [] not a char * so it can't be NULL. From Thomas Adam. 2015-06-10 12:56:04 +00:00
Thomas Adam
0ff172fabf Merge branch 'obsd-master' 2015-06-09 10:01:10 +01:00
nicm
a412dd616f Fix loop comparison broken in last commit, from Thomas Adam. 2015-06-09 07:07:06 +00:00
Nicholas Marriott
02a848d77c It isn't supposed to... 2015-06-08 09:46:14 +01:00
Thomas Adam
7acc4addb5 Merge branch 'obsd-master'
Conflicts:
	client.c
	tmux.1
	tmux.c
2015-06-07 23:42:25 +01:00
nicm
c4e811e519 Add -E flag when attaching or switching client to bypass
update-environment, from Steven Lu.
2015-06-07 21:39:39 +00:00
Nicholas Marriott
a5c55e4393 Update TODO. 2015-06-07 08:36:03 +01:00
nicm
ed6c036ee3 Use ints for the calculations rather than u_char, they could end up
signed.
2015-06-05 22:50:27 +00:00
nicm
55b96a5bd5 Handle the RGB colour escape sequence (\033[38;2;<r>;<g>;<b>m and 48;2)
like xterm(1) does, by mapping to the nearest in the 256 colour palette.
2015-06-05 22:33:39 +00:00
nicm
1cb073d48e Use fixed colour tables rather than generated and do a quick search for
exact match before doing the distance comparison.
2015-06-05 22:01:17 +00:00
nicm
641a9cd3f5 Similarly, for sessions use a callback to free rather than checking
every loop.
2015-06-05 18:18:32 +00:00
nicm
10e90ae01f Change deref to the more sensible unref, and add a couple I missed before. 2015-06-05 18:06:30 +00:00
nicm
8c93b768e4 Instead of putting dead clients on a list and checking it every loop,
use event_once to queue a callback to deal with them. Also dead clients
with references would never actually be freed because the wrap-up
functions (the callback for stdin, or status_prompt_clear) would never
be called. So call them in server_client_lost.
2015-06-05 18:01:12 +00:00
nicm
b0782df8a6 Do not use the key variable uninitialized (in a debug log statement),
reported by jungleboogie0 at gmail dot com.
2015-06-05 15:10:13 +00:00
Nicholas Marriott
f7598b8a26 Only need *.ch in compat. 2015-06-05 12:44:15 +01:00
nicm
2f586905fc Fix a warning. 2015-06-05 09:09:08 +00:00
nicm
4219939c10 Make it so that if a window or session target is prefixed with an =,
only an exact name or index match is accepted, no special character,
prefix match, or fnmatch.
2015-06-05 08:14:16 +00:00
nicm
6b2129696f Move the nested check from client to server and compare the client tty
name to all the pane pty names instead of comparing socket paths. This
means that "new -d" will work without unsetting $TMUX.
2015-06-04 23:27:51 +00:00
jmc
dc0d34e137 tweak SYNOPSIS and usage(); 2015-06-04 20:34:22 +00:00
Thomas Adam
83a70172a4 Merge branch 'obsd-master' 2015-06-04 16:01:07 +01:00
nicm
4a6c06d6a9 Make unsetting a global option restore it to the default. Diff lying
around for a while, I have forgotten who suggested it :-/.
2015-06-04 14:29:33 +00:00
Thomas Adam
02e348c069 Merge branch 'obsd-master' 2015-06-04 12:59:41 +01:00
nicm
a863834574 Add support for a single "marked pane". There is one marked pane in the
server at a time; it may be toggled or cleared with select-pane -m and
-M (the border is highlighted). A new target '~' or '{marked}' specifies
the marked pane to commands and it is the default target for the
swap-pane and join-pane -s flag (this makes them much simpler to use -
mark the source pane and then change to the target pane to run swapp or
joinp).
2015-06-04 11:43:51 +00:00
Nicholas Marriott
1de74e27e5 Spaces -> tabs. 2015-06-04 11:40:27 +01:00
Nicholas Marriott
d058e963fd Update mailmap. 2015-06-04 11:36:44 +01:00
Thomas Adam
13808ccede Merge branch 'obsd-master' 2015-06-04 11:17:39 +01:00
nicm
a3edfd9e84 teminal -> terminal, from Corey Farwell. 2015-06-04 09:42:29 +00:00
Nicholas Marriott
75b70be4a6 Merge branch 'master' of github.com:tmux/tmux 2015-06-04 10:38:04 +01:00
Nicholas Marriott
b67db455a8 Update TODO with some items from old SF tickets. 2015-06-04 10:37:39 +01:00
Thomas Adam
2c29b3e82c SYNCING: Few tweaks 2015-06-04 10:35:40 +01:00
Thomas Adam
8fcac1b794 SYNCING: Update for GH
Explain the release process now that we're using GH.
2015-06-04 09:26:35 +01:00
Nicholas Marriott
75061cb45d I no longer need to care about GCC 3. 2015-06-04 08:50:20 +01:00
Nicholas Marriott
20598dff25 Note version this happened. 2015-06-04 08:47:23 +01:00
Nicholas Marriott
0b22d574e0 Update FAQ for new behaviour. 2015-06-04 08:46:49 +01:00
Nicholas Marriott
1df39aa962 I don't think we should carry around scripts. I'm not too sure about examples/
at all, nobody is maintaining it...
2015-06-04 08:26:50 +01:00
Nicholas Marriott
9d80ad16f9 Remove old tools. 2015-06-04 08:25:39 +01:00
Nicholas Marriott
c0a790453c Add a couple of presentations I wrote a few years ago. One for the ill-fated
AsiaBSDCon in 2011 (canceled due to Fukushima) and the other for LinuxTag 11 in
Berlin.
2015-06-04 08:23:40 +01:00
Nicholas Marriott
dbc5d7b331 Fix clone URL. 2015-06-04 01:27:47 +01:00
Nicholas Marriott
3ed03df23f Remove this file. 2015-06-04 01:26:03 +01:00
Nicholas Marriott
32bc8f4dd4 HTML bits are now elsewhere. 2015-06-04 01:21:41 +01:00
Nicholas Marriott
d2b35e19cd No more SF. 2015-06-04 00:44:22 +01:00
Nicholas Marriott
89131c3e90 No $Id$. 2015-06-04 00:38:01 +01:00
Nicholas Marriott
fc2fb0eb95 Update mailing list addresses. 2015-06-03 18:57:35 +01:00
Nicholas Marriott
dfd72f5250 -$Id$. 2015-06-03 18:42:36 +01:00
Nicholas Marriott
11ae6d16e5 $Id$ -> $OpenBSD$. 2015-06-03 18:35:44 +01:00
Nicholas Marriott
09bcbc57da $Id$ -> $OpenBSD$. 2015-06-03 18:28:26 +01:00
Nicholas Marriott
1c3e1bae41 Remove $Id$. 2015-06-03 18:26:25 +01:00
Nicholas Marriott
3821ca4917 Update TODO. 2015-06-02 15:16:13 +01:00
Thomas Adam
7bf5d4b946 Merge branch 'obsd-master' 2015-06-01 16:01:19 +01:00
nicm
a3c6172495 Missing t at end of response, from Vincent Bernat. 2015-06-01 13:59:57 +00:00
Thomas Adam
b675e6b2d5 Merge branch 'obsd-master' 2015-06-01 12:01:17 +01:00
nicm
58b50fb543 Clear signal handlers before event_reinit as apparently it can otherwise
cause libevent to go strange.
2015-06-01 09:20:19 +00:00
Thomas Adam
7712e6f82b Merge branch 'obsd-master' 2015-06-01 02:01:17 +01:00
deraadt
7e067cb9dc does not need syslog.h 2015-05-31 23:27:06 +00:00
Thomas Adam
c39dfb17ae Merge branch 'obsd-master' 2015-05-30 02:01:18 +01:00
nicm
2a8c2648f0 Don't use special strings if #() commands fail, just remove the format
(as if the command produced nothing). Makes constructions that can fail
like '#(test whatever && echo foo)' work as they did before.
2015-05-29 23:26:52 +00:00
nicm
74c755f2ab Expand formats again inside #(), and free the temporaries. 2015-05-29 23:12:38 +00:00
nicm
a55e569af5 Use RB_MIN to get the lowest index for the current window when creating
grouped sessions, rather than using RB_ROOT.
2015-05-29 23:02:27 +00:00
Thomas Adam
beffdf6575 Merge branch 'obsd-master' 2015-05-27 16:01:22 +01:00
nicm
379400cfa6 Move the jobs output cache into the formats code so that #() work more
generally (for example, again working in set-titles-string).
2015-05-27 13:28:04 +00:00
Thomas Adam
f538f2ae9b Merge branch 'obsd-master' 2015-05-20 10:01:19 +01:00
nicm
7140cce7f3 Return empty string if format is empty rather than attempting to
allocate zero bytes.
2015-05-20 06:39:02 +00:00
n6tadam
1ec93570bf Merge branch 'obsd-master' 2015-05-19 12:01:20 +01:00
nicm
2c53b23d59 In terminfo, sometimes cvvis implies cnorm and sometimes it doesn't, so
don't assume it does. Fixes missing cursor with emacs-in-tmux-in-tmux.
2015-05-19 08:48:37 +00:00
Thomas Adam
4123d69b51 README.md: github-specific readme
This is the same as the current README, but allows for markdown to be used.
We could switch this over to using the README file at some point.
2015-05-17 14:52:58 +01:00
Thomas Adam
35d21be19a TRAVIS-CI: correct path to configure
Specify path to ./configure
2015-05-17 14:39:04 +01:00
Thomas Adam
beb0c01c27 Hook repo to Travis-CI
From now on, all pushes to master will result in tmux compiling against a
linux-based distribution (Debian).  This will make it easier for automatic
merges between OpenBSD and portable to be tested, without the need for so
much manual syncing.

Any build failures will be reported to me, and fixed accordingly.
2015-05-17 14:36:34 +01:00
Thomas Adam
00471dc783 Merge branch 'obsd-master' 2015-05-13 09:44:11 +01:00
nicm
3f4ee98162 To replace c0-*, add a high watermark to the pty event, and also backoff
when the any of the ttys the pane is going to write to has buffered
enough data.
2015-05-12 22:40:38 +00:00
nicm
37ae8a9e0f Tidy blank lines when outputting server info. 2015-05-12 19:36:08 +00:00
nicm
ec34439f9c Add a session_alerts format which is a list of all the alerts in the
current session in symbolic form (something like "0!,4~,5!"). Use this
in the default set-titles-string. Prompted by a request from Jan ONDREJ.
2015-05-12 15:29:29 +00:00
nicm
e958db09a7 Add bell-action "other" to pass through bells in all windows except the
current, suggested by Jan ONDREJ.
2015-05-12 15:27:46 +00:00
nicm
b833fabeb2 Left the c0-* options behind in the table. 2015-05-11 10:58:22 +00:00
nicm
44364d7112 Remove the c0-* options which never really worked satisfactorily. Going
to try something else...
2015-05-11 10:10:16 +00:00
Thomas Adam
4165ed96f8 Add back __CYGWIN__ block
This went missing during the merge from OpenBSD.
2015-05-09 20:03:24 +01:00
Thomas Adam
c11f628342 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2015-05-09 12:53:53 +01:00
Thomas Adam
504b97b6a4 Merge branch 'obsd-master'
Conflicts:
	tmux.h
2015-05-09 12:52:38 +01:00
nicm
92faa2eaeb Put the tty structs together, and tabify. 2015-05-08 16:48:12 +00:00
nicm
592cb73a69 grid_marker_cell is no longer used. 2015-05-08 16:44:03 +00:00
nicm
74b2c40b1b mode_key_entry can go into mode-key.c; also a few spaces->tabs. 2015-05-08 16:33:29 +00:00
nicm
a538141a72 window_choose_mode_item can move into window-choose.c. 2015-05-08 16:23:34 +00:00
nicm
c4a4bd6ac5 Move input parser structs into input.c (removing fairly useless
saved_cursor_[xy] formats as a side-effect).
2015-05-08 16:18:04 +00:00
nicm
879de25583 Remove some stuff that accidentally ended up here from portable, and
remove a little-used debug function.
2015-05-08 15:56:49 +00:00
nicm
d174b9cfcc Update environment when switching sessions as well as attaching, from Si
Beaumont.
2015-05-07 14:07:16 +00:00
nicm
8e9b6e0948 Style spacing nits. 2015-05-07 11:42:56 +00:00
Nicholas Marriott
63b7a031a5 queue.h should come from compat.h. 2015-05-07 11:43:52 +01:00
nicm
1282bb81fe array.h can be local to window-choose.c now. 2015-05-07 08:08:54 +00:00
nicm
7becf326e3 Use a TAILQ not array for find-window. 2015-05-07 07:59:52 +00:00
nicm
73c871ba0a Simplify environ_push so it doesn't need the ARRAY_* functions. 2015-05-07 07:35:31 +00:00
nicm
b6be03f01a If status line is at the top, the offset needs to be adjusted when
drawing pane numbers.  Based on a diff from John O'Meara.
2015-05-07 07:16:14 +00:00
nicm
0b39e6427f Remove ARRAY_* from history and expand completion to complete a) layout
names and b) targets beginning with -t or -s.
2015-05-06 23:56:46 +00:00
Thomas Adam
6525ca5158 Start working on 2.1 2015-05-07 00:00:44 +01:00
Thomas Adam
e362d42dc6 CHANGES for tmux 2.0 2015-05-07 00:00:44 +01:00
Thomas Adam
f10d3675f8 Merge branch 'obsd-master' 2015-05-06 10:03:52 +01:00
nicm
31b1ab4852 Add a format window_linked which is 1 if a window has been linked
multiple times, also remove the default space in window_flags and use a
conditional to add it in window-status-format (this means additional
flags can be added in the option without extra spaces). From Thomas Adam
with tweaks by me.
2015-05-06 08:35:39 +00:00
nicm
33a585c47f Turn cursor off during redraw, pointed out by George Nachman. 2015-05-06 07:52:06 +00:00
nicm
672df72b71 Use the right index when expanding/collapsing tree, from Thomas Adam. 2015-05-04 13:04:10 +00:00
Thomas Adam
c0cf4843e5 Merge branch 'obsd-master' 2015-04-29 18:42:12 +01:00
nicm
69b8f100b7 Do not complain when directions fail. 2015-04-29 16:26:17 +00:00
nicm
7382ba82c5 If default-terminal is set to "screen" or "screen-*", emulate screen's
historical (incorrect) behaviour for SGR 3 and send smso
(standout). Previously, we would send sitm (italics) if the terminal
outside had it and smso otherwise. This was acceptably until recently
because xterm's terminfo entry lacked sitm, so most users got smso.

People who want italics should set default-terminal to the forthcoming
"tmux" entry (and be prepared to deal with it being missing on older
hosts).

As a side-effect this changes default-terminal to be a server rather
than a session option.

suggested by and ok naddy
2015-04-29 15:59:08 +00:00
Nicholas Marriott
8794562a85 Add tmux4.png. 2015-04-28 16:04:07 +01:00
Nicholas Marriott
31ab5caa35 Renumber screenshots. 2015-04-28 15:34:09 +01:00
Nicholas Marriott
1ed5326f5a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2015-04-28 15:18:53 +01:00
Nicholas Marriott
ab5f9ab55b Update two of the screenshots. 2015-04-28 15:12:45 +01:00
Thomas Adam
dc2adc6bc1 Merge branch 'obsd-master' 2015-04-28 14:57:15 +01:00
Nicholas Marriott
7981e653d8 But this does work. 2015-04-28 14:01:03 +01:00
Nicholas Marriott
bc9198072b Upload all the files. 2015-04-28 13:58:17 +01:00
Nicholas Marriott
e88c48ce0e This doesn't work. 2015-04-28 13:58:00 +01:00
Nicholas Marriott
f54f3e2abe Add logo to www, also centre the page. 2015-04-28 13:47:54 +01:00
Nicholas Marriott
bb210ce773 Add tmux logo, createed by Jason Long. 2015-04-28 13:46:47 +01:00
nicm
e36fab2f70 If looking for an index, don't fill in window when given a session. 2015-04-28 12:09:24 +00:00
nicm
14d8cd6445 Do not do a search for the tty path if there isn't one. 2015-04-28 11:57:20 +00:00
nicm
094a047ddf If can't find pane as a pane, try as a window; likewise if can't find
window as a session.
2015-04-28 11:33:17 +00:00
nicm
771744426e Add select-layout -o to undo the last layout change (apply the previously
set layout).
2015-04-28 10:43:13 +00:00
Nicholas Marriott
3eb40a520a No paths.h on Solaris. 2015-04-28 10:36:17 +01:00
Thomas Adam
7d98c51805 Merge branch 'obsd-master' 2015-04-28 09:10:51 +01:00
nicm
c2bc84aa4d Do not include unattached clients when trying to find one for target. 2015-04-27 22:58:58 +00:00
nicm
b7777e7ef3 Reset cfg_ncauses to 0 as well or we could allocate the wrong size if
called again.
2015-04-27 22:50:35 +00:00
nicm
91f6347485 Assign to the right variable when comparing clients. 2015-04-27 22:42:10 +00:00
Thomas Adam
94a8ef1cae Merge branch 'obsd-master'
Conflicts:
	Makefile
	tmux.1
2015-04-27 21:21:55 +01:00
nicm
95195f5258 Rewrite of the target resolution internals to be simpler and more
consistent but with much less duplication, but keeping the same internal
API. Also adds more readable aliases for some of the special tokens used
in targets (eg "{start}" instead of "^"). Some behaviours may have
changed, for example prefix matches now happen before fnmatch.
2015-04-27 16:25:57 +00:00
nicm
a70762c9b5 If the requested pane is already active, do not unzoom the window (or do
anything else). Prevents mouse clicking when zoomed causing unzoom,
reported by Jose Antonio Delgado Alfonso (with a different fix).
2015-04-27 07:49:36 +00:00
nicm
5bd5c9c84e Remove panes from layout if spawning them fails, reported by Anthony J
Bentley.
2015-04-26 20:25:20 +00:00
Thomas Adam
72e9ebf2ec Merge branch 'obsd-master' 2015-04-25 20:45:02 +00:00
nicm
05e7fbd60f Get rid of window_choose_list type. 2015-04-25 18:56:05 +00:00
nicm
1d1208e335 Fix some char* -> char *. 2015-04-25 18:49:01 +00:00
nicm
a568b9cadc Use a char **,u_int pair for cfg_causes. 2015-04-25 18:47:01 +00:00
nicm
07dfdb974d Make message log a TAILQ. 2015-04-25 18:33:59 +00:00
nicm
6dbd63ba4f Move the functions to convert ids from strings into session.c and window.c. 2015-04-25 18:09:28 +00:00
nicm
d23af6cca0 Explicitly cancel mouse "button" mode, this happens implicitly with some
one of the other things we send with xterm, but not with urxvt. Reported
by sthen@.
2015-04-25 15:57:48 +00:00
Thomas Adam
56e1132db4 Merge branch 'obsd-master' 2015-04-25 10:02:46 +00:00
nicm
aeedb464a6 Convert clients list into a TAILQ. 2015-04-24 23:17:11 +00:00
nicm
583b4ab72b Set working directory for run-shell and if-shell. 2015-04-24 22:19:36 +00:00
nicm
5a2d0533a8 Allow choice options (multiple states) to be toggled between states 0
and 1.
2015-04-24 21:38:18 +00:00
nicm
a5a873dccc Set up signal handler earlier so that we don't get zombies, reported by
sobrado@.
2015-04-24 20:58:44 +00:00
deraadt
ab73997cc5 use reallocarray instead of calloc; avoid the zero before infill
ok nicm
2015-04-23 07:45:50 +00:00
nicm
9a453dd354 Make session_has return a flag, returning the first winlink found is a
recipe for errors.
2015-04-22 15:32:33 +00:00
nicm
8d66f4fba4 Change the windows array into an RB tree and fix some places where we
were only looking at the first winlink for a window in a session.
2015-04-22 15:30:11 +00:00
nicm
89e80cabd5 window_index is only used in one place (window_destroy) so inline it there. 2015-04-22 15:05:03 +00:00
Thomas Adam
0a88377086 Merge branch 'obsd-master' 2015-04-22 10:05:54 +01:00
nicm
3909aff06a Look up indexes as number before name, makes more sense if windows are
named starting with numbers. From Thomas Adam.
2015-04-21 22:42:27 +00:00
nicm
69f292a90e Always format real layout even when zoomed. 2015-04-21 22:38:49 +00:00
nicm
93b2871cab Do not die on USR1 if any of the socket parent directories are
missing. Reported by Robin Powell.
2015-04-21 22:32:40 +00:00
nicm
7a72eff4a4 Simplify error messages when socket connect fails, suggested by "Karthik K". 2015-04-21 22:21:41 +00:00
nicm
d16b640fe8 The free callback could end up being fired before the done callback
(happens on Cygwin), so use a reference count instead of a single
flag. SF bug 188 reported by "iceboy".
2015-04-21 21:31:02 +00:00
nicm
0e7219d437 Fix moving windows to nonexistent indexes when renumber-windows is
off. From Thomas Adam, reported by Daniel Levai and Theo Buehler.
2015-04-21 21:24:49 +00:00
nicm
d1337053b6 Bind mouse dragging so that it is passed through to applications if they
want it rather than entering copy mode.
2015-04-21 15:34:32 +00:00
nicm
4cf4302962 Don't eat the mouse event that triggers a drag end because we may want
to pass it on to application inside the pane.
2015-04-21 15:21:41 +00:00
nicm
1f404f6a23 Put mouse_any_flag back, don't know where it went to (still in man page). 2015-04-21 15:18:38 +00:00
nicm
bc3786ece9 Pass mouse events through to commands for if-shell. 2015-04-21 15:18:06 +00:00
nicm
0610f44380 cmd_mouse_pane can return NULL, check for that. 2015-04-21 15:16:06 +00:00
nicm
07d93db427 Remove unused-but-set variables, from Thomas Adam. 2015-04-20 15:41:32 +00:00
nicm
bded743706 Support for multiple key tables to commands to be bound to sequences of
keys. The default key bindings become the "prefix" table and -n the
"root" table. Keys may be bound in new tables with bind -T and
switch-client -T used to specify the table in which the next key should
be looked up. Based on a diff from Keith Amling.
2015-04-20 15:34:56 +00:00
nicm
3497843f02 Style nit - unnecessary brackets. 2015-04-20 14:48:55 +00:00
Thomas Adam
b25dc423b0 Merge branch 'obsd-master' 2015-04-20 15:44:27 +01:00
nicm
0fd9a97202 Make jump-to-backward/jump-to-forward repeatable with
jump-reverse/jump-again, from Jacob Niehus.
2015-04-20 09:39:21 +00:00
nicm
6f587570ed Use a more sensible buffer size for flags string. 2015-04-20 07:50:49 +00:00
Nicholas Marriott
acb8248ba6 +. 2015-04-20 08:46:21 +01:00
jmc
8101f1ef16 tweak previous; 2015-04-19 22:10:30 +00:00
nicm
bbac2aee1f Honour renumber-windows when unlinking a window, from Thomas Adam. 2015-04-19 21:46:52 +00:00
nicm
bf635e7741 Rewrite of tmux mouse support which was a mess. Instead of having
options for "mouse-this" and "mouse-that", mouse events may be bound as
keys and there is one option "mouse" that turns on mouse support
entirely (set -g mouse on).

See the new MOUSE SUPPORT section of the man page for description of the
key names and new flags (-t= to specify the pane or window under mouse
as a target, and send-keys -M to pass through a mouse event).

The default builtin bindings for the mouse are:

    bind -n   MouseDown1Pane select-pane -t=; send-keys -M
    bind -n MouseDown1Status select-window -t=
    bind -n   MouseDrag1Pane copy-mode -M
    bind -n MouseDrag1Border resize-pane -M

To get the effect of turning mode-mouse off, do:

    unbind -n MouseDrag1Pane
    unbind -temacs-copy MouseDrag1Pane

The old mouse options are now gone, set-option -q may be used to
suppress warnings if mixing configuration files.
2015-04-19 21:34:21 +00:00
nicm
ee123c2489 Support setting the default window and pane background colours (window
and active pane via window-style and window-active-style options, an
individual pane by a new select-pane -P flag). From J Raynor.
2015-04-19 21:05:27 +00:00
Nicholas Marriott
24c8f523eb +. 2015-04-19 19:40:12 +01:00
Nicholas Marriott
aaad44bbe7 +. 2015-04-19 19:34:58 +01:00
Thomas Adam
370cf75458 Merge branch 'obsd-master' 2015-04-19 14:44:56 +01:00
nicm
4a7587931c Fix some issues in bright colour handling. Bold background doesn't exist
so there is no reason for tty_check_bg to mess with the BRIGHT flag at
all, ever. Also use aixterm colours for 256-to-16 translation if the
terminal supports them. And there is no reason for tty_colours_bg to
worry about whether the terminal supports them - tty_check_bg has
already taken care of it.
2015-04-15 22:34:46 +00:00
nicm
eec27f9257 Use tty_term_flag not _has for flags, also fix a typo (position not
permission).
2015-04-15 22:10:13 +00:00
nicm
f922920609 Fix setting old-style window -fg/-bg/-attr options that aren't global. 2015-04-15 15:44:40 +00:00
nicm
0cd55eb1e7 Add a -x flag to copy-selection, append-selection and start-named-buffer
to prevent it exiting copy mode after copying. From J Raynor with a few
tweaks by me.
2015-04-10 16:00:08 +00:00
nicm
009a5e4213 in the case -> in this case. 2015-04-10 07:23:14 +00:00
nicm
6920be311b When replacing, don't free the old paste until after the new one's name
has been copied. Fixes a use-after-free in window-copy.c. Bug reported
by J Raynor (who also provided a different fix).
2015-04-07 13:06:22 +00:00
nicm
3aa72b42b2 Add a helper function to convert time, and add session_activity formats
(the latter from Takatoshi Matsumoto).
2015-03-31 17:58:36 +00:00
nicm
02df86079b Fix some format specifier nits, from Ben Boeckel. 2015-03-31 17:45:10 +00:00
Nicholas Marriott
5e956f1148 Make place const to avoid a warning, from Ben Boeckel. 2015-03-31 09:26:37 +01:00
nicm
cd9ccbc1e9 set-titles-string now uses formats, not the status bits (so no #() for
now). Reported by landry.
2015-03-11 08:17:37 +00:00
Nicolas Viennot
e203bff96e Start tmate after the config files are processed
Closes #50
2015-01-30 12:08:13 -05:00
Nicolas Viennot
a1c9d8784f Version bump to 1.8.10 2014-10-31 00:30:36 -04:00
Nicolas Viennot
2f43ed93b7 Allow clients to extract the ssh connection strings from cmd line 2014-10-31 00:30:36 -04:00
Nicolas Viennot
6e4adcc140 Update libssh 2014-10-31 00:30:36 -04:00
Nicolas Viennot
0783022d6d Fix issue with OSX 10.10 2014-09-12 16:08:10 -04:00
Nicolas Viennot
dfe63e9e73 Forgot some libssh files 2013-11-10 02:46:15 -05:00
Nicolas Viennot
2535b531bb Update libssh 2013-11-06 19:40:47 -05:00
Nicolas Viennot
92bf230b8a Can't use the legacy logging callbacks of libssh, it's broken 2013-11-06 19:08:55 -05:00
Nicolas Viennot
a37b7d1ae5 Fix makefile 2013-11-06 19:08:54 -05:00
Nicolas Viennot
3ce7122aac Upgrade to 1.8.9 2013-10-04 17:53:02 -04:00
Nicolas Viennot
ed4020b589 Use ~/.tmate.conf to load tmate specific settings
Closes #10
2013-10-04 17:52:12 -04:00
Nicolas Viennot
0d182e707e Allow users to specify their own tmate servers
Options:
- tmate-server-host
- tmate-server-port
- tmate-server-dsa-fingerprint
- tmate-server-rsa-fingerprint
- tmate-server-ecdsa-fingerprint
2013-10-04 17:36:46 -04:00
Nicolas Viennot
bb5634ce20 Update libssh 2013-10-04 16:34:36 -04:00
Nicolas Viennot
8a87170c8a Remove GSSAPI support in libssh 2013-08-16 18:31:20 -04:00
Nicolas Viennot
604c43bfab Updated to 1.8.8 2013-08-16 13:32:38 -04:00
Nicolas Viennot
246bec30bc Updated libssh 2013-08-16 13:32:26 -04:00
Nicolas Viennot
aab28e3796 Update version to 1.8.7 2013-08-13 15:43:43 -04:00
Nicolas Viennot
31326220fa [server lost] bug fix: The DNS resolver must not be freed on MacOSX 2013-08-13 15:43:43 -04:00
Nicolas Viennot
089a594a68 Better stack traces 2013-07-29 09:51:37 -04:00
Nicolas Viennot
13d3439933 SSH key passphrase support
Closes #6
2013-07-23 16:55:06 -04:00
Nicolas Viennot
b97568cac2 Fix status bar timeout when the client is not yet connected to the session 2013-07-23 16:22:51 -04:00
Nicolas Viennot
ebc4e5ecdf User can specify his SSH identity with the tmate-identity global option 2013-07-22 18:05:44 -04:00
Nicolas Viennot
36bfa71b78 Support for multiple IP on DNS 2013-07-22 17:24:08 -04:00
Nicolas Viennot
2e3661a0f6 Update libssh 2013-07-11 19:40:23 -04:00
Nicolas Viennot
7be65e79db localhost localhost -> 127.0.0.1 for dev mode (ipv6) 2013-07-11 19:40:23 -04:00
Nicolas Viennot
c9a6e2560a Synchronize the list binding pane (bind-key + ?) 2013-06-26 02:05:13 -04:00
Nicolas Viennot
59cab76dd8 Fix copy mode when the buffer size is smaller than 2000 2013-06-26 00:54:27 -04:00
Nicolas Viennot
ddf0a9dd55 Fix compile bug
libssh/include/libssh/libssh.h:115: error: previous declaration of 'ssh_session' was here
tmate.h:83: error: redefinition of typedef 'ssh_channel'
libssh/include/libssh/libssh.h:110: error: previous declaration of 'ssh_channel' was here
make: *** [tmate-ssh-client.o] Error 1
2013-06-17 17:34:34 -04:00
Nicolas Viennot
edea6cf141 Release 1.8.4 2013-06-14 23:59:26 -04:00
Nicolas Viennot
632553bdc9 SSH log level is tweakable with -v 2013-06-14 23:58:08 -04:00
Nicolas Viennot
7316ed33e1 [libssh] auth: If the agent fails, fall back to regular path
It's causing issues on MacOSX when ssh_agent_get_ident_count()
reports "Agent count: 0".
2013-06-14 23:53:18 -04:00
Nicolas Viennot
8f19552af0 Better error message when SSH keys are not setup 2013-06-14 23:10:24 -04:00
Nicolas Viennot
80f9e84b83 Release 1.8.3 2013-06-14 22:39:28 -04:00
Nicolas Viennot
53355a0b92 Bug fix: $TMUX wasn't being reused properly 2013-06-14 22:39:21 -04:00
Nicolas Viennot
16dd13979e Ubuntu complains without the README 2013-06-14 22:11:13 -04:00
Nicolas Viennot
12d681d8cc Change connection string tmate.io -> master.tmate.io 2013-06-14 22:11:12 -04:00
Nicolas Viennot
5d847fb0aa Random socket path (we don't support multi sessions) 2013-06-14 15:35:39 -04:00
Nicolas Viennot
a50dcb09b5 Notification messages 2013-06-13 05:15:08 -04:00
Nicolas Viennot
edd194c23c Synchronize copy-mode 2013-06-13 02:34:59 -04:00
Nicolas Viennot
fc4eaeb89f TERM defaults to screen-256color 2013-06-13 02:34:58 -04:00
Nicolas Viennot
e52312ec3c Report failed commands to slave
which will in turn notify the proper client
2013-06-12 20:33:58 -04:00
Nicolas Viennot
844451c6ce Show tmate messages in the status bar 2013-06-12 19:47:36 -04:00
Nicolas Viennot
a1d7bf7dc0 No reconnection for now 2013-06-12 18:02:29 -04:00
Nicolas Viennot
2dca2c0fd5 Synching winlinks idx instead of window ids 2013-06-12 17:58:31 -04:00
Nicolas Viennot
e70a5f8b7f Add strack trace debug function 2013-06-12 17:57:53 -04:00
Nicolas Viennot
a4e196366e Quick README 2013-06-12 16:30:04 -04:00
Nicolas Viennot
69bc1bfde5 Sync all session windows 2013-06-12 03:19:42 -04:00
Nicolas Viennot
bf4edb4056 Authenticating the server 2013-06-12 01:28:01 -04:00
Nicolas Viennot
141428691e Status bar sync 2013-06-11 23:50:16 -04:00
Nicolas Viennot
35daf6d805 Replication of bind/unbind commands 2013-06-11 22:52:21 -04:00
Nicolas Viennot
839c4e3dd9 Replicate remote client commands 2013-06-11 22:32:49 -04:00
Nicolas Viennot
b7371802bf Developer Environement setup 2013-06-11 17:00:50 -04:00
Nicolas Viennot
f89b98e1c3 Use tmate.io 2013-06-11 13:30:25 -04:00
Nicolas Viennot
6988b99fb4 Enable compression 2013-06-10 05:59:59 -04:00
Nicolas Viennot
56cee30ee8 [libssh] fix server side compression 2013-06-10 05:59:59 -04:00
Nicolas Viennot
7cdb1e2016 [libssh] bug fix in channel_open() 2013-06-10 04:30:12 -04:00
Nicolas Viennot
8131143fa8 gitignore update 2013-06-10 04:30:12 -04:00
Nicolas Viennot
a75e70f86b Fix error message 2013-06-10 04:30:12 -04:00
Nicolas Viennot
864124f4c0 Public key auth no longer need to be blocking (libssh 0.6) 2013-06-10 02:50:07 -04:00
Nicolas Viennot
05de59d106 Adding msgpack 2013-06-10 02:50:07 -04:00
Nicolas Viennot
0f7ccda4fb Adding libssh 2013-06-10 02:50:07 -04:00
Nicolas Viennot
220b2afb3c Client side first shot 2013-06-10 01:54:57 -04:00
219 changed files with 19816 additions and 10402 deletions

1
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1 @@
github: nviennot

41
.github/workflows/DragonflyBSD.yml vendored Normal file
View file

@ -0,0 +1,41 @@
name: DragonflyBSD
on:
push:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/DragonflyBSD.yml'
pull_request:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/DragonflyBSD.yml'
jobs:
DragonflyBSD:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- uses: vmactions/dragonflybsd-vm@v0
with:
prepare: |
pkg install -y automake autoconf libtool pkgconf libevent msgpack libssh gsed
usesh: true
run: |
gsed -i "s/OK/0/g" tty-term.c
autoupdate
./autogen.sh
./configure
make
make install

40
.github/workflows/FreeBSD.yml vendored Normal file
View file

@ -0,0 +1,40 @@
name: FreeBSD
on:
push:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/FreeBSD.yml'
pull_request:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/FreeBSD.yml'
jobs:
FreeBSD:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- uses: vmactions/freebsd-vm@v0
with:
prepare: |
pkg install -y automake autoconf libtool pkgconf libevent msgpack libssh
usesh: true
run: |
autoupdate
./autogen.sh
./configure
make
make install

37
.github/workflows/MacOS.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: MacOS
on:
push:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/MacOS.yml'
pull_request:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/MacOS.yml'
jobs:
MacOS:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- run: |
brew install automake msgpack libssh
autoupdate
./autogen.sh
./configure
make
make install

40
.github/workflows/NetBSD.yml vendored Normal file
View file

@ -0,0 +1,40 @@
name: NetBSD
on:
push:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/NetBSD.yml'
pull_request:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/NetBSD.yml'
jobs:
NetBSD:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- uses: vmactions/netbsd-vm@v0
with:
prepare: |
pkg_add automake autoconf libtool pkgconf libevent msgpack libssh
usesh: true
run: |
autoupdate
./autogen.sh
./configure
make
make install

50
.github/workflows/OpenBSD.yml vendored Normal file
View file

@ -0,0 +1,50 @@
name: OpenBSD
on:
push:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/OpenBSD.yml'
pull_request:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/OpenBSD.yml'
jobs:
OpenBSD:
runs-on: macos-12
steps:
- uses: actions/checkout@v2
- uses: vmactions/openbsd-vm@v0
with:
prepare: |
pkg_add automake-1.16.3 autoconf-2.71 libtool pkgconf libevent msgpack libssh curl
usesh: true
run: |
sed -i 's,<event.h>,<event2/event.h>,' *.[ch]
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-Makefile_am | patch
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-server_c | patch
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmate-debug_c | patch
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmate_h | patch
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmux_c | patch
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmux_h | patch
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-osdep-openbsd_c | patch
export AUTOMAKE_VERSION=1.16
export AUTOCONF_VERSION=2.71
autoupdate
./autogen.sh
./configure
make
make install

37
.github/workflows/Ubuntu.yml vendored Normal file
View file

@ -0,0 +1,37 @@
name: Ubuntu
on:
push:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/Ubuntu.yml'
pull_request:
branches:
- '*'
paths:
- '**.c'
- '**.h'
- 'compat/*'
- '.github/workflows/Ubuntu.yml'
jobs:
Ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: |
sudo apt-get install -y build-essential automake libtool libevent-dev libncurses5-dev libmsgpack-dev libssh-dev pkg-config
autoupdate
ACLOCAL_PATH=/usr/share/aclocal ./autogen.sh
./configure
make
sudo make install

11
.gitignore vendored
View file

@ -16,4 +16,13 @@ tmux
Makefile
Makefile.in
configure
tmux.1.*
tmate
cscope.*
ctags
*.log
tmate.1.*
downloads/
ext/
libssh-*/
msgpack-*/
releases/

View file

@ -1,24 +1,36 @@
Bob Beck <beck@openbsd.org> beck <beck>
Igor Sobrado <sobrado@openbsd.org> sobrado <sobrado>
Jacek Masiulaniec <jacekm@openbsd.org> jacekm <jacekm>
Jason McIntyre <jmc@openbsd.org> jcm <jcm>
Bob Beck <beck@openbsd.org> beck <beck>
Claudio Jeker <claudio@openbsd.org> claudio <claudio>
Igor Sobrado <sobrado@openbsd.org> sobrado <sobrado>
Ingo Schwarze <schwarze@openbsd.org> schwarze <schwarze>
Jacek Masiulaniec <jacekm@openbsd.org> jacekm <jacekm>
Jason McIntyre <jmc@openbsd.org> jmc <jmc>
Joel Sing <jsing@openbsd.org> jsing <jsing>
Marc Espie <espie@openbsd.org> espie <espie>
Matthew Dempsky <matthew@openbsd.org> matthew <matthew>
Matthias Kilian <kili@openbsd.org> kili <kili>
Matthieu Herrb <matthieu@openbsd.org> matthieu <matthieu>
Miod Vallat <miod@openbsd.org> miod <miod>
Nicholas Marriott <nicm@openbsd.org> nicm <nicm>
Nicholas Marriott <nicm@openbsd.org> no_author <no_author@example.org>
<nicm@openbsd.org> <nicholas.marriott@gmail.com>
Okan Demirmen <okan@openbsd.org> okan <okan>
Jonathan Gray <jsg@openbsd.org> jsg <jsg>
Kenneth R Westerback <krw@openbsd.org> krw <krw>
Marc Espie <espie@openbsd.org> espie <espie>
Matthew Dempsky <matthew@openbsd.org> matthew <matthew>
Matthias Kilian <kili@openbsd.org> kili <kili>
Matthieu Herrb <matthieu@openbsd.org> matthieu <matthieu>
Michael McConville <mmcc@openbsd.org> mmcc <mmcc>
Miod Vallat <miod@openbsd.org> miod <miod>
Nicholas Marriott <nicholas.marriott@gmail.com> Nicholas Marriott <nicm@openbsd.org>
Nicholas Marriott <nicholas.marriott@gmail.com> nicm <nicm>
Nicholas Marriott <nicholas.marriott@gmail.com> no_author <no_author@example.org>
Okan Demirmen <okan@openbsd.org> okan <okan>
Philip Guenther <guenther@openbsd.org> guenther <guenther>
Pierre-Yves Ritschard <pyr@openbsd.org> pyr <pyr>
Ray Lai <ray@openbsd.org> ray <ray>
Pierre-Yves Ritschard <pyr@openbsd.org> pyr <pyr>
Ray Lai <ray@openbsd.org> ray <ray>
Ryan McBride <mcbride@openbsd.org> mcbride <mcbride>
Stefan Sperling <stsp@openbsd.org> stsp <stsp>
Stuart Henderson <sthen@openbsd.org> sthen <sthen>
Ted Unangst <tedu@openbsd.org> tedu <tedu>
Theo Deraadt <deraadt@openbsd.org> deraadt <deraadt>
Sebastian Benoit <benno@openbsd.org> benno <benno>
Stefan Sperling <stsp@openbsd.org> stsp <stsp>
Stuart Henderson <sthen@openbsd.org> sthen <sthen>
Ted Unangst <tedu@openbsd.org> tedu <tedu>
Theo de Raadt <deraadt@openbsd.org> Theo Deraadt <deraadt@openbsd.org>
Theo de Raadt <deraadt@openbsd.org> deraadt <deraadt>
Thomas Adam <thomas@xteddy.org> Thomas <thomas@xteddy.org>
William Yodlowsky <william@openbsd.org> william <william>
Thomas Adam <thomas@xteddy.org> Thomas Adam <thomas.adam@smoothwall.net>
Thomas Adam <thomas@xteddy.org> n6tadam <n6tadam@xteddy.org>
Tim van der Molen <tim@openbsd.org> tim <tim>
Tobias Stoeckmann <tobias@openbsd.org> tobias <tobias>
Todd C Miller <millert@openbsd.org> millert <millert>
William Yodlowsky <william@openbsd.org> william <william>

40
.travis.yml Normal file
View file

@ -0,0 +1,40 @@
language: c
services:
- docker
matrix:
include:
- arch: amd64
env: PLATFORM=amd64
- arch: amd64
env: PLATFORM=i386
- arch: arm64
env: PLATFORM=arm32v6
- arch: arm64
env: PLATFORM=arm32v7
- arch: arm64
env: PLATFORM=arm64v8
- arch: s390x
env: PLATFORM=s390x
- arch: ppc64le
env: PLATFORM=ppc64le
script:
- 'docker build . --tag local-$PLATFORM/tmate-build --build-arg PLATFORM=$PLATFORM'
# On arch=arm64, some directories are not setup correctly, and 'ruby -S gem
# install dpl' required by the release push scripts fails.
- 'if [ "$TRAVIS_TAG" ]; then sudo chown -R $USER: /var/lib/gems /usr/local/bin; fi'
- 'if [ "$TRAVIS_TAG" ]; then ./build_static_release.sh $TRAVIS_TAG $PLATFORM; fi'
deploy:
provider: releases
api_key:
secure: T2109tjjOsrVLEpJZK/uxmO0AuDGXYFdN4AAsNTmVwu/W5dcX57Kk2TCgqDuLfD21iGGXP0U/OYHM06IfBDODBWCA9P8ASHYsenS7wIiFnvCEMbfzoAFyBMrXN2kNdM2+ho3aqc0xE2lQKOKDLxpGm5FZrzujscXXzxQjWBU5Hk=
skip_cleanup: true
overwrite: true
file_glob: true
file: releases/*.tar.*
on:
repo: tmate-io/tmate
branch: master
tags: true

112
CHANGES
View file

@ -1,3 +1,113 @@
CHANGES FROM 2.0 to 2.1 18 October 2015
Incompatible Changes
====================
* Mouse-mode has been rewritten. There's now no longer options for:
- mouse-resize-pane
- mouse-select-pane
- mouse-select-window
- mode-mouse
Instead there is just one option: 'mouse' which turns on mouse support
entirely.
* 'default-terminal' is now a session option. Furthermore, if this is set
to 'screen-*' then emulate what screen does. If italics are wanted, this
can be set to 'tmux' but this is still new and not necessarily supported
on all platforms with older ncurses installs.
* The c0-* options for rate-limiting have been removed. Instead, a backoff
approach is used.
Normal Changes
==============
* New formats:
- session_activity
- window_linked
- window_activity_format
- session_alerts
- session_last_attached
- client_pid
- pid
* 'copy-selection', 'append-selection', 'start-named-buffer' now understand
an '-x' flag to prevent it exiting copying mode.
* 'select-pane' now understands '-P' to set window/pane background colours.
* 'renumber-windows' now understands windows which are unlinked.
* 'bind' now understands multiple key tables. Allows for key-chaining.
* 'select-layout' understands '-o' to undo the last layout change.
* The environment is updated when switching sessions as well as attaching.
* 'select-pane' now understands '-M' for marking a pane. This marked pane
can then be used with commands which understand src-pane specifiers
automatically.
* If a session/window target is prefixed with '=' then only an exact match
is considered.
* 'move-window' understands '-a'.
* 'update-environment' understands '-E' when attach-session is used on an
already attached client.
* 'show-environment' understands '-s' to output Bourne-compatible commands.
* New option: 'history-file' to save/restore command prompt history.
* Copy mode is exited if the history is cleared whilst in copy-mode.
* 'copy-mode' learned '-e' to exit copy-mode when scrolling to end.
CHANGES FROM 1.9a to 2.0 6 March 2015
Incompatible Changes
====================
* The choose-list command has been removed.
* 'terminal-overrides' is now a server option, not a session option.
* 'message-limit' is now a server option, not a session option.
* 'monitor-content' option has been removed.
* 'pane_start_path' option has been removed.
* The "info" mechanism which used to (for some commands) provide feedback
has been removed, and like other commands, they now produce nothing on
success.
Normal Changes
==============
* tmux can now write an entry to utmp if the library 'utempter' is present
at compile time.
* set-buffer learned append mode (-a), and a corresponding
'append-selection' command has been added to copy-mode.
* choose-mode now has the following commands which can be bound:
- start-of-list
- end-of-list
- top-line
- bottom-line
* choose-buffer now understands UTF-8.
* Pane navigation has changed:
- The old way of always using the top or left if the choice is ambiguous.
- The new way of remembering the last used pane is annoying if the
layout is balanced and the leftmost is obvious to the user (because
clearly if we go right from the top-left in a tiled set of four we want
to end up in top-right, even if we were last using the bottom-right).
So instead, use a combination of both: if there is only one possible
pane alongside the current pane, move to it, otherwise choose the most
recently used of the choice.
* 'set-buffer' can now be told to give names to buffers.
* The 'new-session', 'new-window', 'split-window', and 'respawn-pane' commands
now understand multiple arguments and handle quoting problems correctly.
* 'capture-pane' understands '-S-' to mean the start of the pane, and '-E-' to
mean the end of the pane.
* Support for function keys beyond F12 has changed. The following explains:
- F13-F24 are S-F1 to S-F12
- F25-F36 are C-F1 to C-F12
- F37-F48 are C-S-F1 to C-S-F12
- F49-F60 are M-F1 to M-F12
- F61-F63 are M-S-F1 to M-S-F3
Therefore, F13 becomes a binding of S-F1, etc.
* Support using pane id as part of session or window specifier (so % means
session-of-%1 or window-of-%1) and window id as part of session
(so @1 means session-of-@1).
* 'copy-pipe' command now understands formats via -F
* 'if-shell' command now understands formats via -F
* 'split-window' and 'join-window' understand -b to create the pane to the left
or above the target pane.
CHANGES FROM 1.9 to 1.9a 22 February 2014
NOTE: This is a bug-fix release to address some important bugs which just
@ -1865,5 +1975,3 @@ The list of older changes is below.
emacs) that don't require scrolling regions (ESC[r) mostly work fine
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
$Id$

37
Dockerfile Normal file
View file

@ -0,0 +1,37 @@
ARG PLATFORM=amd64
FROM ${PLATFORM}/alpine:3.10 AS build
WORKDIR /build
RUN apk add --no-cache wget cmake make gcc g++ linux-headers zlib-dev openssl-dev \
automake autoconf libevent-dev ncurses-dev msgpack-c-dev libexecinfo-dev \
ncurses-static libexecinfo-static libevent-static msgpack-c ncurses-libs \
libevent libexecinfo openssl zlib
RUN set -ex; \
mkdir -p /src/libssh/build; \
cd /src; \
wget -O libssh.tar.xz https://www.libssh.org/files/0.9/libssh-0.9.0.tar.xz; \
tar -xf libssh.tar.xz -C /src/libssh --strip-components=1; \
cd /src/libssh/build; \
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
-DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_PCAP=OFF \
-DWITH_STATIC_LIB=ON -DWITH_GSSAPI=OFF ..; \
make -j $(nproc); \
make install
COPY compat ./compat
COPY *.c *.h autogen.sh Makefile.am configure.ac ./
RUN ./autogen.sh && ./configure --enable-static
RUN make -j $(nproc)
RUN objcopy --only-keep-debug tmate tmate.symbols && chmod -x tmate.symbols && strip tmate
RUN ./tmate -V
FROM alpine:3.9
RUN apk --no-cache add bash
RUN mkdir /build
ENV PATH=/build:$PATH
COPY --from=build /build/tmate.symbols /build
COPY --from=build /build/tmate /build

59
FAQ
View file

@ -108,8 +108,8 @@ Check the latest version of tmux from Git to see if the problem is still
reproducible. Sometimes the length of time between releases means a lot of
fixes can be sitting in Git and the problem might already be fixed.
Please send bug reports by email to nicm@users.sourceforge.net or
tmux-users@lists.sourceforge.net. Please include as much of the following
Please send bug reports by email to nicholas.marriott@gmail.com or
tmux-users@googlegroups.com. Please include as much of the following
information as possible:
- the version of tmux you are running;
@ -123,7 +123,7 @@ information as possible:
* Why doesn't tmux do $x?
Please send feature requests by email to nicm@users.sourceforge.net.
Please send feature requests by email to tmux-users@googlegroups.com.
* Why do you use the screen terminal description inside tmux? It sucks.
@ -352,42 +352,33 @@ lock(1) or vlock(1)) by using the following:
bind x set lock-command '/usr/bin/vlock' \; lock-client \; set lock-command 'tput civis && read -s -n1'
* vim displays reverse video instead of italics, while less displays italics
(or just regular text) instead of reverse. What's wrong?
* I don't see italics! Or less and vim show italics and reverse the wrong way round!
Screen's terminfo description lacks italics mode and has standout mode in its
place, but using the same escape sequence that urxvt uses for italics. This
means applications (like vim) looking for italics will not find it and might
turn to reverse in its place, while applications (like less) asking for
standout will end up with italics instead of reverse. To make applications
aware that tmux supports italics and to use a proper escape sequence for
standout, you'll need to create a new terminfo file with modified sgr, smso,
rmso, sitm and ritm entries:
GNU screen does not support italics and the "screen" terminfo description uses
the italics escape sequence incorrectly.
$ mkdir $HOME/.terminfo/
$ screen_terminfo="screen"
$ infocmp "$screen_terminfo" | sed \
-e 's/^screen[^|]*|[^,]*,/screen-it|screen with italics support,/' \
-e 's/%?%p1%t;3%/%?%p1%t;7%/' \
-e 's/smso=[^,]*,/smso=\\E[7m,/' \
-e 's/rmso=[^,]*,/rmso=\\E[27m,/' \
-e '$s/$/ sitm=\\E[3m, ritm=\\E[23m,/' > /tmp/screen.terminfo
$ tic /tmp/screen.terminfo
As of tmux 2.1, if default-terminal is set to "screen" or matches "screen-*",
tmux will behave like screen and italics will be disabled.
To enable italics, create a new terminfo entry called "tmux" (some platforms
may already have this, you can check with "infocmp tmux"):
$ cat <<EOF|tic -x -
tmux|tmux terminal multiplexer,
ritm=\E[23m, rmso=\E[27m, sitm=\E[3m, smso=\E[7m, Ms@,
use=xterm+tmux, use=screen,
tmux-256color|tmux with 256 colors,
use=xterm+256setaf, use=tmux,
EOF
$
And tell tmux to use it in ~/.tmux.conf:
set -g default-terminal "screen-it"
set -g default-terminal "tmux"
If your terminal supports 256 colors, use:
$ screen_terminfo="screen-256color"
instead of "screen". See the FAQ entry about 256 colors support for more info.
Also note that tmux will still display reverse video on terminals that do not
support italics.
If your urxvt cannot display italics at all, make sure you have an italics
capable font enabled, for example, add to ~/.Xdefaults:
If using urxvt, make sure you have an italics capable font enabled. for
example, add to ~/.Xdefaults:
urxvt.italicFont: xft:Bitstream Vera Sans Mono:italic:autohint=true
@ -461,5 +452,3 @@ Or from inside tmux by detaching individual clients with C-b D or all
using:
C-b : attach -d
$Id$

View file

@ -1,17 +1,16 @@
# $Id$
# Makefile.am
# Obvious program stuff.
bin_PROGRAMS = tmux
CLEANFILES = tmux.1.mdoc tmux.1.man
bin_PROGRAMS = tmate
CLEANFILES = tmate.1.mdoc tmate.1.man
# Distribution tarball options.
EXTRA_DIST = \
CHANGES FAQ README TODO COPYING examples compat \
array.h compat.h tmux.h osdep-*.c mdoc2man.awk tmux.1
CHANGES FAQ README TODO COPYING example_tmux.conf compat/*.[ch] \
array.h compat.h tmux.h osdep-*.c xmalloc.h mdoc2man.awk tmate.1
dist-hook:
make clean
grep "^#found_debug=" configure
find $(distdir) -name .svn -type d|xargs rm -Rf
# Preprocessor flags.
CPPFLAGS += @XOPEN_DEFINES@ -DTMUX_CONF="\"$(sysconfdir)/tmux.conf\""
@ -22,8 +21,11 @@ if IS_GLIBC
CFLAGS += -D_GNU_SOURCE
endif
# Set flags for gcc. gcc4 whines abouts silly stuff so it needs slightly
# different flags.
if IS_LINUX
CFLAGS += -rdynamic # for stack traces
endif
# Set flags for gcc.
if IS_GCC
CFLAGS += -std=gnu99 -O2
if IS_DEBUG
@ -31,20 +33,20 @@ CFLAGS += -g
CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align
CFLAGS += -Wdeclaration-after-statement
CFLAGS += -Wundef -Wbad-function-cast -Winline
CFLAGS += -Wno-pointer-sign -Wno-attributes
CPPFLAGS += -DDEBUG
endif
if IS_GCC4
if IS_COVERAGE
CFLAGS += -g -O0 --coverage
LDFLAGS += --coverage
endif
CPPFLAGS += -iquote.
if IS_DEBUG
CFLAGS += -Wno-pointer-sign
endif
else
CPPFLAGS += -I. -I-
endif
endif
CFLAGS += -Wno-unused-parameter -Wno-unused-variable -Wno-null-pointer-arithmetic
CFLAGS += -Wno-deprecated-declarations -Wno-format-nonliteral
# Set flags for Solaris.
if IS_SUNOS
if IS_GCC
@ -59,8 +61,14 @@ if IS_SUNCC
CFLAGS += -erroff=E_EMPTY_DECLARATION
endif
# Set _LINUX_SOURCE_COMPAT for AIX for malloc(0).
if IS_AIX
DEFS += -D_LINUX_SOURCE_COMPAT=1
endif
# List of sources.
dist_tmux_SOURCES = \
dist_tmate_SOURCES = \
alerts.c \
arguments.c \
attributes.c \
cfg.c \
@ -76,10 +84,10 @@ dist_tmux_SOURCES = \
cmd-command-prompt.c \
cmd-confirm-before.c \
cmd-copy-mode.c \
cmd-delete-buffer.c \
cmd-detach-client.c \
cmd-display-message.c \
cmd-display-panes.c \
cmd-find.c \
cmd-find-window.c \
cmd-if-shell.c \
cmd-join-pane.c \
@ -117,6 +125,7 @@ dist_tmux_SOURCES = \
cmd-send-keys.c \
cmd-set-buffer.c \
cmd-set-environment.c \
cmd-set-hook.c \
cmd-set-option.c \
cmd-show-environment.c \
cmd-show-messages.c \
@ -135,9 +144,9 @@ dist_tmux_SOURCES = \
control-notify.c \
environ.c \
format.c \
grid-cell.c \
grid-view.c \
grid.c \
hooks.c \
input-keys.c \
input.c \
job.c \
@ -153,18 +162,26 @@ dist_tmux_SOURCES = \
options-table.c \
options.c \
paste.c \
proc.c \
resize.c \
screen-redraw.c \
screen-write.c \
screen.c \
server-client.c \
server-fn.c \
server-window.c \
server.c \
session.c \
signal.c \
status.c \
style.c \
tmate-debug.c \
tmate-ssh-client.c \
tmate-encoder.c \
tmate-decoder.c \
tmate-env.c \
tmate-msg.c \
tmate-msgpack.c \
tmate-session.c \
tmux.c \
tty-acs.c \
tty-keys.c \
@ -177,88 +194,76 @@ dist_tmux_SOURCES = \
window.c \
xmalloc.c \
xterm-keys.c
nodist_tmux_SOURCES = osdep-@PLATFORM@.c
nodist_tmate_SOURCES = osdep-@PLATFORM@.c
# Pile in all the compat/ stuff that is needed.
if NO_FORKPTY
nodist_tmux_SOURCES += compat/forkpty-@PLATFORM@.c
nodist_tmate_SOURCES += compat/forkpty-@PLATFORM@.c
endif
if NO_IMSG
nodist_tmux_SOURCES += compat/imsg.c compat/imsg-buffer.c
nodist_tmate_SOURCES += compat/imsg.c compat/imsg-buffer.c
endif
if NO_CLOSEFROM
nodist_tmux_SOURCES += compat/closefrom.c
nodist_tmate_SOURCES += compat/closefrom.c
endif
if NO_DAEMON
nodist_tmux_SOURCES += compat/daemon.c
nodist_tmate_SOURCES += compat/daemon.c
endif
if NO_SETENV
nodist_tmux_SOURCES += compat/setenv.c
nodist_tmate_SOURCES += compat/setenv.c
endif
if NO_STRLCAT
nodist_tmux_SOURCES += compat/strlcat.c
nodist_tmate_SOURCES += compat/strlcat.c
endif
if NO_STRLCPY
nodist_tmux_SOURCES += compat/strlcpy.c
nodist_tmate_SOURCES += compat/strlcpy.c
endif
if NO_ASPRINTF
nodist_tmux_SOURCES += compat/asprintf.c
nodist_tmate_SOURCES += compat/asprintf.c
endif
if NO_FGETLN
nodist_tmux_SOURCES += compat/fgetln.c
nodist_tmate_SOURCES += compat/fgetln.c
endif
if NO_FPARSELN
nodist_tmux_SOURCES += compat/fparseln.c
nodist_tmate_SOURCES += compat/fparseln.c
endif
if NO_GETOPT
nodist_tmux_SOURCES += compat/getopt.c
nodist_tmate_SOURCES += compat/getopt.c
endif
if NO_STRCASESTR
nodist_tmux_SOURCES += compat/strcasestr.c
nodist_tmate_SOURCES += compat/strcasestr.c
endif
if NO_STRSEP
nodist_tmux_SOURCES += compat/strsep.c
nodist_tmate_SOURCES += compat/strsep.c
endif
if NO_VIS
nodist_tmux_SOURCES += compat/vis.c compat/unvis.c
nodist_tmate_SOURCES += compat/vis.c compat/unvis.c
endif
if NO_STRTONUM
nodist_tmux_SOURCES += compat/strtonum.c
nodist_tmate_SOURCES += compat/strtonum.c
endif
if NO_B64_NTOP
nodist_tmux_SOURCES += compat/b64_ntop.c
nodist_tmate_SOURCES += compat/b64_ntop.c
endif
if NO_CFMAKERAW
nodist_tmux_SOURCES += compat/cfmakeraw.c
nodist_tmate_SOURCES += compat/cfmakeraw.c
endif
if NO_OPENAT
nodist_tmux_SOURCES += compat/openat.c
nodist_tmate_SOURCES += compat/openat.c
endif
if NO_REALLOCARRAY
nodist_tmate_SOURCES += compat/reallocarray.c
endif
# Install tmux.1 in the right format.
# Install tmate.1 in the right format.
install-exec-hook:
if test x@MANFORMAT@ = xmdoc; then \
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1 \
>$(srcdir)/tmux.1.mdoc; \
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmate.1 \
>$(srcdir)/tmate.1.mdoc; \
else \
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1| \
$(AWK) -f$(srcdir)/mdoc2man.awk >$(srcdir)/tmux.1.man; \
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmate.1| \
$(AWK) -f$(srcdir)/mdoc2man.awk >$(srcdir)/tmate.1.man; \
fi
$(mkdir_p) $(DESTDIR)$(mandir)/man1
$(INSTALL_DATA) $(srcdir)/tmux.1.@MANFORMAT@ \
$(DESTDIR)$(mandir)/man1/tmux.1
# Update SF web site.
upload-index.html: update-index.html
scp www/index.html www/main.css www/images/*.png \
${USER},tmux@web.sf.net:/home/groups/t/tm/tmux/htdocs
rm -f www/index.html www/images/small-*
update-index.html:
(cd www/images && \
rm -f small-* && \
for i in *.png; do \
convert "$$i" -resize 200x150 "small-$$i"; \
done \
)
sed "s/%%RELEASE%%/${RELEASE}/g" www/index.html.in >www/index.html
$(INSTALL_DATA) $(srcdir)/tmate.1.@MANFORMAT@ \
$(DESTDIR)$(mandir)/man1/tmate.1

44
README
View file

@ -4,12 +4,11 @@ tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen.
This release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they haven't been tested in a while).
This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris.
tmux depends on libevent 2.x. Download it from:
http://www.monkey.org/~provos/libevent/
http://libevent.org
To build tmux from a release tarball, do:
@ -18,14 +17,13 @@ To build tmux from a release tarball, do:
To get and build the latest from version control:
$ git clone git://git.code.sf.net/p/tmux/tmux-code tmux
$ git clone https://github.com/tmux/tmux.git
$ cd tmux
$ sh autogen.sh
$ ./configure && make
For more information see https://sourceforge.net/scm/?type=git&group_id=200378
and http://git-scm.com. Patches should be sent by email to the mailing list at
tmux-users@lists.sourceforge.net.
For more information see http://git-scm.com. Patches should be sent by email to
the mailing list at tmux-users@googlegroups.com.
For documentation on using tmux, see the tmux.1 manpage. It can be viewed from
the source tree with:
@ -35,26 +33,34 @@ the source tree with:
Some common questions are answered in the FAQ file and a more extensive (but
slightly out of date) guide is available in the OpenBSD FAQ at
http://www.openbsd.org/faq/faq7.html#tmux. A rough todo list is in the TODO
file and some example configurations and a Vim syntax file are in the examples
directory.
file and an example configuration in example_tmux.conf.
A vim(1) syntax file is available at:
https://github.com/keith/tmux.vim
https://raw.githubusercontent.com/keith/tmux.vim/master/syntax/tmux.vim
And a bash(1) completion file at:
https://github.com/przepompownia/tmux-bash-completion
For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory.
tmux mailing lists are available. Visit:
tmux mailing lists are available. For general discussion and bug reports:
https://sourceforge.net/mail/?group_id=200378
https://groups.google.com/forum/#!forum/tmux-users
And for Git commit emails:
https://groups.google.com/forum/#!forum/tmux-git
Bug reports, feature suggestions and especially code contributions are most
welcome. Please send by email to:
tmux-users@lists.sourceforge.net
tmux-users@googlegroups.com
This file and the CHANGES, FAQ and TODO files are licensed under the ISC
license. Files under examples/ remain copyright their authors unless otherwise
stated in the file but permission has been received to distribute them with
tmux. All other files have a license and copyright notice at their start.
This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under the
ISC license. All other files have a license and copyright notice at their start.
-- Nicholas Marriott <nicm@users.sf.net>
$Id$
-- Nicholas Marriott <nicholas.marriott@gmail.com>

61
README-tmux Normal file
View file

@ -0,0 +1,61 @@
Welcome to tmux!
tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen.
This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris.
tmux depends on libevent 2.x. Download it from:
http://www.monkey.org/~provos/libevent/
To build tmux from a release tarball, do:
$ ./configure && make
$ sudo make install
To get and build the latest from version control:
$ git clone https://github.com/tmux/tmux.git
$ cd tmux
$ sh autogen.sh
$ ./configure && make
For more information see http://git-scm.com. Patches should be sent by email to
the mailing list at tmux-users@googlegroups.com.
For documentation on using tmux, see the tmux.1 manpage. It can be viewed from
the source tree with:
$ nroff -mdoc tmux.1|less
Some common questions are answered in the FAQ file and a more extensive (but
slightly out of date) guide is available in the OpenBSD FAQ at
http://www.openbsd.org/faq/faq7.html#tmux. A rough todo list is in the TODO
file and some example configurations and a Vim syntax file are in the examples
directory.
For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory.
tmux mailing lists are available. For general discussion and bug reports:
https://groups.google.com/forum/#!forum/tmux-users
And for Git commit emails:
https://groups.google.com/forum/#!forum/tmux-git
Bug reports, feature suggestions and especially code contributions are most
welcome. Please send by email to:
tmux-users@googlegroups.com
This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under
the ISC license. Files under examples/ remain copyright their authors unless
otherwise stated in the file but permission has been received to distribute
them with tmux. All other files have a license and copyright notice at their
start.
-- Nicholas Marriott <nicholas.marriott@gmail.com>

12
README.md Normal file
View file

@ -0,0 +1,12 @@
tmate
=====
What is it?
-----------
Tmate is a fork of tmux. It provides an instant pairing solution.
License
-------
tmate is built on top of tmux. tmux and tmate are BSD-licensed.

73
SYNCING
View file

@ -1,10 +1,10 @@
Preamble
========
Tmux on SourceForge has two git repositories [1] "tmux-code" and "tmux-openbsd".
Tmux portable relies on repositories "tmux" and "tmux-openbsd".
Here's a description of them:
* "tmux-code" is the portable version, the one which contains code for other
* "tmux" is the portable version, the one which contains code for other
operating systems, and autotools, etc., which isn't found or needed in the
OpenBSD base system.
@ -17,9 +17,6 @@ repository will take at least that long to appear in this git repository.
(It might take longer, depending on the CVS mirror used to import the
OpenBSD code).
It is assumed that the person doing the sync has read/write access to the
tmux-code repository on SourceForge already.
If you've never used git before, git tracks meta-data about the committer
and the author, as part of a commit, hence:
@ -37,11 +34,11 @@ this information has ever been set before.
Cloning repositories
====================
This involves having both tmux-code and tmux-openbsd cloned, as in:
This involves having both tmux and tmux-openbsd cloned, as in:
% cd /some/where/useful
% git clone ssh://${USER}@git.code.sf.net/p/tmux/tmux
% git clone ssh://${USER}@git.code.sf.net/p/tmux/tmux-openbsd
% git clone https://github.com/tmux/tmux.git
% git clone https://github.com/ThomasAdam/tmux-openbsd.git
Note that you do not need additional checkouts to manage the sync -- an
existing clone of either repositories will suffice. So if you already have
@ -50,56 +47,56 @@ these checkouts existing, skip that.
Adding in git-remotes
=====================
Because the portable "tmux-code" git repository and the "tmux-openbsd"
Because the portable "tmux" git repository and the "tmux-openbsd"
repository do not inherently share any history between each other, the
history has been faked between them. This "faking of history" is something
which has to be told to git for the purposes of comparing the "tmux" and
"tmux-openbsd" repositories for syncing. To do this, we must reference the
clone of the "tmux-openbsd" repository from the "tmux-code" repository, as
clone of the "tmux-openbsd" repository from the "tmux" repository, as
shown by the following command:
% cd /path/to/tmux-code
% cd /path/to/tmux
% git remote add obsd-tmux file:///path/to/tmux-openbsd
So that now, the remote "obsd-tmux" can be used to reference branches and
commits from the "tmux-openbsd" repository, but from the context of the
portable "tmux-code" repository, which makes sense because it's the "tmux"
portable "tmux" repository, which makes sense because it's the "tmux"
repository which will have the updates applied to them.
Fetching updates
================
To ensure the latest commits from "tmux-openbsd" can be found from within
"tmux-code", we have to ensure the "master" branch from "tmux-openbsd" is
up-to-date first, and then reference that update in "tmux-code", as in:
"tmux", we have to ensure the "master" branch from "tmux-openbsd" is
up-to-date first, and then reference that update in "tmux", as in:
% cd /path/to/tmux-openbsd
% git checkout master
% git pull
Then back in "tmux-code":
Then back in "tmux":
% cd /path/to/tmux-code
% git fetch obsd-tmux-code
% cd /path/to/tmux
% git fetch obsd-tmux
Creating the necessary branches
===============================
Now that "tmux-code" can see commits and branches from "tmux-openbsd" by way
Now that "tmux" can see commits and branches from "tmux-openbsd" by way
of the remote name "obsd-tmux", we can now create the master branch from
"tmux-openbsd" in the "tmux-code" repository:
"tmux-openbsd" in the "tmux" repository:
% git checkout -b obsd-master obsd-tmux/master
Adding in the fake history points
=================================
To tie both the "master" branch from "tmux-code" and the "obsd-master"
To tie both the "master" branch from "tmux" and the "obsd-master"
branch from "tmux-openbsd" together, the fake history points added to the
"tmux-code" repository need to be added. To do this, we must add an
"tmux" repository need to be added. To do this, we must add an
additional refspec line, as in:
% cd /path/to/tmux-code
% cd /path/to/tmux
% git config --add remote.origin.fetch '+refs/replace/*:refs/replace/*'
% git fetch origin
@ -110,7 +107,7 @@ Make sure the "master" branch is checked out:
% git checkout master
The following will show commits on OpenBSD not yet synched with "tmux-code":
The following will show commits on OpenBSD not yet synched with "tmux":
% git log master..obsd-master
@ -154,30 +151,26 @@ Release tmux for next version
3. Tag with:
% git tag -a 1.X
% git tag -a 2.X
Where "1.X" is the next version.
Where "2.X" is the next version.
Push the tag out with:
% git push 1.X
% git push 2.X
4. Build the tarball with make dist. Now that it's using autoconf there
shouldn't be any weird files (such as the original and rejection files
from patch(1)) but it doesn't hurt taking a quick look at it.
4. Build the tarball with 'make dist'.
5. Split the release changes into a new file. This should be named
tmux-$VERSION-readme to make sourceforge show it automagically in specific
parts of the project page.
5. Check the tarball. If it's good, go here to select the tag just pushed:
6. Upload the tarball and the above file. Make the tarball the default
download by selecting all operating systems under the file details.
https://github.com/tmux/tmux/tags
7. Run make update-index.html upload-index.html to replace %%VERSION%%.
Click the "Add release notes", upload the tarball and add a link in the
description field to the CHANGES file.
8. Bump version in configure.ac and uncomment "found_debug=yes" to create
a debug build by default.
7. Clone the tmux.github.io repository, and change the RELEASE version in
the Makefile. Commit it, and run 'make' to replace %%VERSION%%. Push
the result out.
9. Update freshmeat.
[1] https://sourceforge.net/p/tmux/_list/git
8. Bump version in tmu/tmux.git configure.ac and uncomment "found_debug=yes" to
create a debug build by default.

86
TODO
View file

@ -1,14 +1,12 @@
- command bits and pieces:
* why doesn't command-prompt work if made read-only?
* allow multiple targets: fnmatch for -t/-c, for example detach all
clients with -t*
* add -c for new-session like new-window
* attach should take a pane and select it as well as attaching
* ' and " should be parsed the same (eg "\e" vs '\e') in config
and command prompt
* last-pane across sessions
* exact match operator for targets (or break the substring match
and require eg x* instead of just x)
* list-keys should quote output so that bindings can just be used in
config file as-is
- make command sequences more usable
* don't require space after ;
@ -19,11 +17,9 @@
* way to set socket path from config file
- format improvements:
* last bits of status_replace into formats?
* option to quote format (#{session_name:quoted})
* option to quote format (#{q:session_name})
* formats need conditions for >0 (for #P)
* some way to pad # stuff with spaces, #!2T maybe
* last window update time and format for it
* some way to pad # stuff with spaces
* formats to show if a window is linked into multiple sessions, into
multiple attached sessions, and is the active window in multiple
attached sessions?
@ -34,6 +30,9 @@
* flag to choose-* for sort order
* choose mode would be better per client than per window?
* two choices (first one then second, for swap-pane and join-pane)
* choose modes should ditch the key bindings and just have fixed keys, and
be more customized to their purpose (d to delete a buffer for choose-buffer,
a preview of buffer contents, etc)
- improve monitor-*:
* straighten out rules for multiple clients
@ -43,53 +42,45 @@
- improve mouse support:
* bind commands to mouse in different areas?
* more fine-grained options?
* commands executed when clicking on a pattern (URL)
* mouse-select-pane will screw up with !MODE_MOUSE_STANDARD (it sets
the flag on w/o checking the others before calling tty_update_mode)
* mouse can be like normal key bindings?
- {button-{1,2,3},wheel-{up,down}}-{status,pane,border} and
drag-{start,end}-{status,pane,border} plus the modifiers
- resize and copy can be special cases - once you call something
like copy-mode -M or resize-pane -M to start the drag, it tracks
mouse until you call -m to stop the drag. or just keep drags
entirely special?
- what happens with stuff that wants mouse inside? especially for
pane clicks which need to run command AND pass event through
(like mouse-select-pane). maybe just a flag to say whether it
always runs or only if pane hasn't taken mouse? or it could be
eg bind Button1Pane "select-pane -t=; send-keys -Mt='
- also need a) some way to tell commands bound to key which
window or pane the mouse key binding applies to (maybe a new
special char in target, or pass targets through formats?) b) a
way to bind repeat count to mode keys so that wheel up/down can
do multiple lines c) send-keys -M to pass a mouse event through?
- what does the mouse->KEYC_* conversion and find-the-pane bit?
server_client_handle_key?
- hooks!
- warts on current naming:
* display-time but message-fg/bg/attr
* list-* vs show-*
* split-window -> split-pane??
* split-window -> split-pane?
- better UTF-8 support:
* window names and titles
* message display
* prompt input
* multibyte key input
* searching in copy mode
- copy/paste improvements:
* incremental searching
* append to buffer
* paste w/o trailing whitespace
* command to toggle selection not to move it in copy-mode
* regex searching
* copy-pipe should have -x as well
* copy mode key bindings should just be a standard key table, using
something like "copy-mode start-selection"; it could use
command-prompt for search, goto, etc:
bind -Temacs command-prompt -p'Search Up: ' 'copy-mode search-up %%'
it'd need a separate lookup, because modes are per-pane, perhaps a
table() cb to give the table name ("vi" or "emacs"). anything in the
table fires the command, anything not in the table is injected as a
key
* searching in copy mode should unwrap lines, so if you seach for "foobar"
then it should be found even if it is now "foo\nbar" (if the WRAP flag
is set on the line)
* {} to go to next/previous blank line in copy mode
- layout stuff
* way to tag a layout as a number/name
* maybe keep last layout + size around and if size reverts just put it
back
back
* revamp layouts: they are too complicated, should be more closely
integrated, should support hints, layout sets should just be a
special case of custom layouts, and we should support panes that are
@ -98,15 +89,14 @@
* way to set hints/limits about pane size for resizing
* panning over window (window larger than visible)
* a mode where one application can cross two panes (ie x|y, width =
COLUMNS/2 but height = ROWS * 2)
* general key to space cells out evenly (horiz or vert) within their
parent cell (could replace even-vert/even-horiz layouts)
COLUMNS/2 but height = ROWS * 2)
* general key to space cells out evenly (horiz or vert) within their
parent cell (could replace even-vert/even-horiz layouts)
* separate active panes for different clients
- terminfo bits
* use a better termcap internally instead of screen, perhaps xterm
* use screen-256color when started on 256 colour terminal?
* need a tmux terminfo entry to document the extensions we are using in
upstream terminfo
- code cleanup
* instead of separate window and session options, just one master
@ -125,17 +115,13 @@
know about the client, notably:
- is this the config file? (cmdq->c == NULL)
- is this a command client? (cmdq->c != NULL &&
cmdq->c->session == NULL)
cmdq->c->session == NULL)
- is this a control client?
- can i do stdin or stdout to this client?
or even guarantee that cmdq->c != NULL and provide a better way to
tell when in the config file - then we use cmdq->c if we need a
client w/o a session else cmd_current_client
* optimize pane redraws, 20120318184853.GK10965@yelena.nicm.ath.cx
* cmd_find_* could be much simpler - parse everything the same, only
difference is what to choose when not given a ":" or "." (such as a
plain "0" could be session, window or pane). So just cmd_find_target
with a type (session, window, or pane)..
- miscellaneous
* way to keep a job running just read its last line of output for #()
@ -146,10 +132,8 @@
comes from config for new sessions and windows. likewise, panes and
jobs and run-shell and lock command all start with slightly different
environments
* multiline status line?
* bind commands to key sequences -- make it so ALL keys go through a
table, first an implicit table in which C-b is the only default
binding to a command that says "next key from $othertable" and so
on. means -n can go away as well
* multiline status line? separate command prompt and status line?
* customizable command aliases
* any remaining clients in wait-for should be woken when server exits
* automatic pane logging
* BCE? We are halfway there (output side is done for pane backgrounds),
just need to change how screen/grid handles erase

294
alerts.c Normal file
View file

@ -0,0 +1,294 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF 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 <event.h>
#include "tmux.h"
int alerts_fired;
void alerts_timer(int, short, void *);
int alerts_enabled(struct window *, int);
void alerts_callback(int, short, void *);
void alerts_reset(struct window *);
void alerts_run_hook(struct session *, struct winlink *, int);
int alerts_check_all(struct session *, struct winlink *);
int alerts_check_bell(struct session *, struct winlink *);
int alerts_check_activity(struct session *, struct winlink *);
int alerts_check_silence(struct session *, struct winlink *);
void alerts_ring_bell(struct session *);
void
alerts_timer(__unused int fd, __unused short events, void *arg)
{
struct window *w = arg;
log_debug("@%u alerts timer expired", w->id);
alerts_reset(w);
alerts_queue(w, WINDOW_SILENCE);
}
void
alerts_callback(__unused int fd, __unused short events, __unused void *arg)
{
struct window *w;
struct session *s;
struct winlink *wl;
int flags, alerts;
RB_FOREACH(w, windows, &windows) {
RB_FOREACH(s, sessions, &sessions) {
RB_FOREACH(wl, winlinks, &s->windows) {
if (wl->window != w)
continue;
flags = w->flags;
alerts = alerts_check_all(s, wl);
log_debug("%s:%d @%u alerts check, alerts %#x, "
"flags %#x", s->name, wl->idx, w->id,
alerts, flags);
}
}
}
alerts_fired = 0;
}
void
alerts_run_hook(struct session *s, struct winlink *wl, int flags)
{
struct cmd_find_state fs;
if (cmd_find_from_winlink(&fs, s, wl) != 0)
return;
if (flags & WINDOW_BELL)
hooks_run(s->hooks, NULL, &fs, "alert-bell");
if (flags & WINDOW_SILENCE)
hooks_run(s->hooks, NULL, &fs, "alert-silence");
if (flags & WINDOW_ACTIVITY)
hooks_run(s->hooks, NULL, &fs, "alert-activity");
}
int
alerts_check_all(struct session *s, struct winlink *wl)
{
int alerts;
alerts = alerts_check_bell(s, wl);
alerts |= alerts_check_activity(s, wl);
alerts |= alerts_check_silence(s, wl);
if (alerts != 0) {
alerts_run_hook(s, wl, alerts);
server_status_session(s);
}
return (alerts);
}
void
alerts_check_session(struct session *s)
{
struct winlink *wl;
RB_FOREACH(wl, winlinks, &s->windows)
alerts_check_all(s, wl);
}
int
alerts_enabled(struct window *w, int flags)
{
if (flags & WINDOW_BELL)
return (1);
if (flags & WINDOW_ACTIVITY) {
if (options_get_number(w->options, "monitor-activity"))
return (1);
}
if (flags & WINDOW_SILENCE) {
if (options_get_number(w->options, "monitor-silence") != 0)
return (1);
}
return (0);
}
void
alerts_reset_all(void)
{
struct window *w;
RB_FOREACH(w, windows, &windows)
alerts_reset(w);
}
void
alerts_reset(struct window *w)
{
struct timeval tv;
w->flags &= ~WINDOW_SILENCE;
event_del(&w->alerts_timer);
timerclear(&tv);
tv.tv_sec = options_get_number(w->options, "monitor-silence");
log_debug("@%u alerts timer reset %u", w->id, (u_int)tv.tv_sec);
if (tv.tv_sec != 0)
event_add(&w->alerts_timer, &tv);
}
void
alerts_queue(struct window *w, int flags)
{
if (w->flags & WINDOW_ACTIVITY)
alerts_reset(w);
if (!event_initialized(&w->alerts_timer))
evtimer_set(&w->alerts_timer, alerts_timer, w);
if (!alerts_fired) {
w->flags |= flags;
log_debug("@%u alerts flags added %#x", w->id, flags);
if (alerts_enabled(w, flags)) {
log_debug("alerts check queued (by @%u)", w->id);
event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL);
alerts_fired = 1;
}
}
}
int
alerts_check_bell(struct session *s, struct winlink *wl)
{
struct client *c;
struct window *w = wl->window;
int action, visual;
if (!(w->flags & WINDOW_BELL))
return (0);
if (s->curw != wl) {
wl->flags |= WINLINK_BELL;
w->flags &= ~WINDOW_BELL;
}
if (s->curw->window == w)
w->flags &= ~WINDOW_BELL;
action = options_get_number(s->options, "bell-action");
if (action == BELL_NONE)
return (0);
visual = options_get_number(s->options, "visual-bell");
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s || c->flags & CLIENT_CONTROL)
continue;
if (!visual) {
if ((action == BELL_CURRENT &&
c->session->curw->window == w) ||
(action == BELL_OTHER &&
c->session->curw->window != w) ||
action == BELL_ANY)
tty_putcode(&c->tty, TTYC_BEL);
continue;
}
if (action == BELL_CURRENT && c->session->curw->window == w)
status_message_set(c, "Bell in current window");
else if (action == BELL_ANY || (action == BELL_OTHER &&
c->session->curw->window != w))
status_message_set(c, "Bell in window %d", wl->idx);
}
return (WINDOW_BELL);
}
int
alerts_check_activity(struct session *s, struct winlink *wl)
{
struct client *c;
struct window *w = wl->window;
if (s->curw->window == w)
w->flags &= ~WINDOW_ACTIVITY;
if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)
return (0);
if (s->curw == wl)
return (0);
if (!options_get_number(w->options, "monitor-activity"))
return (0);
if (options_get_number(s->options, "bell-on-alert"))
alerts_ring_bell(s);
wl->flags |= WINLINK_ACTIVITY;
if (options_get_number(s->options, "visual-activity")) {
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
status_message_set(c, "Activity in window %d", wl->idx);
}
}
return (WINDOW_ACTIVITY);
}
int
alerts_check_silence(struct session *s, struct winlink *wl)
{
struct client *c;
struct window *w = wl->window;
if (s->curw->window == w)
w->flags &= ~WINDOW_SILENCE;
if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
return (0);
if (s->curw == wl)
return (0);
if (options_get_number(w->options, "monitor-silence") == 0)
return (0);
if (options_get_number(s->options, "bell-on-alert"))
alerts_ring_bell(s);
wl->flags |= WINLINK_SILENCE;
if (options_get_number(s->options, "visual-silence")) {
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
status_message_set(c, "Silence in window %d", wl->idx);
}
}
return (WINDOW_SILENCE);
}
void
alerts_ring_bell(struct session *s)
{
struct client *c;
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == s && !(c->flags & CLIENT_CONTROL))
tty_putcode(&c->tty, TTYC_BEL);
}
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -18,7 +18,6 @@
#include <sys/types.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -29,6 +28,12 @@
* Manipulate command arguments.
*/
struct args_entry {
u_char flag;
char *value;
RB_ENTRY(args_entry) entry;
};
struct args_entry *args_find(struct args *, u_char);
RB_GENERATE(args_tree, args_entry, entry, args_cmp);
@ -122,77 +127,73 @@ args_free(struct args *args)
free(args);
}
/* Print a set of arguments. */
size_t
args_print(struct args *args, char *buf, size_t len)
/* Add to string. */
static void printflike(3, 4)
args_print_add(char **buf, size_t *len, const char *fmt, ...)
{
size_t off, used;
va_list ap;
char *s;
size_t slen;
va_start(ap, fmt);
slen = xvasprintf(&s, fmt, ap);
va_end(ap);
*len += slen;
*buf = xrealloc(*buf, *len);
strlcat(*buf, s, *len);
free(s);
}
/* Print a set of arguments. */
char *
args_print(struct args *args)
{
size_t len;
char *buf;
int i;
const char *quotes;
struct args_entry *entry;
/* There must be at least one byte at the start. */
if (len == 0)
return (0);
off = 0;
len = 1;
buf = xcalloc(1, len);
/* Process the flags first. */
buf[off++] = '-';
RB_FOREACH(entry, args_tree, &args->tree) {
if (entry->value != NULL)
continue;
if (off == len - 1) {
buf[off] = '\0';
return (len);
}
buf[off++] = entry->flag;
buf[off] = '\0';
if (*buf == '\0')
args_print_add(&buf, &len, "-");
args_print_add(&buf, &len, "%c", entry->flag);
}
if (off == 1)
buf[--off] = '\0';
/* Then the flags with arguments. */
RB_FOREACH(entry, args_tree, &args->tree) {
if (entry->value == NULL)
continue;
if (off >= len) {
/* snprintf will have zero terminated. */
return (len);
}
if (strchr(entry->value, ' ') != NULL)
quotes = "\"";
if (*buf != '\0')
args_print_add(&buf, &len, " -%c ", entry->flag);
else
quotes = "";
used = xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
off != 0 ? " " : "", entry->flag, quotes, entry->value,
quotes);
if (used > len - off)
used = len - off;
off += used;
args_print_add(&buf, &len, "-%c ", entry->flag);
if (strchr(entry->value, ' ') != NULL)
args_print_add(&buf, &len, "\"%s\"", entry->value);
else
args_print_add(&buf, &len, "%s", entry->value);
}
/* And finally the argument vector. */
for (i = 0; i < args->argc; i++) {
if (off >= len) {
/* snprintf will have zero terminated. */
return (len);
}
if (*buf != '\0')
args_print_add(&buf, &len, " ");
if (strchr(args->argv[i], ' ') != NULL)
quotes = "\"";
args_print_add(&buf, &len, "\"%s\"", args->argv[i]);
else
quotes = "";
used = xsnprintf(buf + off, len - off, "%s%s%s%s",
off != 0 ? " " : "", quotes, args->argv[i], quotes);
if (used > len - off)
used = len - off;
off += used;
args_print_add(&buf, &len, "%s", args->argv[i]);
}
return (off);
return (buf);
}
/* Return if an argument is present. */

View file

@ -1,7 +1,7 @@
/* $Id$ */
/* $OpenBSD$ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2006 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above

View file

@ -1,5 +1,4 @@
#!/bin/sh
# $Id$
if [ "x$(uname)" = "xOpenBSD" ]; then
[ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.10

33
build_static_release.sh Executable file
View file

@ -0,0 +1,33 @@
#!/bin/bash
set -eux
# This is invoked by .travis.yml
VERSION=$1
PLATFORM=$2
SRC_VERSION=`cat configure.ac | grep AC_INIT | sed -E 's/^AC_INIT\(tmate, (.+)\)$/\1/'`
if [ $SRC_VERSION != $VERSION ]; then
echo "Version mismatch: $SRC_VERSION != $VERSION"
exit 1
fi
RELEASE_NAME=tmate-$VERSION-static-linux-$PLATFORM
echo "Building $RELEASE_NAME"
docker build . --tag local-$PLATFORM/tmate-build --build-arg PLATFORM=$PLATFORM
mkdir -p releases
cd releases
rm -rf $RELEASE_NAME
mkdir -p $RELEASE_NAME
docker run --rm local-$PLATFORM/tmate-build cat /build/tmate > $RELEASE_NAME/tmate
chmod +x $RELEASE_NAME/tmate
tar -cf - $RELEASE_NAME | xz > tmate-$VERSION-static-linux-$PLATFORM.tar.xz
rm -rf $RELEASE_NAME-symbols
mkdir -p $RELEASE_NAME-symbols
docker run --rm local-$PLATFORM/tmate-build cat /build/tmate.symbols > $RELEASE_NAME-symbols/tmate.symbols
tar -cf - $RELEASE_NAME-symbols | xz > dbg-symbols-tmate-$VERSION-static-linux-$PLATFORM.tar.xz

137
cfg.c
View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -23,14 +23,66 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
#include "tmate.h"
struct cmd_q *cfg_cmd_q;
int cfg_finished;
int cfg_references;
ARRAY_DECL (, char *) cfg_causes = ARRAY_INITIALIZER;
struct client *cfg_client;
char *cfg_file;
#ifdef TMATE
char *tmate_cfg_file;
#endif
struct cmd_q *cfg_cmd_q;
int cfg_finished;
int cfg_references;
char **cfg_causes;
u_int cfg_ncauses;
struct client *cfg_client;
void cfg_default_done(struct cmd_q *);
void
set_cfg_file(const char *path)
{
free(cfg_file);
cfg_file = xstrdup(path);
}
void
start_cfg(void)
{
char *cause = NULL;
const char *home;
cfg_cmd_q = cmdq_new(NULL);
cfg_cmd_q->emptyfn = cfg_default_done;
cfg_finished = 0;
cfg_references = 1;
cfg_client = TAILQ_FIRST(&clients);
if (cfg_client != NULL)
cfg_client->references++;
if (access(TMUX_CONF, R_OK) == 0) {
if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1)
cfg_add_cause("%s: %s", TMUX_CONF, cause);
} else if (errno != ENOENT)
cfg_add_cause("%s: %s", TMUX_CONF, strerror(errno));
if (cfg_file == NULL && (home = find_home()) != NULL) {
xasprintf(&cfg_file, "%s/.tmate.conf", home);
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
free(cfg_file);
cfg_file = NULL;
}
}
if (cfg_file != NULL && load_cfg(cfg_file, cfg_cmd_q, &cause) == -1)
cfg_add_cause("%s: %s", cfg_file, cause);
free(cause);
cmdq_continue(cfg_cmd_q);
}
int
load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
@ -49,7 +101,7 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
}
found = 0;
while ((buf = fparseln(f, NULL, &line, delim, 0))) {
while ((buf = fparseln(f, NULL, &line, delim, 0)) != NULL) {
log_debug("%s: %s", path, buf);
/* Skip empty lines. */
@ -74,7 +126,7 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
if (cmdlist == NULL)
continue;
cmdq_append(cmdq, cmdlist);
cmdq_append(cmdq, cmdlist, NULL);
cmd_list_free(cmdlist);
found++;
}
@ -83,13 +135,38 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
return (found);
}
static void print_cfg_errors(void)
{
u_int i;
for (i = 0; i < cfg_ncauses; i++) {
tmate_info("%s", cfg_causes[i]);
free(cfg_causes[i]);
}
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
}
void
cfg_default_done(unused struct cmd_q *cmdq)
cfg_default_done(__unused struct cmd_q *cmdq)
{
if (--cfg_references != 0)
return;
cfg_finished = 1;
#ifdef TMATE
/* We do it this late, this way, CLI options take precedence over cfg file */
tmate_load_cli_options();
tmate_session_start();
if (tmate_foreground && cfg_ncauses) {
print_cfg_errors();
exit(1);
}
#endif
if (!RB_EMPTY(&sessions))
cfg_show_causes(RB_MIN(sessions, &sessions));
@ -106,55 +183,59 @@ cfg_default_done(unused struct cmd_q *cmdq)
*/
if (!TAILQ_EMPTY(&cfg_client->cmdq->queue))
cmdq_continue(cfg_client->cmdq);
cfg_client->references--;
server_client_unref(cfg_client);
cfg_client = NULL;
}
}
void
cfg_add_cause(const char* fmt, ...)
cfg_add_cause(const char *fmt, ...)
{
va_list ap;
char* msg;
va_list ap;
char *msg;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end (ap);
va_end(ap);
ARRAY_ADD(&cfg_causes, msg);
cfg_ncauses++;
cfg_causes = xreallocarray(cfg_causes, cfg_ncauses, sizeof *cfg_causes);
cfg_causes[cfg_ncauses - 1] = msg;
}
void
cfg_print_causes(struct cmd_q *cmdq)
{
char *cause;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
cmdq_print(cmdq, "%s", cause);
free(cause);
for (i = 0; i < cfg_ncauses; i++) {
cmdq_print(cmdq, "%s", cfg_causes[i]);
free(cfg_causes[i]);
}
ARRAY_FREE(&cfg_causes);
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
}
void
cfg_show_causes(struct session *s)
{
struct window_pane *wp;
char *cause;
u_int i;
if (s == NULL || ARRAY_EMPTY(&cfg_causes))
if (s == NULL || cfg_ncauses == 0)
return;
wp = s->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
window_copy_add(wp, "%s", cause);
free(cause);
for (i = 0; i < cfg_ncauses; i++) {
window_copy_add(wp, "%s", cfg_causes[i]);
free(cfg_causes[i]);
}
ARRAY_FREE(&cfg_causes);
free(cfg_causes);
cfg_causes = NULL;
cfg_ncauses = 0;
}

794
client.c

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -33,52 +33,42 @@
enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach",
"c:drt:", 0, 0,
"[-dr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER,
cmd_attach_session_exec
.name = "attach-session",
.alias = "attach",
.args = { "c:dErt:", 0, 0 },
.usage = "[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION_WITHPANE,
.flags = CMD_STARTSERVER,
.exec = cmd_attach_session_exec
};
enum cmd_retval
cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
const char *cflag)
cmd_attach_session(struct cmd_q *cmdq, int dflag, int rflag, const char *cflag,
int Eflag)
{
struct session *s;
struct client *c;
struct winlink *wl = NULL;
struct window *w = NULL;
struct window_pane *wp = NULL;
struct session *s = cmdq->state.tflag.s;
struct client *c = cmdq->client, *c_loop;
struct winlink *wl = cmdq->state.tflag.wl;
struct window_pane *wp = cmdq->state.tflag.wp;
const char *update;
char *cause;
u_int i;
int fd;
char *cause, *cwd;
struct format_tree *ft;
char *cp;
if (RB_EMPTY(&sessions)) {
cmdq_error(cmdq, "no sessions");
return (CMD_RETURN_ERROR);
}
if (tflag == NULL) {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
} else {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
w = cmd_lookup_windowid(tflag);
if (w == NULL && (wp = cmd_lookup_paneid(tflag)) != NULL)
w = wp->window;
if (w != NULL)
wl = winlink_find_by_window(&s->windows, w);
}
if (cmdq->client == NULL)
if (c == NULL)
return (CMD_RETURN_NORMAL);
if (server_client_check_nested(c)) {
cmdq_error(cmdq, "sessions should be nested with care, "
"unset $TMUX to force");
return (CMD_RETURN_ERROR);
}
if (wl != NULL) {
if (wp != NULL)
@ -86,93 +76,79 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
session_set_current(s, wl);
}
if (cmdq->client->session != NULL) {
if (cflag != NULL) {
ft = format_create(cmdq, 0);
format_defaults(ft, c, s, wl, wp);
cwd = format_expand(ft, cflag);
format_free(ft);
free((void *)s->cwd);
s->cwd = cwd;
}
if (c->session != NULL) {
if (dflag) {
/*
* 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)
TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue;
if (c == cmdq->client)
continue;
server_write_client(c, MSG_DETACH,
c->session->name,
strlen(c->session->name) + 1);
server_client_detach(c_loop, MSG_DETACH);
}
}
if (cflag != NULL) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
NULL, NULL);
cp = format_expand(ft, cflag);
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
close(s->cwd);
s->cwd = fd;
if (!Eflag) {
update = options_get_string(s->options,
"update-environment");
environ_update(update, c->environ, s->environ);
}
cmdq->client->session = s;
notify_attached_session_changed(cmdq->client);
session_update_activity(s);
server_redraw_client(cmdq->client);
c->session = s;
server_client_set_key_table(c, NULL);
status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
} else {
if (server_client_open(cmdq->client, &cause) != 0) {
if (server_client_open(c, &cause) != 0) {
cmdq_error(cmdq, "open terminal failed: %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
if (cflag != NULL) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
NULL, NULL);
cp = format_expand(ft, cflag);
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
close(s->cwd);
s->cwd = fd;
}
if (rflag)
cmdq->client->flags |= CLIENT_READONLY;
c->flags |= CLIENT_READONLY;
if (dflag) {
server_write_session(s, MSG_DETACH, s->name,
strlen(s->name) + 1);
TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue;
server_client_detach(c_loop, MSG_DETACH);
}
}
update = options_get_string(&s->options, "update-environment");
environ_update(update, &cmdq->client->environ, &s->environ);
if (!Eflag) {
update = options_get_string(s->options,
"update-environment");
environ_update(update, c->environ, s->environ);
}
cmdq->client->session = s;
notify_attached_session_changed(cmdq->client);
session_update_activity(s);
server_redraw_client(cmdq->client);
c->session = s;
server_client_set_key_table(c, NULL);
status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
server_write_ready(cmdq->client);
if (~c->flags & CLIENT_CONTROL)
proc_send(c->peer, MSG_READY, -1, NULL, 0);
hooks_run(c->session->hooks, c, NULL, "client-attached");
cmdq->client_exit = 0;
}
recalculate_sizes();
alerts_check_session(s);
server_update_socket();
return (CMD_RETURN_NORMAL);
@ -183,6 +159,6 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
return (cmd_attach_session(cmdq, args_get(args, 't'),
args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c')));
return (cmd_attach_session(cmdq, args_has(args, 'd'),
args_has(args, 'r'), args_get(args, 'c'), args_has(args, 'E')));
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,14 +29,19 @@
enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_bind_key_mode_table(struct cmd *, struct cmd_q *, int);
enum cmd_retval cmd_bind_key_mode_table(struct cmd *, struct cmd_q *,
key_code);
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
"cnrt:", 1, -1,
"[-cnr] [-t mode-table] key command [arguments]",
0,
cmd_bind_key_exec
.name = "bind-key",
.alias = "bind",
.args = { "cnrt:T:", 1, -1 },
.usage = "[-cnr] [-t mode-table] [-T key-table] key command "
"[arguments]",
.flags = 0,
.exec = cmd_bind_key_exec
};
enum cmd_retval
@ -45,7 +50,8 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args;
char *cause;
struct cmd_list *cmdlist;
int key;
key_code key;
const char *tablename;
if (args_has(args, 't')) {
if (args->argc != 2 && args->argc != 3) {
@ -60,7 +66,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
}
key = key_string_lookup_string(args->argv[0]);
if (key == KEYC_NONE) {
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
@ -68,6 +74,13 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
if (args_has(args, 't'))
return (cmd_bind_key_mode_table(self, cmdq, key));
if (args_has(args, 'T'))
tablename = args_get(args, 'T');
else if (args_has(args, 'n'))
tablename = "root";
else
tablename = "prefix";
cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0,
&cause);
if (cmdlist == NULL) {
@ -76,14 +89,12 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
if (!args_has(args, 'n'))
key |= KEYC_PREFIX;
key_bindings_add(key, args_has(args, 'r'), cmdlist);
key_bindings_add(tablename, key, args_has(args, 'r'), cmdlist);
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
{
struct args *args = self->args;
const char *tablename;
@ -104,18 +115,34 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
return (CMD_RETURN_ERROR);
}
if (cmd != MODEKEYCOPY_COPYPIPE) {
if (args->argc != 2) {
cmdq_error(cmdq, "no argument allowed");
return (CMD_RETURN_ERROR);
switch (cmd) {
case MODEKEYCOPY_APPENDSELECTION:
case MODEKEYCOPY_COPYSELECTION:
case MODEKEYCOPY_STARTNAMEDBUFFER:
if (args->argc == 2)
arg = NULL;
else {
arg = args->argv[2];
if (strcmp(arg, "-x") != 0) {
cmdq_error(cmdq, "unknown argument");
return (CMD_RETURN_ERROR);
}
}
arg = NULL;
} else {
break;
case MODEKEYCOPY_COPYPIPE:
if (args->argc != 3) {
cmdq_error(cmdq, "no argument given");
return (CMD_RETURN_ERROR);
}
arg = args->argv[2];
break;
default:
if (args->argc != 2) {
cmdq_error(cmdq, "no argument allowed");
return (CMD_RETURN_ERROR);
}
arg = NULL;
break;
}
mtmp.key = key;

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -31,65 +31,82 @@
enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp",
"dPF:t:", 0, 0,
"[-dP] [-F format] " CMD_TARGET_PANE_USAGE,
0,
cmd_break_pane_exec
.name = "break-pane",
.alias = "breakp",
.args = { "dPF:s:t:", 0, 0 },
.usage = "[-dP] [-F format] [-s src-pane] [-t dst-window]",
.sflag = CMD_PANE,
.tflag = CMD_WINDOW_INDEX,
.flags = 0,
.exec = cmd_break_pane_exec
};
enum cmd_retval
cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
#ifdef TMATE
cmdq_error(cmdq, "break pane is not supported with tmate");
return (CMD_RETURN_ERROR);
#else
struct args *args = self->args;
struct winlink *wl;
struct session *s;
struct window_pane *wp;
struct window *w;
struct winlink *wl = cmdq->state.sflag.wl;
struct session *src_s = cmdq->state.sflag.s;
struct session *dst_s = cmdq->state.tflag.s;
struct window_pane *wp = cmdq->state.sflag.wp;
struct window *w = wl->window;
char *name;
char *cause;
int base_idx;
int idx = cmdq->state.tflag.idx;
struct format_tree *ft;
const char *template;
char *cp;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
if (window_count_panes(wl->window) == 1) {
cmdq_error(cmdq, "can't break with only one pane");
if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
cmdq_error(cmdq, "index %d already in use", idx);
return (CMD_RETURN_ERROR);
}
w = wl->window;
if (window_count_panes(w) == 1) {
cmdq_error(cmdq, "can't break with only one pane");
return (CMD_RETURN_ERROR);
}
server_unzoom_window(w);
TAILQ_REMOVE(&w->panes, wp, entry);
window_lost_pane(w, wp);
layout_close_pane(wp);
w = wp->window = window_create1(s->sx, s->sy);
w = wp->window = window_create1(dst_s->sx, dst_s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
name = default_window_name(w);
window_set_name(w, name);
free(name);
layout_init(w, wp);
wp->flags |= PANE_CHANGED;
base_idx = options_get_number(&s->options, "base-index");
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
if (idx == -1)
idx = -1 - options_get_number(dst_s->options, "base-index");
wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
if (!args_has(self->args, 'd'))
session_select(s, wl->idx);
session_select(dst_s, wl->idx);
server_redraw_session(s);
server_status_session_group(s);
server_redraw_session(src_s);
if (src_s != dst_s)
server_redraw_session(dst_s);
server_status_session_group(src_s);
if (src_s != dst_s)
server_status_session_group(dst_s);
if (args_has(args, 'P')) {
if ((template = args_get(args, 'F')) == NULL)
template = BREAK_PANE_TEMPLATE;
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl, wp);
ft = format_create(cmdq, 0);
format_defaults(ft, cmdq->state.c, dst_s, wl, wp);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);
@ -98,4 +115,5 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft);
}
return (CMD_RETURN_NORMAL);
#endif
}

View file

@ -36,12 +36,17 @@ char *cmd_capture_pane_history(struct args *, struct cmd_q *,
struct window_pane *, size_t *);
const struct cmd_entry cmd_capture_pane_entry = {
"capture-pane", "capturep",
"ab:CeE:JpPqS:t:", 0, 0,
"[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] [-S start-line]"
CMD_TARGET_PANE_USAGE,
0,
cmd_capture_pane_exec
.name = "capture-pane",
.alias = "capturep",
.args = { "ab:CeE:JpPqS:t:", 0, 0 },
.usage = "[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] "
"[-S start-line]" CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_capture_pane_exec
};
char *
@ -57,15 +62,17 @@ char *
cmd_capture_pane_pending(struct args *args, struct window_pane *wp,
size_t *len)
{
char *buf, *line, tmp[5];
size_t linelen;
u_int i;
struct evbuffer *pending;
char *buf, *line, tmp[5];
size_t linelen;
u_int i;
if (wp->ictx.since_ground == NULL)
pending = input_pending(wp);
if (pending == NULL)
return (xstrdup(""));
line = EVBUFFER_DATA(wp->ictx.since_ground);
linelen = EVBUFFER_LENGTH(wp->ictx.since_ground);
line = EVBUFFER_DATA(pending);
linelen = EVBUFFER_LENGTH(pending);
buf = xstrdup("");
if (args_has(args, 'C')) {
@ -74,7 +81,7 @@ cmd_capture_pane_pending(struct args *args, struct window_pane *wp,
tmp[0] = line[i];
tmp[1] = '\0';
} else
xsnprintf(tmp, sizeof tmp, "\\%03o", line[i]);
xsnprintf(tmp, sizeof tmp, "\\%03hho", line[i]);
buf = cmd_capture_pane_append(buf, len, tmp,
strlen(tmp));
}
@ -173,14 +180,11 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct window_pane *wp;
struct window_pane *wp = cmdq->state.tflag.wp;
char *buf, *cause;
const char *bufname;
size_t len;
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
len = 0;
if (args_has(args, 'P'))
buf = cmd_capture_pane_pending(args, wp, &len);
@ -194,22 +198,23 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
if (c == NULL ||
(c->session != NULL && !(c->flags & CLIENT_CONTROL))) {
cmdq_error(cmdq, "can't write to stdout");
free(buf);
return (CMD_RETURN_ERROR);
}
evbuffer_add(c->stdout_data, buf, len);
free(buf);
if (args_has(args, 'P') && len > 0)
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
server_client_push_stdout(c);
} else {
bufname = NULL;
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
if (paste_set(buf, len, bufname, &cause) != 0) {
cmdq_error(cmdq, "%s", cause);
free(buf);
free(cause);
free(buf);
return (CMD_RETURN_ERROR);
}
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -33,27 +33,31 @@
enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_choose_buffer_entry = {
"choose-buffer", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0,
cmd_choose_buffer_exec
.name = "choose-buffer",
.alias = NULL,
.args = { "F:t:", 0, 1 },
.usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_buffer_exec
};
enum cmd_retval
cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct client *c = cmdq->state.c;
struct winlink *wl = cmdq->state.tflag.wl;
struct window_choose_data *cdata;
struct winlink *wl;
struct paste_buffer *pb;
char *action, *action_data;
const char *template;
u_int idx;
int utf8flag;
if ((c = cmd_current_client(cmdq)) == NULL) {
if (c == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
@ -61,11 +65,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
if ((template = args_get(args, 'F')) == NULL)
template = CHOOSE_BUFFER_TEMPLATE;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
utf8flag = options_get_number(&wl->window->options, "utf8");
if (paste_get_top() == NULL)
if (paste_get_top(NULL) == NULL)
return (CMD_RETURN_NORMAL);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
@ -83,9 +83,9 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
cdata->idx = idx;
cdata->ft_template = xstrdup(template);
format_defaults_paste_buffer(cdata->ft, pb, utf8flag);
format_defaults_paste_buffer(cdata->ft, pb);
xasprintf(&action_data, "%s", pb->name);
xasprintf(&action_data, "%s", paste_buffer_name(pb));
cdata->command = cmd_template_replace(action, action_data, 1);
free(action_data);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -31,18 +31,23 @@
"#{client_tty}: #{session_name} " \
"[#{client_width}x#{client_height} #{client_termname}]" \
"#{?client_utf8, (utf8),}#{?client_readonly, (ro),} " \
"(last used #{client_activity_string})"
"(last used #{t:client_activity})"
enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_q *);
void cmd_choose_client_callback(struct window_choose_data *);
const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0,
cmd_choose_client_exec
.name = "choose-client",
.alias = NULL,
.args = { "F:t:", 0, 1 },
.usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_client_exec
};
struct cmd_choose_client_data {
@ -53,22 +58,19 @@ enum cmd_retval
cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct client *c = cmdq->state.c;
struct client *c1;
struct window_choose_data *cdata;
struct winlink *wl;
struct winlink *wl = cmdq->state.tflag.wl;
const char *template;
char *action;
u_int i, idx, cur;
u_int idx, cur;
if ((c = cmd_current_client(cmdq)) == NULL) {
if (c == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (CMD_RETURN_NORMAL);
@ -81,24 +83,24 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
action = xstrdup("detach-client -t '%%'");
cur = idx = 0;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c1 = ARRAY_ITEM(&clients, i);
if (c1 == NULL || c1->session == NULL || c1->tty.path == NULL)
TAILQ_FOREACH(c1, &clients, entry) {
if (c1->session == NULL || c1->tty.path == NULL)
continue;
if (c1 == cmdq->client)
cur = idx;
idx++;
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->idx = i;
cdata->idx = idx;
cdata->ft_template = xstrdup(template);
format_add(cdata->ft, "line", "%u", i);
format_add(cdata->ft, "line", "%u", idx);
format_defaults(cdata->ft, c1, NULL, NULL, NULL);
cdata->command = cmd_template_replace(action, c1->tty.path, 1);
window_choose_add(wl->window->active, cdata);
idx++;
}
free(action);
@ -112,15 +114,19 @@ void
cmd_choose_client_callback(struct window_choose_data *cdata)
{
struct client *c;
u_int idx;
if (cdata == NULL)
return;
if (cdata->start_client->flags & CLIENT_DEAD)
return;
if (cdata->idx > ARRAY_LENGTH(&clients) - 1)
return;
c = ARRAY_ITEM(&clients, cdata->idx);
idx = 0;
TAILQ_FOREACH(c, &clients, entry) {
if (idx == cdata->idx)
break;
idx++;
}
if (c == NULL || c->session == NULL)
return;

View file

@ -44,37 +44,52 @@
enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_choose_tree_entry = {
"choose-tree", NULL,
"S:W:swub:c:t:", 0, 1,
"[-suw] [-b session-template] [-c window template] [-S format] " \
"[-W format] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_choose_tree_exec
.name = "choose-tree",
.alias = NULL,
.args = { "S:W:swub:c:t:", 0, 1 },
.usage = "[-suw] [-b session-template] [-c window template] "
"[-S format] [-W format] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_tree_exec
};
const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
0,
cmd_choose_tree_exec
.name = "choose-session",
.alias = NULL,
.args = { "F:t:", 0, 1 },
.usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_tree_exec
};
const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL,
"F:t:", 0, 1,
CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
0,
cmd_choose_tree_exec
.name = "choose-window",
.alias = NULL,
.args = { "F:t:", 0, 1 },
.usage = CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_choose_tree_exec
};
enum cmd_retval
cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl, *wm;
struct session *s, *s2;
struct client *c;
struct client *c = cmdq->state.c;
struct winlink *wl = cmdq->state.tflag.wl, *wm;
struct session *s = cmdq->state.tflag.s, *s2;
struct window_choose_data *wcd = NULL;
const char *ses_template, *win_template;
char *final_win_action, *cur_win_template;
@ -87,14 +102,11 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq)
ses_template = win_template = NULL;
ses_action = win_action = NULL;
if ((c = cmd_current_client(cmdq)) == NULL) {
if (c == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (CMD_RETURN_NORMAL);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,26 +27,29 @@
enum cmd_retval cmd_clear_history_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
0,
cmd_clear_history_exec
.name = "clear-history",
.alias = "clearhist",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_clear_history_exec
};
enum cmd_retval
cmd_clear_history_exec(struct cmd *self, struct cmd_q *cmdq)
cmd_clear_history_exec(__unused struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct window_pane *wp;
struct window_pane *wp = cmdq->state.tflag.wp;
struct grid *gd;
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
gd = wp->base.grid;
gd = cmdq->state.tflag.wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy);
gd->hsize = 0;
if (wp->mode == &window_copy_mode)
window_pane_reset_mode(wp);
grid_clear_history(gd);
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -35,11 +35,17 @@ int cmd_command_prompt_callback(void *, const char *);
void cmd_command_prompt_free(void *);
const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL,
"I:p:t:", 0, 1,
"[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
0,
cmd_command_prompt_exec
.name = "command-prompt",
.alias = NULL,
.args = { "I:p:t:", 0, 1 },
.usage = "[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
"[template]",
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_command_prompt_exec
};
struct cmd_command_prompt_cdata {
@ -58,13 +64,10 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args;
const char *inputs, *prompts;
struct cmd_command_prompt_cdata *cdata;
struct client *c;
struct client *c = cmdq->state.c;
char *prompt, *ptr, *input = NULL;
size_t n;
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
if (c->prompt_string != NULL)
return (CMD_RETURN_NORMAL);
@ -151,7 +154,7 @@ cmd_command_prompt_callback(void *data, const char *s)
return (0);
}
cmdq_run(c->cmdq, cmdlist);
cmdq_run(c->cmdq, cmdlist, NULL);
cmd_list_free(cmdlist);
if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)

View file

@ -34,11 +34,16 @@ 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",
"p:t:", 1, 1,
"[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
0,
cmd_confirm_before_exec
.name = "confirm-before",
.alias = "confirm",
.args = { "p:t:", 1, 1 },
.usage = "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_confirm_before_exec
};
struct cmd_confirm_before_data {
@ -51,13 +56,10 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct cmd_confirm_before_data *cdata;
struct client *c;
struct client *c = cmdq->state.c;
char *cmd, *copy, *new_prompt, *ptr;
const char *prompt;
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
if ((prompt = args_get(args, 'p')) != NULL)
xasprintf(&new_prompt, "%s ", prompt);
else {
@ -105,7 +107,7 @@ cmd_confirm_before_callback(void *data, const char *s)
return (0);
}
cmdq_run(c->cmdq, cmdlist);
cmdq_run(c->cmdq, cmdlist, NULL);
cmd_list_free(cmdlist);
return (0);
@ -117,7 +119,7 @@ cmd_confirm_before_free(void *data)
struct cmd_confirm_before_data *cdata = data;
struct client *c = cdata->client;
c->references--;
server_client_unref(c);
free(cdata->cmd);
free(cdata);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,29 +27,45 @@
enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
"t:u", 0, 0,
"[-u] " CMD_TARGET_PANE_USAGE,
0,
cmd_copy_mode_exec
.name = "copy-mode",
.alias = NULL,
.args = { "Met:u", 0, 0 },
.usage = "[-Mu] " CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_copy_mode_exec
};
const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
"t:", 0, 0,
CMD_TARGET_PANE_USAGE,
0,
cmd_copy_mode_exec
.name = "clock-mode",
.alias = NULL,
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_copy_mode_exec
};
enum cmd_retval
cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct window_pane *wp;
struct client *c = cmdq->client;
struct session *s;
struct window_pane *wp = cmdq->state.tflag.wp;
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'M')) {
if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL)
return (CMD_RETURN_NORMAL);
if (c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
}
if (self->entry == &cmd_clock_mode_entry) {
window_pane_set_mode(wp, &window_clock_mode);
@ -59,7 +75,12 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
if (wp->mode != &window_copy_mode) {
if (window_pane_set_mode(wp, &window_copy_mode) != 0)
return (CMD_RETURN_NORMAL);
window_copy_init_from_pane(wp);
window_copy_init_from_pane(wp, args_has(self->args, 'e'));
}
if (args_has(args, 'M')) {
if (wp->mode != NULL && wp->mode != &window_copy_mode)
return (CMD_RETURN_NORMAL);
window_copy_start_drag(c, &cmdq->item->mouse);
}
if (wp->mode == &window_copy_mode && args_has(self->args, 'u'))
window_copy_pageup(wp);

View file

@ -1,57 +0,0 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Delete a paste buffer.
*/
enum cmd_retval cmd_delete_buffer_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb",
"b:", 0, 0,
CMD_BUFFER_USAGE,
0,
cmd_delete_buffer_exec
};
enum cmd_retval
cmd_delete_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
const char *bufname;
if (!args_has(args, 'b')) {
paste_free_top();
return (CMD_RETURN_NORMAL);
}
bufname = args_get(args, 'b');
if (paste_free_name(bufname) != 0) {
cmdq_error(cmdq, "no buffer %s", bufname);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,36 +29,44 @@
enum cmd_retval cmd_detach_client_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_detach_client_entry = {
"detach-client", "detach",
"as:t:P", 0, 0,
"[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
CMD_READONLY,
cmd_detach_client_exec
.name = "detach-client",
.alias = "detach",
.args = { "as:t:P", 0, 0 },
.usage = "[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
.sflag = CMD_SESSION,
.tflag = CMD_CLIENT,
.flags = CMD_READONLY,
.exec = cmd_detach_client_exec
};
const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
cmd_detach_client_exec
.name = "suspend-client",
.alias = "suspendc",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_CLIENT_USAGE,
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_detach_client_exec
};
enum cmd_retval
cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c, *cloop;
struct client *c = cmdq->state.c, *cloop;
struct session *s;
enum msgtype msgtype;
u_int i;
if (self->entry == &cmd_suspend_client_entry) {
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
tty_stop_tty(&c->tty);
c->flags |= CLIENT_SUSPENDED;
server_write_client(c, MSG_SUSPEND, NULL, 0);
proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0);
return (CMD_RETURN_NORMAL);
}
@ -68,40 +76,22 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
msgtype = MSG_DETACH;
if (args_has(args, 's')) {
s = cmd_find_session(cmdq, args_get(args, 's'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
cloop = ARRAY_ITEM(&clients, i);
if (cloop == NULL || cloop->session != s)
continue;
server_write_client(cloop, msgtype,
cloop->session->name,
strlen(cloop->session->name) + 1);
s = cmdq->state.sflag.s;
TAILQ_FOREACH(cloop, &clients, entry) {
if (cloop->session == s)
server_client_detach(cloop, msgtype);
}
return (CMD_RETURN_STOP);
}
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
if (c == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'a')) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
cloop = ARRAY_ITEM(&clients, i);
if (cloop == NULL || cloop->session == NULL)
continue;
if (cloop == c)
continue;
server_write_client(cloop, msgtype,
cloop->session->name,
strlen(cloop->session->name) + 1);
TAILQ_FOREACH(cloop, &clients, entry) {
if (cloop->session != NULL && cloop != c)
server_client_detach(cloop, msgtype);
}
return (CMD_RETURN_NORMAL);
}
server_write_client(c, msgtype, c->session->name,
strlen(c->session->name) + 1);
server_client_detach(c, msgtype);
return (CMD_RETURN_STOP);
}

View file

@ -35,70 +35,47 @@
enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_display_message_entry = {
"display-message", "display",
"c:pt:F:", 0, 1,
"[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE
" [message]",
0,
cmd_display_message_exec
.name = "display-message",
.alias = "display",
.args = { "c:pt:F:", 0, 1 },
.usage = "[-p] [-c target-client] [-F format] "
CMD_TARGET_PANE_USAGE " [message]",
.cflag = CMD_CLIENT_CANFAIL,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_display_message_exec
};
enum cmd_retval
cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct session *s;
struct winlink *wl;
struct window_pane *wp;
struct client *c = cmdq->state.c;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct window_pane *wp = cmdq->state.tflag.wp;
const char *template;
char *msg;
struct format_tree *ft;
char out[BUFSIZ];
time_t t;
size_t len;
if (args_has(args, 't')) {
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
if (wl == NULL)
return (CMD_RETURN_ERROR);
} else {
wl = cmd_find_pane(cmdq, NULL, &s, &wp);
if (wl == NULL)
return (CMD_RETURN_ERROR);
}
if (args_has(args, 'F') && args->argc != 0) {
cmdq_error(cmdq, "only one of -F or argument must be given");
return (CMD_RETURN_ERROR);
}
if (args_has(args, 'c')) {
c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
if (c == NULL)
return (CMD_RETURN_ERROR);
} else {
c = cmd_current_client(cmdq);
if (c == NULL && !args_has(self->args, 'p')) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
}
template = args_get(args, 'F');
if (args->argc != 0)
template = args->argv[0];
if (template == NULL)
template = DISPLAY_MESSAGE_TEMPLATE;
ft = format_create();
ft = format_create(cmdq, 0);
format_defaults(ft, c, s, wl, wp);
t = time(NULL);
len = strftime(out, sizeof out, template, localtime(&t));
out[len] = '\0';
msg = format_expand(ft, out);
msg = format_expand_time(ft, template, time(NULL));
if (args_has(self->args, 'p'))
cmdq_print(cmdq, "%s", msg);
else

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,23 +27,22 @@
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
.name = "display-panes",
.alias = "displayp",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_CLIENT_USAGE,
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_display_panes_exec
};
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
cmd_display_panes_exec(__unused struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
server_set_identify(c);
server_set_identify(cmdq->state.c);
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -48,22 +48,28 @@ void cmd_find_window_callback(struct window_choose_data *);
CMD_FIND_WINDOW_BY_NAME)
const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw",
"F:CNt:T", 1, 4,
"[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
0,
cmd_find_window_exec
.name = "find-window",
.alias = "findw",
.args = { "F:CNt:T", 1, 4 },
.usage = "[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_find_window_exec
};
struct cmd_find_window_data {
struct winlink *wl;
char *list_ctx;
u_int pane_id;
TAILQ_ENTRY(cmd_find_window_data) entry;
};
ARRAY_DECL(cmd_find_window_data_list, struct cmd_find_window_data);
TAILQ_HEAD(cmd_find_window_list, cmd_find_window_data);
u_int cmd_find_window_match_flags(struct args *);
void cmd_find_window_match(struct cmd_find_window_data_list *, int,
void cmd_find_window_match(struct cmd_find_window_list *, int,
struct winlink *, const char *, const char *);
u_int
@ -87,16 +93,16 @@ cmd_find_window_match_flags(struct args *args)
}
void
cmd_find_window_match(struct cmd_find_window_data_list *find_list,
cmd_find_window_match(struct cmd_find_window_list *find_list,
int match_flags, struct winlink *wl, const char *str,
const char *searchstr)
{
struct cmd_find_window_data find_data;
struct cmd_find_window_data *find_data;
struct window_pane *wp;
u_int i, line;
char *sres;
memset(&find_data, 0, sizeof find_data);
find_data = xcalloc(1, sizeof *find_data);
i = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
@ -104,53 +110,53 @@ cmd_find_window_match(struct cmd_find_window_data_list *find_list,
if ((match_flags & CMD_FIND_WINDOW_BY_NAME) &&
fnmatch(searchstr, wl->window->name, 0) == 0) {
find_data.list_ctx = xstrdup("");
find_data->list_ctx = xstrdup("");
break;
}
if ((match_flags & CMD_FIND_WINDOW_BY_TITLE) &&
fnmatch(searchstr, wp->base.title, 0) == 0) {
xasprintf(&find_data.list_ctx,
xasprintf(&find_data->list_ctx,
"pane %u title: \"%s\"", i - 1, wp->base.title);
break;
}
if (match_flags & CMD_FIND_WINDOW_BY_CONTENT &&
(sres = window_pane_search(wp, str, &line)) != NULL) {
xasprintf(&find_data.list_ctx,
xasprintf(&find_data->list_ctx,
"pane %u line %u: \"%s\"", i - 1, line + 1, sres);
free(sres);
break;
}
}
if (find_data.list_ctx != NULL) {
find_data.wl = wl;
find_data.pane_id = i - 1;
ARRAY_ADD(find_list, find_data);
}
if (find_data->list_ctx != NULL) {
find_data->wl = wl;
find_data->pane_id = i - 1;
TAILQ_INSERT_TAIL(find_list, find_data, entry);
} else
free(find_data);
}
enum cmd_retval
cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct client *c = cmdq->state.c;
struct window_choose_data *cdata;
struct session *s;
struct winlink *wl, *wm;
struct cmd_find_window_data_list find_list;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl, *wm;
struct cmd_find_window_list find_list;
struct cmd_find_window_data *find_data;
struct cmd_find_window_data *find_data1;
char *str, *searchstr;
const char *template;
u_int i, match_flags;
if ((c = cmd_current_client(cmdq)) == NULL) {
if (c == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
s = c->session;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
if ((template = args_get(args, 'F')) == NULL)
template = FIND_WINDOW_TEMPLATE;
@ -158,21 +164,20 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
match_flags = cmd_find_window_match_flags(args);
str = args->argv[0];
ARRAY_INIT(&find_list);
TAILQ_INIT(&find_list);
xasprintf(&searchstr, "*%s*", str);
RB_FOREACH(wm, winlinks, &s->windows)
cmd_find_window_match(&find_list, match_flags, wm, str, searchstr);
free(searchstr);
if (ARRAY_LENGTH(&find_list) == 0) {
if (TAILQ_EMPTY(&find_list)) {
cmdq_error(cmdq, "no windows matching: %s", str);
ARRAY_FREE(&find_list);
return (CMD_RETURN_ERROR);
}
if (ARRAY_LENGTH(&find_list) == 1) {
if (session_select(s, ARRAY_FIRST(&find_list).wl->idx) == 0)
if (TAILQ_NEXT(TAILQ_FIRST(&find_list), entry) == NULL) {
if (session_select(s, TAILQ_FIRST(&find_list)->wl->idx) == 0)
server_redraw_session(s);
recalculate_sizes();
goto out;
@ -181,30 +186,33 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
goto out;
for (i = 0; i < ARRAY_LENGTH(&find_list); i++) {
wm = ARRAY_ITEM(&find_list, i).wl;
i = 0;
TAILQ_FOREACH(find_data, &find_list, entry) {
cdata = window_choose_data_create(TREE_OTHER, c, c->session);
cdata->idx = wm->idx;
cdata->wl = wm;
cdata->idx = find_data->wl->idx;
cdata->wl = find_data->wl;
cdata->ft_template = xstrdup(template);
cdata->pane_id = ARRAY_ITEM(&find_list, i).pane_id;
cdata->pane_id = find_data->pane_id;
format_add(cdata->ft, "line", "%u", i);
format_add(cdata->ft, "window_find_matches", "%s",
ARRAY_ITEM(&find_list, i).list_ctx);
format_defaults(cdata->ft, NULL, s, wm, NULL);
find_data->list_ctx);
format_defaults(cdata->ft, NULL, s, find_data->wl, NULL);
window_choose_add(wl->window->active, cdata);
i++;
}
window_choose_ready(wl->window->active, 0, cmd_find_window_callback);
out:
for (i = 0; i < ARRAY_LENGTH(&find_list); i++)
free(ARRAY_ITEM(&find_list, i).list_ctx);
ARRAY_FREE(&find_list);
TAILQ_FOREACH_SAFE(find_data, &find_list, entry, find_data1) {
free(find_data->list_ctx);
TAILQ_REMOVE(&find_list, find_data, entry);
free(find_data);
}
return (CMD_RETURN_NORMAL);
}

1257
cmd-find.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -36,19 +36,28 @@ void cmd_if_shell_done(struct cmd_q *);
void cmd_if_shell_free(void *);
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"bFt:", 2, 3,
"[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
0,
cmd_if_shell_exec
.name = "if-shell",
.alias = "if",
.args = { "bFt:", 2, 3 },
.usage = "[-bF] " CMD_TARGET_PANE_USAGE " shell-command command "
"[command]",
.tflag = CMD_PANE_CANFAIL,
.flags = 0,
.exec = cmd_if_shell_exec
};
struct cmd_if_shell_data {
char *cmd_if;
char *cmd_else;
struct cmd_q *cmdq;
int bflag;
int started;
char *cmd_if;
char *cmd_else;
struct cmd_q *cmdq;
struct mouse_event mouse;
int bflag;
int references;
};
enum cmd_retval
@ -58,24 +67,20 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct cmd_if_shell_data *cdata;
char *shellcmd, *cmd, *cause;
struct cmd_list *cmdlist;
struct client *c;
struct session *s = NULL;
struct winlink *wl = NULL;
struct window_pane *wp = NULL;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct window_pane *wp = cmdq->state.tflag.wp;
struct format_tree *ft;
const char *cwd;
if (args_has(args, 't'))
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
else {
c = cmd_find_client(cmdq, NULL, 1);
if (c != NULL && c->session != NULL) {
s = c->session;
wl = s->curw;
wp = wl->window->active;
}
}
if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else if (s != NULL)
cwd = s->cwd;
else
cwd = NULL;
ft = format_create();
ft = format_create(cmdq, 0);
format_defaults(ft, NULL, s, wl, wp);
shellcmd = format_expand(ft, args->argv[0]);
format_free(ft);
@ -86,6 +91,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
cmd = args->argv[1];
else if (args->argc == 3)
cmd = args->argv[2];
free(shellcmd);
if (cmd == NULL)
return (CMD_RETURN_NORMAL);
if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
@ -95,24 +101,28 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
}
return (CMD_RETURN_ERROR);
}
cmdq_run(cmdq, cmdlist);
cmdq_run(cmdq, cmdlist, &cmdq->item->mouse);
cmd_list_free(cmdlist);
return (CMD_RETURN_NORMAL);
}
cdata = xmalloc(sizeof *cdata);
cdata->cmd_if = xstrdup(args->argv[1]);
if (args->argc == 3)
cdata->cmd_else = xstrdup(args->argv[2]);
else
cdata->cmd_else = NULL;
cdata->bflag = args_has(args, 'b');
cdata->started = 0;
cdata->cmdq = cmdq;
memcpy(&cdata->mouse, &cmdq->item->mouse, sizeof cdata->mouse);
cmdq->references++;
job_run(shellcmd, s, cmd_if_shell_callback, cmd_if_shell_free, cdata);
cdata->references = 1;
job_run(shellcmd, s, cwd, cmd_if_shell_callback, cmd_if_shell_free,
cdata);
free(shellcmd);
if (cdata->bflag)
@ -128,7 +138,7 @@ cmd_if_shell_callback(struct job *job)
struct cmd_list *cmdlist;
char *cause, *cmd;
if (cmdq->dead)
if (cmdq->flags & CMD_Q_DEAD)
return;
if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
@ -146,13 +156,12 @@ cmd_if_shell_callback(struct job *job)
return;
}
cdata->started = 1;
cmdq1 = cmdq_new(cmdq->client);
cmdq1->emptyfn = cmd_if_shell_done;
cmdq1->data = cdata;
cmdq_run(cmdq1, cmdlist);
cdata->references++;
cmdq_run(cmdq1, cmdlist, &cdata->mouse);
cmd_list_free(cmdlist);
}
@ -164,12 +173,14 @@ cmd_if_shell_done(struct cmd_q *cmdq1)
if (cmdq1->client_exit >= 0)
cmdq->client_exit = cmdq1->client_exit;
cmdq_free(cmdq1);
if (--cdata->references != 0)
return;
if (!cmdq_free(cmdq) && !cdata->bflag)
cmdq_continue(cmdq);
cmdq_free(cmdq1);
free(cdata->cmd_else);
free(cdata->cmd_if);
free(cdata);
@ -181,7 +192,7 @@ cmd_if_shell_free(void *data)
struct cmd_if_shell_data *cdata = data;
struct cmd_q *cmdq = cdata->cmdq;
if (cdata->started)
if (--cdata->references != 0)
return;
if (!cmdq_free(cmdq) && !cdata->bflag)

View file

@ -2,7 +2,7 @@
/*
* Copyright (c) 2011 George Nachman <tmux@georgester.com>
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -33,19 +33,31 @@ enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmd_q *);
enum cmd_retval join_pane(struct cmd *, struct cmd_q *, int);
const struct cmd_entry cmd_join_pane_entry = {
"join-pane", "joinp",
"bdhvp:l:s:t:", 0, 0,
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
0,
cmd_join_pane_exec
.name = "join-pane",
.alias = "joinp",
.args = { "bdhvp:l:s:t:", 0, 0 },
.usage = "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
.sflag = CMD_PANE_MARKED,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_join_pane_exec
};
const struct cmd_entry cmd_move_pane_entry = {
"move-pane", "movep",
"bdhvp:l:s:t:", 0, 0,
"[-bdhv] [-p percentage|-l size] [-s src-pane] [-t dst-pane]",
0,
cmd_join_pane_exec
.name = "move-pane",
.alias = "movep",
.args = { "bdhvp:l:s:t:", 0, 0 },
.usage = "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
.sflag = CMD_PANE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_join_pane_exec
};
enum cmd_retval
@ -57,6 +69,10 @@ cmd_join_pane_exec(struct cmd *self, struct cmd_q *cmdq)
enum cmd_retval
join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
{
#ifdef TMATE
cmdq_error(cmdq, "join pane is not supported with tmate");
return (CMD_RETURN_ERROR);
#else
struct args *args = self->args;
struct session *dst_s;
struct winlink *src_wl, *dst_wl;
@ -67,16 +83,15 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
enum layout_type type;
struct layout_cell *lc;
dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), &dst_s, &dst_wp);
if (dst_wl == NULL)
return (CMD_RETURN_ERROR);
dst_s = cmdq->state.tflag.s;
dst_wl = cmdq->state.tflag.wl;
dst_wp = cmdq->state.tflag.wp;
dst_w = dst_wl->window;
dst_idx = dst_wl->idx;
server_unzoom_window(dst_w);
src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
if (src_wl == NULL)
return (CMD_RETURN_ERROR);
src_wl = cmdq->state.sflag.wl;
src_wp = cmdq->state.sflag.wp;
src_w = src_wl->window;
server_unzoom_window(src_w);
@ -147,4 +162,5 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
notify_window_layout_changed(dst_w);
return (CMD_RETURN_NORMAL);
#endif
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,22 +29,24 @@
enum cmd_retval cmd_kill_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp",
"at:", 0, 0,
"[-a] " CMD_TARGET_PANE_USAGE,
0,
cmd_kill_pane_exec
.name = "kill-pane",
.alias = "killp",
.args = { "at:", 0, 0 },
.usage = "[-a] " CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_kill_pane_exec
};
enum cmd_retval
cmd_kill_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window_pane *loopwp, *tmpwp, *wp;
struct winlink *wl = cmdq->state.tflag.wl;
struct window_pane *loopwp, *tmpwp, *wp = cmdq->state.tflag.wp;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
return (CMD_RETURN_ERROR);
server_unzoom_window(wl->window);
if (window_count_panes(wl->window) == 1) {

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -30,23 +30,29 @@
enum cmd_retval cmd_kill_server_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_kill_server_entry = {
"kill-server", NULL,
"", 0, 0,
"",
0,
cmd_kill_server_exec
.name = "kill-server",
.alias = NULL,
.args = { "", 0, 0 },
.usage = "",
.flags = 0,
.exec = cmd_kill_server_exec
};
const struct cmd_entry cmd_start_server_entry = {
"start-server", "start",
"", 0, 0,
"",
CMD_STARTSERVER,
cmd_kill_server_exec
.name = "start-server",
.alias = "start",
.args = { "", 0, 0 },
.usage = "",
.flags = CMD_STARTSERVER,
.exec = cmd_kill_server_exec
};
enum cmd_retval
cmd_kill_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
cmd_kill_server_exec(struct cmd *self, __unused struct cmd_q *cmdq)
{
if (self->entry == &cmd_kill_server_entry)
kill(getpid(), SIGTERM);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -30,27 +30,38 @@
enum cmd_retval cmd_kill_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL,
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
0,
cmd_kill_session_exec
.name = "kill-session",
.alias = NULL,
.args = { "aCt:", 0, 0 },
.usage = "[-aC] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_kill_session_exec
};
enum cmd_retval
cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s, *s2, *s3;
struct session *s, *sloop, *stmp;
struct winlink *wl;
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
s = cmdq->state.tflag.s;
if (args_has(args, 'a')) {
RB_FOREACH_SAFE(s2, sessions, &sessions, s3) {
if (s != s2) {
server_destroy_session(s2);
session_destroy(s2);
if (args_has(args, 'C')) {
RB_FOREACH(wl, winlinks, &s->windows) {
wl->window->flags &= ~WINDOW_ALERTFLAGS;
wl->flags &= ~WINLINK_ALERTFLAGS;
}
server_redraw_session(s);
} else if (args_has(args, 'a')) {
RB_FOREACH_SAFE(sloop, sessions, &sessions, stmp) {
if (sloop != s) {
server_destroy_session(sloop);
session_destroy(sloop);
}
}
} else {

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,42 +27,41 @@
enum cmd_retval cmd_kill_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw",
"at:", 0, 0,
"[-a] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_kill_window_exec
.name = "kill-window",
.alias = "killw",
.args = { "at:", 0, 0 },
.usage = "[-a] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_kill_window_exec
};
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
"kt:", 0, 0,
"[-k] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_kill_window_exec
.name = "unlink-window",
.alias = "unlinkw",
.args = { "kt:", 0, 0 },
.usage = "[-k] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_kill_window_exec
};
enum cmd_retval
cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl, *wl2, *wl3;
struct window *w;
struct session *s;
struct session_group *sg;
u_int references;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
struct winlink *wl = cmdq->state.tflag.wl, *wl2, *wl3;
struct window *w = wl->window;
struct session *s = cmdq->state.tflag.s;
if (self->entry == &cmd_unlink_window_entry) {
sg = session_group_find(s);
if (sg != NULL)
references = session_group_count(sg);
else
references = 1;
if (!args_has(self->args, 'k') && w->references == references) {
if (!args_has(self->args, 'k') && !session_is_linked(s, w)) {
cmdq_error(cmdq, "window only linked to one session");
return (CMD_RETURN_ERROR);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -33,15 +33,18 @@
enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_buffers_entry = {
"list-buffers", "lsb",
"F:", 0, 0,
"[-F format]",
0,
cmd_list_buffers_exec
.name = "list-buffers",
.alias = "lsb",
.args = { "F:", 0, 0 },
.usage = "[-F format]",
.flags = 0,
.exec = cmd_list_buffers_exec
};
enum cmd_retval
cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq)
cmd_list_buffers_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct paste_buffer *pb;
@ -54,8 +57,8 @@ cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq)
pb = NULL;
while ((pb = paste_walk(pb)) != NULL) {
ft = format_create();
format_defaults_paste_buffer(ft, pb, 0);
ft = format_create(cmdq, 0);
format_defaults_paste_buffer(ft, pb);
line = format_expand(ft, template);
cmdq_print(cmdq, "%s", line);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -36,11 +36,16 @@
enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc",
"F:t:", 0, 0,
"[-F format] " CMD_TARGET_SESSION_USAGE,
CMD_READONLY,
cmd_list_clients_exec
.name = "list-clients",
.alias = "lsc",
.args = { "F:t:", 0, 0 },
.usage = "[-F format] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = CMD_READONLY,
.exec = cmd_list_clients_exec
};
enum cmd_retval
@ -51,29 +56,24 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
struct session *s;
struct format_tree *ft;
const char *template;
u_int i;
u_int idx;
char *line;
if (args_has(args, 't')) {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
} else
if (args_has(args, 't'))
s = cmdq->state.tflag.s;
else
s = NULL;
if ((template = args_get(args, 'F')) == NULL)
template = LIST_CLIENTS_TEMPLATE;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
idx = 0;
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == NULL || (s != NULL && s != c->session))
continue;
if (s != NULL && s != c->session)
continue;
ft = format_create();
format_add(ft, "line", "%u", i);
ft = format_create(cmdq, 0);
format_add(ft, "line", "%u", idx);
format_defaults(ft, c, NULL, NULL, NULL);
line = format_expand(ft, template);
@ -81,6 +81,8 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
free(line);
format_free(ft);
idx++;
}
return (CMD_RETURN_NORMAL);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -18,6 +18,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@ -29,80 +30,112 @@
enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_list_keys_commands(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_list_keys_commands(struct cmd_q *);
const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk",
"t:", 0, 0,
"[-t key-table]",
0,
cmd_list_keys_exec
.name = "list-keys",
.alias = "lsk",
.args = { "t:T:", 0, 0 },
.usage = "[-t mode-table] [-T key-table]",
.flags = CMD_STARTSERVER,
.exec = cmd_list_keys_exec
};
const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm",
"", 0, 0,
"",
0,
cmd_list_keys_exec
.name = "list-commands",
.alias = "lscm",
.args = { "", 0, 0 },
.usage = "",
.flags = CMD_STARTSERVER,
.exec = cmd_list_keys_exec
};
enum cmd_retval
cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct key_table *table;
struct key_binding *bd;
const char *key;
char tmp[BUFSIZ], flags[8];
size_t used;
int width, keywidth;
const char *key, *tablename, *r;
char *cp, tmp[BUFSIZ];
int repeat, width, tablewidth, keywidth;
if (self->entry == &cmd_list_commands_entry)
return (cmd_list_keys_commands(self, cmdq));
return (cmd_list_keys_commands(cmdq));
#ifdef TMATE
/* XXX TODO Really nasty hack, we really need our own client instance... */
struct client fake_client;
if (!cmdq->client) {
cmdq->client = &fake_client;
cmdq->client->flags = 0;
cmdq->client->session = RB_MIN(sessions, &sessions);
}
#endif
if (args_has(args, 't'))
return (cmd_list_keys_table(self, cmdq));
width = 0;
RB_FOREACH(bd, key_bindings, &key_bindings) {
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
keywidth = strlen(key);
if (!(bd->key & KEYC_PREFIX)) {
if (bd->can_repeat)
keywidth += 4;
else
keywidth += 3;
} else if (bd->can_repeat)
keywidth += 3;
if (keywidth > width)
width = keywidth;
tablename = args_get(args, 'T');
if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
cmdq_error(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
RB_FOREACH(bd, key_bindings, &key_bindings) {
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
repeat = 0;
tablewidth = keywidth = 0;
RB_FOREACH(table, key_tables, &key_tables) {
if (tablename != NULL && strcmp(table->name, tablename) != 0)
continue;
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
key = key_string_lookup_key(bd->key);
*flags = '\0';
if (!(bd->key & KEYC_PREFIX)) {
if (bd->can_repeat)
xsnprintf(flags, sizeof flags, "-rn ");
else
xsnprintf(flags, sizeof flags, "-n ");
} else if (bd->can_repeat)
xsnprintf(flags, sizeof flags, "-r ");
repeat = 1;
used = xsnprintf(tmp, sizeof tmp, "%s%*s ",
flags, (int) (width - strlen(flags)), key);
if (used >= sizeof tmp)
width = utf8_cstrwidth(table->name);
if (width > tablewidth)
tablewidth = width;
width = utf8_cstrwidth(key);
if (width > keywidth)
keywidth = width;
}
}
RB_FOREACH(table, key_tables, &key_tables) {
if (tablename != NULL && strcmp(table->name, tablename) != 0)
continue;
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
key = key_string_lookup_key(bd->key);
cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
cmdq_print(cmdq, "bind-key %s", tmp);
if (!repeat)
r = "";
else if (bd->can_repeat)
r = "-r ";
else
r = " ";
xsnprintf(tmp, sizeof tmp, "%s-T ", r);
cp = utf8_padcstr(table->name, tablewidth);
strlcat(tmp, cp, sizeof tmp);
strlcat(tmp, " ", sizeof tmp);
free(cp);
cp = utf8_padcstr(key, keywidth);
strlcat(tmp, cp, sizeof tmp);
strlcat(tmp, " ", sizeof tmp);
free(cp);
cp = cmd_list_print(bd->cmdlist);
strlcat(tmp, cp, sizeof tmp);
free(cp);
cmdq_print(cmdq, "bind-key %s", tmp);
}
}
return (CMD_RETURN_NORMAL);
@ -128,8 +161,6 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
any_mode = 0;
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
if (key == NULL)
continue;
if (mbind->mode != 0)
any_mode = 1;
@ -141,8 +172,6 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
key = key_string_lookup_key(mbind->key);
if (key == NULL)
continue;
mode = "";
if (mbind->mode != 0)
@ -162,7 +191,7 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
}
enum cmd_retval
cmd_list_keys_commands(unused struct cmd *self, struct cmd_q *cmdq)
cmd_list_keys_commands(struct cmd_q *cmdq)
{
const struct cmd_entry **entryp;
const struct cmd_entry *entry;

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -19,7 +19,6 @@
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
@ -30,39 +29,37 @@
enum cmd_retval cmd_list_panes_exec(struct cmd *, struct cmd_q *);
void cmd_list_panes_server(struct cmd *, struct cmd_q *);
void cmd_list_panes_session(
struct cmd *, struct session *, struct cmd_q *, int);
void cmd_list_panes_window(struct cmd *,
struct session *, struct winlink *, struct cmd_q *, int);
void cmd_list_panes_session(struct cmd *, struct session *, struct cmd_q *,
int);
void cmd_list_panes_window(struct cmd *, struct session *, struct winlink *,
struct cmd_q *, int);
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
"asF:t:", 0, 0,
"[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_list_panes_exec
.name = "list-panes",
.alias = "lsp",
.args = { "asF:t:", 0, 0 },
.usage = "[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_list_panes_exec
};
enum cmd_retval
cmd_list_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct winlink *wl;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
if (args_has(args, 'a'))
cmd_list_panes_server(self, cmdq);
else if (args_has(args, 's')) {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
else if (args_has(args, 's'))
cmd_list_panes_session(self, s, cmdq, 1);
} else {
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
if (wl == NULL)
return (CMD_RETURN_ERROR);
else
cmd_list_panes_window(self, s, wl, cmdq, 0);
}
return (CMD_RETURN_NORMAL);
}
@ -77,8 +74,8 @@ cmd_list_panes_server(struct cmd *self, struct cmd_q *cmdq)
}
void
cmd_list_panes_session(
struct cmd *self, struct session *s, struct cmd_q *cmdq, int type)
cmd_list_panes_session(struct cmd *self, struct session *s, struct cmd_q *cmdq,
int type)
{
struct winlink *wl;
@ -87,8 +84,8 @@ cmd_list_panes_session(
}
void
cmd_list_panes_window(struct cmd *self,
struct session *s, struct winlink *wl, struct cmd_q *cmdq, int type)
cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl,
struct cmd_q *cmdq, int type)
{
struct args *args = self->args;
struct window_pane *wp;
@ -115,9 +112,9 @@ cmd_list_panes_window(struct cmd *self,
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
break;
case 2:
template = "#{session_name}:#{window_index}.#{pane_index}: "
"[#{pane_width}x#{pane_height}] [history "
"#{history_size}/#{history_limit}, "
template = "#{session_name}:#{window_index}."
"#{pane_index}: [#{pane_width}x#{pane_height}] "
"[history #{history_size}/#{history_limit}, "
"#{history_bytes} bytes] #{pane_id}"
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
break;
@ -126,7 +123,7 @@ cmd_list_panes_window(struct cmd *self,
n = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
ft = format_create();
ft = format_create(cmdq, 0);
format_add(ft, "line", "%u", n);
format_defaults(ft, NULL, s, wl, wp);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -30,7 +30,7 @@
#define LIST_SESSIONS_TEMPLATE \
"#{session_name}: #{session_windows} windows " \
"(created #{session_created_string}) " \
"(created #{t:session_created}) " \
"[#{session_width}x#{session_height}]" \
"#{?session_grouped, (group ,}" \
"#{session_group}#{?session_grouped,),}" \
@ -39,11 +39,14 @@
enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls",
"F:", 0, 0,
"[-F format]",
0,
cmd_list_sessions_exec
.name = "list-sessions",
.alias = "ls",
.args = { "F:", 0, 0 },
.usage = "[-F format]",
.flags = 0,
.exec = cmd_list_sessions_exec
};
enum cmd_retval
@ -61,7 +64,7 @@ cmd_list_sessions_exec(struct cmd *self, struct cmd_q *cmdq)
n = 0;
RB_FOREACH(s, sessions, &sessions) {
ft = format_create();
ft = format_create(cmdq, 0);
format_add(ft, "line", "%u", n);
format_defaults(ft, NULL, s, NULL, NULL);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -46,27 +46,27 @@ void cmd_list_windows_session(struct cmd *, struct session *,
struct cmd_q *, int);
const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw",
"F:at:", 0, 0,
"[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
0,
cmd_list_windows_exec
.name = "list-windows",
.alias = "lsw",
.args = { "F:at:", 0, 0 },
.usage = "[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_list_windows_exec
};
enum cmd_retval
cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
if (args_has(args, 'a'))
cmd_list_windows_server(self, cmdq);
else {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
cmd_list_windows_session(self, s, cmdq, 0);
}
else
cmd_list_windows_session(self, cmdq->state.tflag.s, cmdq, 0);
return (CMD_RETURN_NORMAL);
}
@ -81,8 +81,8 @@ cmd_list_windows_server(struct cmd *self, struct cmd_q *cmdq)
}
void
cmd_list_windows_session(
struct cmd *self, struct session *s, struct cmd_q *cmdq, int type)
cmd_list_windows_session(struct cmd *self, struct session *s,
struct cmd_q *cmdq, int type)
{
struct args *args = self->args;
struct winlink *wl;
@ -105,7 +105,7 @@ cmd_list_windows_session(
n = 0;
RB_FOREACH(wl, winlinks, &s->windows) {
ft = format_create();
ft = format_create(cmdq, 0);
format_add(ft, "line", "%u", n);
format_defaults(ft, NULL, s, wl, NULL);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -99,25 +99,28 @@ cmd_list_free(struct cmd_list *cmdlist)
free(cmdlist);
}
size_t
cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
char *
cmd_list_print(struct cmd_list *cmdlist)
{
struct cmd *cmd;
size_t off, used;
char *buf, *this;
size_t len;
len = 1;
buf = xcalloc(1, len);
off = 0;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
if (off >= len)
break;
off += cmd_print(cmd, buf + off, len - off);
if (off >= len)
break;
if (TAILQ_NEXT(cmd, qentry) != NULL) {
used = xsnprintf(buf + off, len - off, " ; ");
if (used > len - off)
used = len - off;
off += used;
}
this = cmd_print(cmd);
len += strlen(this) + 3;
buf = xrealloc(buf, len);
strlcat(buf, this, len);
if (TAILQ_NEXT(cmd, qentry) != NULL)
strlcat(buf, " ; ", len);
free(this);
}
return (off);
return (buf);
}

View file

@ -35,11 +35,14 @@ enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmd_q *);
void cmd_load_buffer_callback(struct client *, int, void *);
const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb",
"b:", 1, 1,
CMD_BUFFER_USAGE " path",
0,
cmd_load_buffer_exec
.name = "load-buffer",
.alias = "loadb",
.args = { "b:", 1, 1 },
.usage = CMD_BUFFER_USAGE " path",
.flags = 0,
.exec = cmd_load_buffer_exec
};
enum cmd_retval
@ -49,10 +52,10 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client;
struct session *s;
FILE *f;
const char *path, *bufname;
char *pdata, *new_pdata, *cause;
const char *path, *bufname, *cwd;
char *pdata, *new_pdata, *cause, *file, resolved[PATH_MAX];
size_t psize;
int ch, error, cwd, fd;
int ch, error;
bufname = NULL;
if (args_has(args, 'b'))
@ -70,18 +73,26 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_WAIT);
}
if (c != NULL && c->session == NULL)
if (c != NULL && c->session == NULL && c->cwd != NULL)
cwd = c->cwd;
else if ((s = cmd_current_session(cmdq, 0)) != NULL)
else if ((s = c->session) != NULL && s->cwd != NULL)
cwd = s->cwd;
else
cwd = AT_FDCWD;
cwd = ".";
if ((fd = openat(cwd, path, O_RDONLY)) == -1 ||
(f = fdopen(fd, "rb")) == NULL) {
if (fd != -1)
close(fd);
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
if (*path == '/')
file = xstrdup(path);
else
xasprintf(&file, "%s/%s", cwd, path);
if (realpath(file, resolved) == NULL &&
strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) {
cmdq_error(cmdq, "%s: %s", file, strerror(ENAMETOOLONG));
return (CMD_RETURN_ERROR);
}
f = fopen(resolved, "rb");
free(file);
if (f == NULL) {
cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
return (CMD_RETURN_ERROR);
}
@ -97,7 +108,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
pdata[psize++] = ch;
}
if (ferror(f)) {
cmdq_error(cmdq, "%s: read error", path);
cmdq_error(cmdq, "%s: read error", resolved);
goto error;
}
if (pdata != NULL)
@ -125,14 +136,14 @@ void
cmd_load_buffer_callback(struct client *c, int closed, void *data)
{
const char *bufname = data;
char *pdata, *cause;
char *pdata, *cause, *saved;
size_t psize;
if (!closed)
return;
c->stdin_callback = NULL;
c->references--;
server_client_unref(c);
if (c->flags & CLIENT_DEAD)
return;
@ -146,8 +157,13 @@ cmd_load_buffer_callback(struct client *c, int closed, void *data)
if (paste_set(pdata, psize, bufname, &cause) != 0) {
/* No context so can't use server_client_msg_error. */
if (~c->flags & CLIENT_UTF8) {
saved = cause;
cause = utf8_sanitize(saved);
free(saved);
}
evbuffer_add_printf(c->stderr_data, "%s", cause);
server_push_stderr(c);
server_client_push_stderr(c);
free(pdata);
free(cause);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,49 +27,52 @@
enum cmd_retval cmd_lock_server_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock",
"", 0, 0,
"",
0,
cmd_lock_server_exec
.name = "lock-server",
.alias = "lock",
.args = { "", 0, 0 },
.usage = "",
.flags = 0,
.exec = cmd_lock_server_exec
};
const struct cmd_entry cmd_lock_session_entry = {
"lock-session", "locks",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
0,
cmd_lock_server_exec
.name = "lock-session",
.alias = "locks",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_lock_server_exec
};
const struct cmd_entry cmd_lock_client_entry = {
"lock-client", "lockc",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
0,
cmd_lock_server_exec
.name = "lock-client",
.alias = "lockc",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_CLIENT_USAGE,
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_lock_server_exec
};
enum cmd_retval
cmd_lock_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
cmd_lock_server_exec(struct cmd *self, __unused struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct session *s;
if (self->entry == &cmd_lock_server_entry)
server_lock();
else if (self->entry == &cmd_lock_session_entry) {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
server_lock_session(s);
} else {
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
if (c == NULL)
return (CMD_RETURN_ERROR);
server_lock_client(c);
}
else if (self->entry == &cmd_lock_session_entry)
server_lock_session(cmdq->state.tflag.s);
else
server_lock_client(cmdq->state.c);
recalculate_sizes();
return (CMD_RETURN_NORMAL);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,48 +29,66 @@
enum cmd_retval cmd_move_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew",
"dkrs:t:", 0, 0,
"[-dkr] " CMD_SRCDST_WINDOW_USAGE,
0,
cmd_move_window_exec
.name = "move-window",
.alias = "movew",
.args = { "adkrs:t:", 0, 0 },
.usage = "[-dkr] " CMD_SRCDST_WINDOW_USAGE,
.sflag = CMD_WINDOW,
.tflag = CMD_MOVEW_R,
.flags = 0,
.exec = cmd_move_window_exec
};
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"dks:t:", 0, 0,
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0,
cmd_move_window_exec
.name = "link-window",
.alias = "linkw",
.args = { "adks:t:", 0, 0 },
.usage = "[-dk] " CMD_SRCDST_WINDOW_USAGE,
.sflag = CMD_WINDOW,
.tflag = CMD_WINDOW_INDEX,
.flags = 0,
.exec = cmd_move_window_exec
};
enum cmd_retval
cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
#ifdef TMATE
cmdq_error(cmdq, "move window is not supported with tmate");
return (CMD_RETURN_ERROR);
#else
struct args *args = self->args;
struct session *src, *dst, *s;
struct winlink *wl;
struct session *src = cmdq->state.sflag.s;
struct session *dst = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.sflag.wl;
char *cause;
int idx, kflag, dflag;
int idx = cmdq->state.tflag.idx, kflag, dflag, sflag;
kflag = args_has(self->args, 'k');
dflag = args_has(self->args, 'd');
if (args_has(args, 'r')) {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
session_renumber_windows(s);
session_renumber_windows(dst);
recalculate_sizes();
return (CMD_RETURN_NORMAL);
}
if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL)
return (CMD_RETURN_ERROR);
if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst)) == -2)
return (CMD_RETURN_ERROR);
kflag = args_has(self->args, 'k');
dflag = args_has(self->args, 'd');
sflag = args_has(self->args, 's');
if (args_has(self->args, 'a')) {
if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1)
return (CMD_RETURN_ERROR);
}
if (server_link_window(src, wl, dst, idx, kflag, !dflag,
&cause) != 0) {
cmdq_error(cmdq, "can't link window: %s", cause);
@ -79,7 +97,17 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
if (self->entry == &cmd_move_window_entry)
server_unlink_window(src, wl);
/*
* Renumber the winlinks in the src session only, the destination
* session already has the correct winlink id to us, either
* automatically or specified by -s.
*/
if (!sflag && options_get_number(src->options, "renumber-windows"))
session_renumber_windows(src);
recalculate_sizes();
return (CMD_RETURN_NORMAL);
#endif
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -36,44 +36,56 @@
enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"Ac:dDF:n:Ps:t:x:y:", 0, -1,
"[-AdDP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
"[-y height] [command]",
CMD_STARTSERVER|CMD_CANTNEST,
cmd_new_session_exec
.name = "new-session",
.alias = "new",
.args = { "Ac:dDEF:n:Ps:t:x:y:", 0, -1 },
.usage = "[-AdDEP] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
"[-y height] [command]",
.tflag = CMD_SESSION_CANFAIL,
.flags = CMD_STARTSERVER,
.exec = cmd_new_session_exec
};
const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
0,
cmd_new_session_exec
.name = "has-session",
.alias = "has",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_new_session_exec
};
enum cmd_retval
cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c = cmdq->client, *c0;
struct session *s, *groupwith;
struct client *c = cmdq->client;
struct session *s, *as;
struct session *groupwith = cmdq->state.tflag.s;
struct window *w;
struct environ env;
struct environ *env;
struct termios tio, *tiop;
const char *newname, *target, *update, *errstr, *template;
const char *path;
const char *path, *cwd, *to_free = NULL;
char **argv, *cmd, *cause, *cp;
int detached, already_attached, idx, cwd, fd = -1;
int argc;
int detached, already_attached, idx, argc;
u_int sx, sy;
struct format_tree *ft;
struct environ_entry *envent;
if (self->entry == &cmd_has_session_entry) {
if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
return (CMD_RETURN_ERROR);
/*
* cmd_prepare() will fail if the session cannot be found,
* hence always return success here.
*/
return (CMD_RETURN_NORMAL);
}
@ -88,21 +100,29 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "bad session name: %s", newname);
return (CMD_RETURN_ERROR);
}
if (session_find(newname) != NULL) {
if ((as = session_find(newname)) != NULL) {
if (args_has(args, 'A')) {
return (cmd_attach_session(cmdq, newname,
args_has(args, 'D'), 0, NULL));
/*
* This cmdq is now destined for
* attach-session. Because attach-session
* will have already been prepared, copy this
* session into its tflag so it can be used.
*/
cmd_find_from_session(&cmdq->state.tflag, as);
return (cmd_attach_session(cmdq,
args_has(args, 'D'), 0, NULL,
args_has(args, 'E')));
}
cmdq_error(cmdq, "duplicate session: %s", newname);
return (CMD_RETURN_ERROR);
}
}
target = args_get(args, 't');
if (target != NULL) {
groupwith = cmd_find_session(cmdq, target, 0);
if (groupwith == NULL)
return (CMD_RETURN_ERROR);
if ((target = args_get(args, 't')) != NULL) {
if (groupwith == NULL) {
cmdq_error(cmdq, "no such session: %s", target);
goto error;
}
} else
groupwith = NULL;
@ -111,6 +131,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (c == NULL)
detached = 1;
if (tmate_foreground)
detached = 1;
/* Is this client already attached? */
already_attached = 0;
if (c != NULL && c->session != NULL)
@ -118,42 +141,30 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
/* Get the new session working directory. */
if (args_has(args, 'c')) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL,
NULL);
cp = format_expand(ft, args_get(args, 'c'));
ft = format_create(cmdq, 0);
format_defaults(ft, c, NULL, NULL, NULL);
to_free = cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft);
if (cp != NULL && *cp != '\0') {
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
} else if (cp != NULL)
free(cp);
cwd = fd;
} else if (c != NULL && c->session == NULL)
} else if (c != NULL && c->session == NULL && c->cwd != NULL)
cwd = c->cwd;
else if ((c0 = cmd_current_client(cmdq)) != NULL)
cwd = c0->session->cwd;
else {
fd = open(".", O_RDONLY);
cwd = fd;
}
else
cwd = ".";
/*
* Save the termios settings, part of which is used for new windows in
* this session.
* If this is a new client, check for nesting and 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.
* tcgetattr() is used rather than using tty.tio since if the client is
* detached, tty_open won't be called. It must be done before opening
* the terminal as that calls tcsetattr() to prepare for tmux taking
* over.
*/
if (!detached && !already_attached && c->tty.fd != -1) {
if (server_client_check_nested(cmdq->client)) {
cmdq_error(cmdq, "sessions should be nested with care, "
"unset $TMUX to force");
return (CMD_RETURN_ERROR);
}
if (tcgetattr(c->tty.fd, &tio) != 0)
fatal("tcgetattr failed");
tiop = &tio;
@ -191,7 +202,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
goto error;
}
}
if (sy > 0 && options_get_number(&global_s_options, "status"))
if (sy > 0 && options_get_number(global_s_options, "status"))
sy--;
if (sx == 0)
sx = 1;
@ -201,11 +212,11 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
/* Figure out the command for the new window. */
argc = -1;
argv = NULL;
if (target == NULL && args->argc != 0) {
if (!args_has(args, 't') && args->argc != 0) {
argc = args->argc;
argv = args->argv;
} else if (target == NULL) {
cmd = options_get_string(&global_s_options, "default-command");
} else if (groupwith == NULL) {
cmd = options_get_string(global_s_options, "default-command");
if (cmd != NULL && *cmd != '\0') {
argc = 1;
argv = &cmd;
@ -217,34 +228,36 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
path = NULL;
if (c != NULL && c->session == NULL)
envent = environ_find(&c->environ, "PATH");
envent = environ_find(c->environ, "PATH");
else
envent = environ_find(&global_environ, "PATH");
envent = environ_find(global_environ, "PATH");
if (envent != NULL)
path = envent->value;
/* Construct the environment. */
environ_init(&env);
update = options_get_string(&global_s_options, "update-environment");
if (c != NULL)
environ_update(update, &c->environ, &env);
env = environ_create();
if (c != NULL && !args_has(args, 'E')) {
update = options_get_string(global_s_options,
"update-environment");
environ_update(update, c->environ, env);
}
/* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
idx = -1 - options_get_number(global_s_options, "base-index");
s = session_create(newname, argc, argv, path, cwd, env, tiop, idx, sx,
sy, &cause);
environ_free(env);
if (s == NULL) {
cmdq_error(cmdq, "create session failed: %s", cause);
free(cause);
goto error;
}
environ_free(&env);
/* Set the initial window name if one given. */
if (argc >= 0 && args_has(args, 'n')) {
w = s->curw->window;
window_set_name(w, args_get(args, 'n'));
options_set_number(&w->options, "automatic-rename", 0);
options_set_number(w->options, "automatic-rename", 0);
}
/*
@ -254,7 +267,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (groupwith != NULL) {
session_group_add(groupwith, s);
session_group_synchronize_to(s);
session_select(s, RB_ROOT(&s->windows)->idx);
session_select(s, RB_MIN(winlinks, &s->windows)->idx);
}
/*
@ -262,13 +275,17 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
* taking this session and needs to get MSG_READY and stay around.
*/
if (!detached) {
if (!already_attached)
server_write_ready(c);
else if (c->session != NULL)
if (!already_attached) {
if (~c->flags & CLIENT_CONTROL)
proc_send(c->peer, MSG_READY, -1, NULL, 0);
} else if (c->session != NULL)
c->last_session = c->session;
c->session = s;
server_client_set_key_table(c, NULL);
status_timer_start(c);
notify_attached_session_changed(c);
session_update_activity(s);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
server_redraw_client(c);
}
recalculate_sizes();
@ -286,9 +303,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if ((template = args_get(args, 'F')) == NULL)
template = NEW_SESSION_TEMPLATE;
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
ft = format_create(cmdq, 0);
format_defaults(ft, c, s, NULL, NULL);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);
@ -300,12 +316,12 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
if (!detached)
cmdq->client_exit = 0;
if (fd != -1)
close(fd);
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_NORMAL);
error:
if (fd != -1)
close(fd);
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_ERROR);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -35,57 +35,43 @@
enum cmd_retval cmd_new_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
"ac:dF:kn:Pt:", 0, -1,
"[-adkP] [-c start-directory] [-F format] [-n window-name] "
CMD_TARGET_WINDOW_USAGE " [command]",
0,
cmd_new_window_exec
.name = "new-window",
.alias = "neww",
.args = { "ac:dF:kn:Pt:", 0, -1 },
.usage = "[-adkP] [-c start-directory] [-F format] [-n window-name] "
CMD_TARGET_WINDOW_USAGE " [command]",
.tflag = CMD_WINDOW_INDEX,
.flags = 0,
.exec = cmd_new_window_exec
};
enum cmd_retval
cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct winlink *wl;
const char *cmd, *path, *template;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct client *c = cmdq->state.c;
int idx = cmdq->state.tflag.idx;
const char *cmd, *path, *template, *cwd, *to_free;
char **argv, *cause, *cp;
int argc, idx, last, detached, cwd, fd = -1;
int argc, detached;
struct format_tree *ft;
struct environ_entry *envent;
if (args_has(args, 'a')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
if (wl == NULL)
return (CMD_RETURN_ERROR);
idx = wl->idx + 1;
/* Find the next free index. */
for (last = idx; last < INT_MAX; last++) {
if (winlink_find_by_index(&s->windows, last) == NULL)
break;
}
if (last == INT_MAX) {
if ((idx = winlink_shuffle_up(s, wl)) == -1) {
cmdq_error(cmdq, "no free window indexes");
return (CMD_RETURN_ERROR);
}
/* Move everything from last - 1 to idx up a bit. */
for (; last > idx; last--) {
wl = winlink_find_by_index(&s->windows, last - 1);
server_link_window(s, wl, s, last, 0, 0, NULL);
server_unlink_window(s, wl);
}
} else {
idx = cmd_find_index(cmdq, args_get(args, 't'), &s);
if (idx == -2)
return (CMD_RETURN_ERROR);
}
detached = args_has(args, 'd');
if (args->argc == 0) {
cmd = options_get_string(&s->options, "default-command");
cmd = options_get_string(s->options, "default-command");
if (cmd != NULL && *cmd != '\0') {
argc = 1;
argv = (char **)&cmd;
@ -100,30 +86,18 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
envent = environ_find(cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
envent = environ_find(s->environ, "PATH");
if (envent != NULL)
path = envent->value;
to_free = NULL;
if (args_has(args, 'c')) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
cp = format_expand(ft, args_get(args, 'c'));
ft = format_create(cmdq, 0);
format_defaults(ft, c, s, NULL, NULL);
cwd = to_free = format_expand(ft, args_get(args, 'c'));
format_free(ft);
if (cp != NULL && *cp != '\0') {
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
} else if (cp != NULL)
free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else
@ -150,7 +124,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
idx = -1 - options_get_number(s->options, "base-index");
wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
&cause);
if (wl == NULL) {
@ -168,9 +142,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
if ((template = args_get(args, 'F')) == NULL)
template = NEW_WINDOW_TEMPLATE;
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
NULL);
ft = format_create(cmdq, 0);
format_defaults(ft, c, s, wl, NULL);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);
@ -179,12 +152,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
format_free(ft);
}
if (fd != -1)
close(fd);
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_NORMAL);
error:
if (fd != -1)
close(fd);
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_ERROR);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -33,31 +33,35 @@ void cmd_paste_buffer_filter(struct window_pane *,
const char *, size_t, const char *, int);
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
"db:prs:t:", 0, 0,
"[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE,
0,
cmd_paste_buffer_exec
.name = "paste-buffer",
.alias = "pasteb",
.args = { "db:prs:t:", 0, 0 },
.usage = "[-dpr] [-s separator] " CMD_BUFFER_USAGE " "
CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_paste_buffer_exec
};
enum cmd_retval
cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct window_pane *wp;
struct session *s;
struct window_pane *wp = cmdq->state.tflag.wp;
struct paste_buffer *pb;
const char *sepstr, *bufname;
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
return (CMD_RETURN_ERROR);
const char *sepstr, *bufname, *bufdata, *bufend, *line;
size_t seplen, bufsize;
int bracket = args_has(args, 'p');
bufname = NULL;
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
if (bufname == NULL)
pb = paste_get_top();
pb = paste_get_top(NULL);
else {
pb = paste_get_name(bufname);
if (pb == NULL) {
@ -66,7 +70,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
if (pb != NULL) {
if (pb != NULL && ~wp->flags & PANE_INPUTOFF) {
sepstr = args_get(args, 's');
if (sepstr == NULL) {
if (args_has(args, 'r'))
@ -74,16 +78,33 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
else
sepstr = "\r";
}
paste_send_pane(pb, wp, sepstr, args_has(args, 'p'));
seplen = strlen(sepstr);
if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
bufferevent_write(wp->event, "\033[200~", 6);
bufdata = paste_buffer_data(pb, &bufsize);
bufend = bufdata + bufsize;
for (;;) {
line = memchr(bufdata, '\n', bufend - bufdata);
if (line == NULL)
break;
bufferevent_write(wp->event, bufdata, line - bufdata);
bufferevent_write(wp->event, sepstr, seplen);
bufdata = line + 1;
}
if (bufdata != bufend)
bufferevent_write(wp->event, bufdata, bufend - bufdata);
if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
bufferevent_write(wp->event, "\033[201~", 6);
}
/* Delete the buffer if -d. */
if (args_has(args, 'd')) {
if (bufname == NULL)
paste_free_top();
else
paste_free_name(bufname);
}
if (pb != NULL && args_has(args, 'd'))
paste_free(pb);
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -37,29 +37,30 @@ enum cmd_retval cmd_pipe_pane_exec(struct cmd *, struct cmd_q *);
void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
"ot:", 0, 1,
"[-o] " CMD_TARGET_PANE_USAGE " [command]",
0,
cmd_pipe_pane_exec
.name = "pipe-pane",
.alias = "pipep",
.args = { "ot:", 0, 1 },
.usage = "[-o] " CMD_TARGET_PANE_USAGE " [command]",
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_pipe_pane_exec
};
enum cmd_retval
cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct session *s;
struct winlink *wl;
struct window_pane *wp;
struct client *c = cmdq->state.c;
struct window_pane *wp = cmdq->state.tflag.wp;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
char *cmd;
int old_fd, pipe_fd[2], null_fd;
struct format_tree *ft;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
c = cmd_find_client(cmdq, NULL, 1);
/* Destroy the old pipe. */
old_fd = wp->pipe_fd;
if (wp->pipe_fd != -1) {
@ -88,7 +89,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
}
/* Expand the command. */
ft = format_create();
ft = format_create(cmdq, 0);
format_defaults(ft, c, s, wl, wp);
cmd = format_expand_time(ft, args->argv[0], time(NULL));
format_free(ft);
@ -141,8 +142,8 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
}
void
cmd_pipe_pane_error_callback(
unused struct bufferevent *bufev, unused short what, void *data)
cmd_pipe_pane_error_callback(__unused struct bufferevent *bufev,
__unused short what, void *data)
{
struct window_pane *wp = data;

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -20,9 +20,13 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "tmux.h"
#include "tmate.h"
static enum cmd_retval cmdq_continue_one(struct cmd_q *);
/* Create new command queue. */
struct cmd_q *
@ -32,7 +36,7 @@ cmdq_new(struct client *c)
cmdq = xcalloc(1, sizeof *cmdq);
cmdq->references = 1;
cmdq->dead = 0;
cmdq->flags = 0;
cmdq->client = c;
cmdq->client_exit = -1;
@ -41,6 +45,9 @@ cmdq_new(struct client *c)
cmdq->item = NULL;
cmdq->cmd = NULL;
cmd_find_clear_state(&cmdq->current, NULL, 0);
cmdq->parent = NULL;
return (cmdq);
}
@ -48,8 +55,11 @@ cmdq_new(struct client *c)
int
cmdq_free(struct cmd_q *cmdq)
{
if (--cmdq->references != 0)
return (cmdq->dead);
if (--cmdq->references != 0) {
if (cmdq->flags & CMD_Q_DEAD)
return (1);
return (0);
}
cmdq_flush(cmdq);
free(cmdq);
@ -63,22 +73,32 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
struct client *c = cmdq->client;
struct window *w;
va_list ap;
char *tmp, *msg;
va_start(ap, fmt);
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
if (~c->flags & CLIENT_UTF8) {
vasprintf(&tmp, fmt, ap);
msg = utf8_sanitize(tmp);
free(tmp);
evbuffer_add(c->stdout_data, msg, strlen(msg));
free(msg);
} else
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
server_client_push_stdout(c);
} else {
w = c->session->curw->window;
if (w->active->mode != &window_copy_mode) {
window_pane_reset_mode(w->active);
window_pane_set_mode(w->active, &window_copy_mode);
window_copy_init_for_output(w->active);
#ifdef TMATE
tmate_sync_copy_mode(w->active);
#endif
}
window_copy_vadd(w->active, fmt, ap);
}
@ -95,18 +115,31 @@ cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
va_list ap;
char *msg;
size_t msglen;
char *tmp;
va_start(ap, fmt);
msglen = xvasprintf(&msg, fmt, ap);
va_end(ap);
if (c == NULL)
#ifdef TMATE
if (cmd->file && cmd->line)
cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
else
cfg_add_cause("%s", msg);
#else
cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
#endif
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
if (~c->flags & CLIENT_UTF8) {
tmp = msg;
msg = utf8_sanitize(tmp);
free(tmp);
msglen = strlen(msg);
}
evbuffer_add(c->stderr_data, msg, msglen);
evbuffer_add(c->stderr_data, "\n", 1);
server_push_stderr(c);
server_client_push_stderr(c);
c->retval = 1;
} else {
*msg = toupper((u_char) *msg);
@ -127,14 +160,14 @@ cmdq_guard(struct cmd_q *cmdq, const char *guard, int flags)
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
(long) cmdq->time, cmdq->number, flags);
server_push_stdout(c);
server_client_push_stdout(c);
}
/* Add command list to queue and begin processing if needed. */
void
cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist)
cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
{
cmdq_append(cmdq, cmdlist);
cmdq_append(cmdq, cmdlist, m);
if (cmdq->item == NULL) {
cmdq->cmd = NULL;
@ -144,7 +177,7 @@ cmdq_run(struct cmd_q *cmdq, struct cmd_list *cmdlist)
/* Add command list to queue. */
void
cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist)
cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
{
struct cmd_q_item *item;
@ -152,20 +185,65 @@ cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist)
item->cmdlist = cmdlist;
TAILQ_INSERT_TAIL(&cmdq->queue, item, qentry);
cmdlist->references++;
if (m != NULL)
memcpy(&item->mouse, m, sizeof item->mouse);
else
item->mouse.valid = 0;
}
/* Process one command. */
static enum cmd_retval
cmdq_continue_one(struct cmd_q *cmdq)
{
struct cmd *cmd = cmdq->cmd;
enum cmd_retval retval;
char *tmp;
int flags = !!(cmd->flags & CMD_CONTROL);
#ifdef TMATE
if (tmate_should_replicate_cmd(cmd->entry))
tmate_exec_cmd(cmd);
#endif
tmp = cmd_print(cmd);
log_debug("cmdq %p: %s", cmdq, tmp);
free(tmp);
cmdq->time = time(NULL);
cmdq->number++;
cmdq_guard(cmdq, "begin", flags);
if (cmd_prepare_state(cmd, cmdq, NULL) != 0)
goto error;
retval = cmd->entry->exec(cmd, cmdq);
if (retval == CMD_RETURN_ERROR)
goto error;
cmdq_guard(cmdq, "end", flags);
return (retval);
error:
cmdq_guard(cmdq, "error", flags);
return (CMD_RETURN_ERROR);
}
/* Continue processing command queue. Returns 1 if finishes empty. */
int
cmdq_continue(struct cmd_q *cmdq)
{
struct client *c = cmdq->client;
struct cmd_q_item *next;
enum cmd_retval retval;
int empty, flags;
char s[1024];
int empty;
cmdq->references++;
notify_disable();
log_debug("continuing cmdq %p: flags %#x, client %p", cmdq, cmdq->flags,
c);
empty = TAILQ_EMPTY(&cmdq->queue);
if (empty)
goto empty;
@ -178,23 +256,7 @@ cmdq_continue(struct cmd_q *cmdq)
do {
while (cmdq->cmd != NULL) {
cmd_print(cmdq->cmd, s, sizeof s);
log_debug("cmdq %p: %s (client %d)", cmdq, s,
cmdq->client != NULL ? cmdq->client->ibuf.fd : -1);
cmdq->time = time(NULL);
cmdq->number++;
flags = !!(cmdq->cmd->flags & CMD_CONTROL);
cmdq_guard(cmdq, "begin", flags);
retval = cmdq->cmd->entry->exec(cmdq->cmd, cmdq);
if (retval == CMD_RETURN_ERROR)
cmdq_guard(cmdq, "error", flags);
else
cmdq_guard(cmdq, "end", flags);
retval = cmdq_continue_one(cmdq);
if (retval == CMD_RETURN_ERROR)
break;
if (retval == CMD_RETURN_WAIT)
@ -203,7 +265,6 @@ cmdq_continue(struct cmd_q *cmdq)
cmdq_flush(cmdq);
goto empty;
}
cmdq->cmd = TAILQ_NEXT(cmdq->cmd, qentry);
}
next = TAILQ_NEXT(cmdq->item, qentry);
@ -244,3 +305,4 @@ cmdq_flush(struct cmd_q *cmdq)
}
cmdq->item = NULL;
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,24 +27,26 @@
enum cmd_retval cmd_refresh_client_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh",
"C:St:", 0, 0,
"[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_refresh_client_exec
.name = "refresh-client",
.alias = "refresh",
.args = { "C:St:", 0, 0 },
.usage = "[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_refresh_client_exec
};
enum cmd_retval
cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct client *c = cmdq->state.c;
const char *size;
u_int w, h;
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'C')) {
if ((size = args_get(args, 'C')) == NULL) {
cmdq_error(cmdq, "missing size");
@ -66,10 +68,12 @@ cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq)
if (tty_set_size(&c->tty, w, h))
recalculate_sizes();
} else if (args_has(args, 'S')) {
status_update_jobs(c);
c->flags |= CLIENT_STATUSFORCE;
server_status_client(c);
} else
} else {
c->flags |= CLIENT_STATUSFORCE;
server_redraw_client(c);
}
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,18 +29,23 @@
enum cmd_retval cmd_rename_session_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename",
"t:", 1, 1,
CMD_TARGET_SESSION_USAGE " new-name",
0,
cmd_rename_session_exec
.name = "rename-session",
.alias = "rename",
.args = { "t:", 1, 1 },
.usage = CMD_TARGET_SESSION_USAGE " new-name",
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_rename_session_exec
};
enum cmd_retval
cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct session *s = cmdq->state.tflag.s;
const char *newname;
newname = args->argv[0];
@ -53,9 +58,6 @@ cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
RB_REMOVE(sessions, &sessions, s);
free(s->name);
s->name = xstrdup(newname);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,25 +29,26 @@
enum cmd_retval cmd_rename_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew",
"t:", 1, 1,
CMD_TARGET_WINDOW_USAGE " new-name",
0,
cmd_rename_window_exec
.name = "rename-window",
.alias = "renamew",
.args = { "t:", 1, 1 },
.usage = CMD_TARGET_WINDOW_USAGE " new-name",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_rename_window_exec
};
enum cmd_retval
cmd_rename_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct winlink *wl;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
struct winlink *wl = cmdq->state.tflag.wl;
window_set_name(wl->window, args->argv[0]);
options_set_number(&wl->window->options, "automatic-rename", 0);
options_set_number(wl->window->options, "automatic-rename", 0);
server_status_window(wl->window);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -28,29 +28,45 @@
enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_q *);
void cmd_resize_pane_mouse_update(struct client *, struct mouse_event *);
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
"DLRt:Ux:y:Z", 0, 1,
"[-DLRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " [adjustment]",
0,
cmd_resize_pane_exec
.name = "resize-pane",
.alias = "resizep",
.args = { "DLMRt:Ux:y:Z", 0, 1 },
.usage = "[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " "
"[adjustment]",
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_resize_pane_exec
};
enum cmd_retval
cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct window_pane *wp = cmdq->state.tflag.wp;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w = wl->window;
struct client *c = cmdq->client;
struct session *s = cmdq->state.tflag.s;
const char *errstr;
char *cause;
struct window_pane *wp;
u_int adjust;
int x, y;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (args_has(args, 'M')) {
if (cmd_mouse_window(&cmdq->item->mouse, &s) == NULL)
return (CMD_RETURN_NORMAL);
if (c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
c->tty.mouse_drag_update = cmd_resize_pane_mouse_update;
cmd_resize_pane_mouse_update(c, &cmdq->item->mouse);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'Z')) {
if (w->flags & WINDOW_ZOOMED)
@ -106,3 +122,50 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
}
void
cmd_resize_pane_mouse_update(struct client *c, struct mouse_event *m)
{
struct winlink *wl;
struct window_pane *wp;
int found;
u_int y, ly;
wl = cmd_mouse_window(m, NULL);
if (wl == NULL) {
c->tty.mouse_drag_update = NULL;
return;
}
y = m->y;
if (m->statusat == 0 && y > 0)
y--;
else if (m->statusat > 0 && y >= (u_int)m->statusat)
y = m->statusat - 1;
ly = m->ly;
if (m->statusat == 0 && ly > 0)
ly--;
else if (m->statusat > 0 && ly >= (u_int)m->statusat)
ly = m->statusat - 1;
found = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
if (!window_pane_visible(wp))
continue;
if (wp->xoff + wp->sx == m->lx &&
wp->yoff <= 1 + ly && wp->yoff + wp->sy >= ly) {
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, m->x - m->lx);
found = 1;
}
if (wp->yoff + wp->sy == ly &&
wp->xoff <= 1 + m->lx && wp->xoff + wp->sx >= m->lx) {
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, y - ly);
found = 1;
}
}
if (found)
server_redraw_window(wl->window);
else
c->tty.mouse_drag_update = NULL;
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
* Copyright (c) 2011 Marcel P. Partap <mpartap@gmx.net>
*
* Permission to use, copy, modify, and distribute this software for any
@ -31,43 +31,44 @@
enum cmd_retval cmd_respawn_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_respawn_pane_entry = {
"respawn-pane", "respawnp",
"kt:", 0, -1,
"[-k] " CMD_TARGET_PANE_USAGE " [command]",
0,
cmd_respawn_pane_exec
.name = "respawn-pane",
.alias = "respawnp",
.args = { "kt:", 0, -1 },
.usage = "[-k] " CMD_TARGET_PANE_USAGE " [command]",
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_respawn_pane_exec
};
enum cmd_retval
cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct session *s;
struct environ env;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w = wl->window;
struct window_pane *wp = cmdq->state.tflag.wp;
struct session *s = cmdq->state.tflag.s;
struct environ *env;
const char *path;
char *cause;
u_int idx;
struct environ_entry *envent;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (!args_has(self->args, 'k') && wp->fd != -1) {
if (window_pane_index(wp, &idx) != 0)
fatalx("index not found");
cmdq_error(cmdq, "pane still active: %s:%u.%u",
cmdq_error(cmdq, "pane still active: %s:%d.%u",
s->name, wl->idx, idx);
return (CMD_RETURN_ERROR);
}
environ_init(&env);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
env = environ_create();
environ_copy(global_environ, env);
environ_copy(s->environ, env);
server_fill_environ(s, env);
window_pane_reset_mode(wp);
screen_reinit(&wp->base);
@ -75,22 +76,22 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
envent = environ_find(cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
envent = environ_find(s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn pane failed: %s", cause);
free(cause);
environ_free(&env);
environ_free(env);
return (CMD_RETURN_ERROR);
}
wp->flags |= PANE_REDRAW;
server_status_window(w);
environ_free(&env);
environ_free(env);
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -30,44 +30,45 @@
enum cmd_retval cmd_respawn_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw",
"kt:", 0, -1,
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
0,
cmd_respawn_window_exec
.name = "respawn-window",
.alias = "respawnw",
.args = { "kt:", 0, -1 },
.usage = "[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_respawn_window_exec
};
enum cmd_retval
cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w = wl->window;
struct window_pane *wp;
struct session *s;
struct environ env;
struct environ *env;
const char *path;
char *cause;
struct environ_entry *envent;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (!args_has(self->args, 'k')) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1)
continue;
cmdq_error(cmdq,
"window still active: %s:%d", s->name, wl->idx);
cmdq_error(cmdq, "window still active: %s:%d", s->name,
wl->idx);
return (CMD_RETURN_ERROR);
}
}
environ_init(&env);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
env = environ_create();
environ_copy(global_environ, env);
environ_copy(s->environ, env);
server_fill_environ(s, env);
wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry);
@ -78,18 +79,18 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
envent = environ_find(cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
envent = environ_find(s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
s->tio, &cause) != 0) {
cmdq_error(cmdq, "respawn window failed: %s", cause);
free(cause);
environ_free(&env);
server_destroy_pane(wp);
environ_free(env);
server_destroy_pane(wp, 0);
return (CMD_RETURN_ERROR);
}
layout_init(w, wp);
@ -101,6 +102,6 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
recalculate_sizes();
server_redraw_window(w);
environ_free(&env);
environ_free(env);
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,27 +27,27 @@
enum cmd_retval cmd_rotate_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew",
"Dt:U", 0, 0,
"[-DU] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_rotate_window_exec
.name = "rotate-window",
.alias = "rotatew",
.args = { "Dt:U", 0, 0 },
.usage = "[-DU] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_rotate_window_exec
};
enum cmd_retval
cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w = wl->window;
struct window_pane *wp, *wp2;
struct layout_cell *lc;
u_int sx, sy, xoff, yoff;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
if (args_has(self->args, 'D')) {
wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry);

View file

@ -36,11 +36,16 @@ void cmd_run_shell_free(void *);
void cmd_run_shell_print(struct job *, const char *);
const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run",
"bt:", 1, 1,
"[-b] " CMD_TARGET_PANE_USAGE " shell-command",
0,
cmd_run_shell_exec
.name = "run-shell",
.alias = "run",
.args = { "bt:", 1, 1 },
.usage = "[-b] " CMD_TARGET_PANE_USAGE " shell-command",
.tflag = CMD_PANE_CANFAIL,
.flags = 0,
.exec = cmd_run_shell_exec
};
struct cmd_run_shell_data {
@ -75,25 +80,20 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
struct args *args = self->args;
struct cmd_run_shell_data *cdata;
char *shellcmd;
struct client *c;
struct session *s = NULL;
struct winlink *wl = NULL;
struct window_pane *wp = NULL;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct window_pane *wp = cmdq->state.tflag.wp;
struct format_tree *ft;
const char *cwd;
if (args_has(args, 't'))
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
else {
c = cmd_find_client(cmdq, NULL, 1);
if (c != NULL && c->session != NULL) {
s = c->session;
wl = s->curw;
wp = wl->window->active;
}
}
ft = format_create();
format_defaults(ft, NULL, s, wl, wp);
if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else if (s != NULL)
cwd = s->cwd;
else
cwd = NULL;
ft = format_create(cmdq, 0);
format_defaults(ft, cmdq->state.c, s, wl, wp);
shellcmd = format_expand(ft, args->argv[0]);
format_free(ft);
@ -105,7 +105,8 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
cdata->cmdq = cmdq;
cmdq->references++;
job_run(shellcmd, s, cmd_run_shell_callback, cmd_run_shell_free, cdata);
job_run(shellcmd, s, cwd, cmd_run_shell_callback, cmd_run_shell_free,
cdata);
if (cdata->bflag)
return (CMD_RETURN_NORMAL);
@ -122,7 +123,7 @@ cmd_run_shell_callback(struct job *job)
int retcode;
u_int lines;
if (cmdq->dead)
if (cmdq->flags & CMD_Q_DEAD)
return;
cmd = cdata->cmd;

View file

@ -34,19 +34,25 @@
enum cmd_retval cmd_save_buffer_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_save_buffer_entry = {
"save-buffer", "saveb",
"ab:", 1, 1,
"[-a] " CMD_BUFFER_USAGE " path",
0,
cmd_save_buffer_exec
.name = "save-buffer",
.alias = "saveb",
.args = { "ab:", 1, 1 },
.usage = "[-a] " CMD_BUFFER_USAGE " path",
.flags = 0,
.exec = cmd_save_buffer_exec
};
const struct cmd_entry cmd_show_buffer_entry = {
"show-buffer", "showb",
"b:", 0, 0,
CMD_BUFFER_USAGE,
0,
cmd_save_buffer_exec
.name = "show-buffer",
.alias = "showb",
.args = { "b:", 0, 0 },
.usage = CMD_BUFFER_USAGE,
.flags = 0,
.exec = cmd_save_buffer_exec
};
enum cmd_retval
@ -56,14 +62,14 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct client *c = cmdq->client;
struct session *s;
struct paste_buffer *pb;
const char *path, *bufname;
char *start, *end, *msg;
size_t size, used, msglen;
int cwd, fd;
const char *path, *bufname, *bufdata, *start, *end, *cwd;
const char *flags;
char *msg, *file, resolved[PATH_MAX];
size_t size, used, msglen, bufsize;
FILE *f;
if (!args_has(args, 'b')) {
if ((pb = paste_get_top()) == NULL) {
if ((pb = paste_get_top(NULL)) == NULL) {
cmdq_error(cmdq, "no buffers");
return (CMD_RETURN_ERROR);
}
@ -75,6 +81,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
}
bufdata = paste_buffer_data(pb, &bufsize);
if (self->entry == &cmd_show_buffer_entry)
path = "-";
@ -90,31 +97,35 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
goto do_print;
}
if (c != NULL && c->session == NULL)
if (c != NULL && c->session == NULL && c->cwd != NULL)
cwd = c->cwd;
else if ((s = cmd_current_session(cmdq, 0)) != NULL)
else if ((s = c->session) != NULL && s->cwd != NULL)
cwd = s->cwd;
else
cwd = AT_FDCWD;
cwd = ".";
f = NULL;
if (args_has(self->args, 'a')) {
fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600);
if (fd != -1)
f = fdopen(fd, "ab");
} else {
fd = openat(cwd, path, O_CREAT|O_RDWR|O_TRUNC, 0600);
if (fd != -1)
f = fdopen(fd, "wb");
}
if (f == NULL) {
if (fd != -1)
close(fd);
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
flags = "wb";
if (args_has(self->args, 'a'))
flags = "ab";
if (*path == '/')
file = xstrdup(path);
else
xasprintf(&file, "%s/%s", cwd, path);
if (realpath(file, resolved) == NULL &&
strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) {
cmdq_error(cmdq, "%s: %s", file, strerror(ENAMETOOLONG));
return (CMD_RETURN_ERROR);
}
if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
cmdq_error(cmdq, "%s: fwrite error", path);
f = fopen(resolved, flags);
free(file);
if (f == NULL) {
cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
return (CMD_RETURN_ERROR);
}
if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
cmdq_error(cmdq, "%s: write error", resolved);
fclose(f);
return (CMD_RETURN_ERROR);
}
@ -123,25 +134,25 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
do_stdout:
evbuffer_add(c->stdout_data, pb->data, pb->size);
server_push_stdout(c);
evbuffer_add(c->stdout_data, bufdata, bufsize);
server_client_push_stdout(c);
return (CMD_RETURN_NORMAL);
do_print:
if (pb->size > (INT_MAX / 4) - 1) {
if (bufsize > (INT_MAX / 4) - 1) {
cmdq_error(cmdq, "buffer too big");
return (CMD_RETURN_ERROR);
}
msg = NULL;
used = 0;
while (used != pb->size) {
start = pb->data + used;
end = memchr(start, '\n', pb->size - used);
while (used != bufsize) {
start = bufdata + used;
end = memchr(start, '\n', bufsize - used);
if (end != NULL)
size = end - start;
else
size = pb->size - used;
size = bufsize - used;
msglen = size * 4 + 1;
msg = xrealloc(msg, msglen);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -18,6 +18,8 @@
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
@ -27,74 +29,111 @@
enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
"npt:", 0, 1,
"[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
0,
cmd_select_layout_exec
.name = "select-layout",
.alias = "selectl",
.args = { "nopt:", 0, 1 },
.usage = "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_select_layout_exec
};
const struct cmd_entry cmd_next_layout_entry = {
"next-layout", "nextl",
"t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
0,
cmd_select_layout_exec
.name = "next-layout",
.alias = "nextl",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_select_layout_exec
};
const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl",
"t:", 0, 0,
CMD_TARGET_WINDOW_USAGE,
0,
cmd_select_layout_exec
.name = "previous-layout",
.alias = "prevl",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_select_layout_exec
};
enum cmd_retval
cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w;
const char *layoutname;
char *oldlayout;
int next, previous, layout;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
server_unzoom_window(wl->window);
w = wl->window;
server_unzoom_window(w);
next = self->entry == &cmd_next_layout_entry;
if (args_has(self->args, 'n'))
if (args_has(args, 'n'))
next = 1;
previous = self->entry == &cmd_previous_layout_entry;
if (args_has(self->args, 'p'))
if (args_has(args, 'p'))
previous = 1;
oldlayout = w->old_layout;
w->old_layout = layout_dump(w->layout_root);
if (next || previous) {
if (next)
layout = layout_set_next(wl->window);
layout_set_next(w);
else
layout = layout_set_previous(wl->window);
server_redraw_window(wl->window);
return (CMD_RETURN_NORMAL);
layout_set_previous(w);
goto changed;
}
if (args->argc == 0)
layout = wl->window->lastlayout;
else
layout = layout_set_lookup(args->argv[0]);
if (layout != -1) {
layout = layout_set_select(wl->window, layout);
server_redraw_window(wl->window);
return (CMD_RETURN_NORMAL);
}
if (args->argc != 0) {
layoutname = args->argv[0];
if (layout_parse(wl->window, layoutname) == -1) {
cmdq_error(cmdq, "can't set layout: %s", layoutname);
return (CMD_RETURN_ERROR);
if (!args_has(args, 'o')) {
if (args->argc == 0)
layout = w->lastlayout;
else
layout = layout_set_lookup(args->argv[0]);
if (layout != -1) {
layout_set_select(w, layout);
goto changed;
}
server_redraw_window(wl->window);
}
if (args->argc != 0)
layoutname = args->argv[0];
else if (args_has(args, 'o'))
layoutname = oldlayout;
else
layoutname = NULL;
if (layoutname != NULL) {
if (layout_parse(w, layoutname) == -1) {
cmdq_error(cmdq, "can't set layout: %s", layoutname);
goto error;
}
goto changed;
}
free(oldlayout);
return (CMD_RETURN_NORMAL);
changed:
free(oldlayout);
server_redraw_window(w);
return (CMD_RETURN_NORMAL);
error:
free(w->old_layout);
w->old_layout = oldlayout;
return (CMD_RETURN_ERROR);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,32 +27,42 @@
enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
"DdeLlRt:U", 0, 0,
"[-DdeLlRU] " CMD_TARGET_PANE_USAGE,
0,
cmd_select_pane_exec
.name = "select-pane",
.alias = "selectp",
.args = { "DdegLlMmP:Rt:U", 0, 0 },
.usage = "[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_select_pane_exec
};
const struct cmd_entry cmd_last_pane_entry = {
"last-pane", "lastp",
"det:", 0, 0,
"[-de] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_select_pane_exec
.name = "last-pane",
.alias = "lastp",
.args = { "det:", 0, 0 },
.usage = "[-de] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_select_pane_exec
};
enum cmd_retval
cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct window_pane *wp;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w = wl->window;
struct session *s = cmdq->state.tflag.s;
struct window_pane *wp = cmdq->state.tflag.wp, *lastwp, *markedwp;
const char *style;
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
if (wl == NULL)
return (CMD_RETURN_ERROR);
if (wl->window->last == NULL) {
cmdq_error(cmdq, "no last pane");
@ -60,48 +70,94 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
}
if (args_has(self->args, 'e'))
wl->window->last->flags &= ~PANE_INPUTOFF;
w->last->flags &= ~PANE_INPUTOFF;
else if (args_has(self->args, 'd'))
wl->window->last->flags |= PANE_INPUTOFF;
w->last->flags |= PANE_INPUTOFF;
else {
server_unzoom_window(wl->window);
window_set_active_pane(wl->window, wl->window->last);
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
server_unzoom_window(w);
window_redraw_active_switch(w, w->last);
if (window_set_active_pane(w, w->last)) {
server_status_window(w);
server_redraw_window_borders(w);
}
}
return (CMD_RETURN_NORMAL);
}
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'm') || args_has(args, 'M')) {
if (args_has(args, 'm') && !window_pane_visible(wp))
return (CMD_RETURN_NORMAL);
lastwp = marked_pane.wp;
if (args_has(args, 'M') || server_is_marked(s, wl, wp))
server_clear_marked();
else
server_set_marked(s, wl, wp);
markedwp = marked_pane.wp;
if (lastwp != NULL) {
server_redraw_window_borders(lastwp->window);
server_status_window(lastwp->window);
}
if (markedwp != NULL) {
server_redraw_window_borders(markedwp->window);
server_status_window(markedwp->window);
}
return (CMD_RETURN_NORMAL);
}
if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
if (args_has(args, 'P')) {
style = args_get(args, 'P');
if (style_parse(&grid_default_cell, &wp->colgc,
style) == -1) {
cmdq_error(cmdq, "bad style: %s", style);
return (CMD_RETURN_ERROR);
}
wp->flags |= PANE_REDRAW;
}
if (args_has(self->args, 'g'))
cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
return (CMD_RETURN_NORMAL);
}
if (args_has(self->args, 'L')) {
server_unzoom_window(wp->window);
wp = window_pane_find_left(wp);
} else if (args_has(self->args, 'R')) {
server_unzoom_window(wp->window);
wp = window_pane_find_right(wp);
} else if (args_has(self->args, 'U')) {
server_unzoom_window(wp->window);
wp = window_pane_find_up(wp);
} else if (args_has(self->args, 'D')) {
server_unzoom_window(wp->window);
wp = window_pane_find_down(wp);
}
if (wp == NULL)
return (CMD_RETURN_NORMAL);
if (args_has(self->args, 'e')) {
wp->flags &= ~PANE_INPUTOFF;
return (CMD_RETURN_NORMAL);
}
if (args_has(self->args, 'd')) {
wp->flags |= PANE_INPUTOFF;
return (CMD_RETURN_NORMAL);
}
if (wp == w->active)
return (CMD_RETURN_NORMAL);
server_unzoom_window(wp->window);
if (!window_pane_visible(wp)) {
cmdq_error(cmdq, "pane not visible");
return (CMD_RETURN_ERROR);
}
if (args_has(self->args, 'L'))
wp = window_pane_find_left(wp);
else if (args_has(self->args, 'R'))
wp = window_pane_find_right(wp);
else if (args_has(self->args, 'U'))
wp = window_pane_find_up(wp);
else if (args_has(self->args, 'D'))
wp = window_pane_find_down(wp);
if (wp == NULL) {
cmdq_error(cmdq, "pane not found");
return (CMD_RETURN_ERROR);
}
if (args_has(self->args, 'e'))
wp->flags &= ~PANE_INPUTOFF;
else if (args_has(self->args, 'd'))
wp->flags |= PANE_INPUTOFF;
else if (window_set_active_pane(wl->window, wp)) {
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
window_redraw_active_switch(w, wp);
if (window_set_active_pane(w, wp)) {
server_status_window(w);
server_redraw_window_borders(w);
}
return (CMD_RETURN_NORMAL);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,43 +29,62 @@
enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw",
"lnpTt:", 0, 0,
"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_select_window_exec
.name = "select-window",
.alias = "selectw",
.args = { "lnpTt:", 0, 0 },
.usage = "[-lnpT] " CMD_TARGET_WINDOW_USAGE,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_select_window_exec
};
const struct cmd_entry cmd_next_window_entry = {
"next-window", "next",
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
0,
cmd_select_window_exec
.name = "next-window",
.alias = "next",
.args = { "at:", 0, 0 },
.usage = "[-a] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_select_window_exec
};
const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev",
"at:", 0, 0,
"[-a] " CMD_TARGET_SESSION_USAGE,
0,
cmd_select_window_exec
.name = "previous-window",
.alias = "prev",
.args = { "at:", 0, 0 },
.usage = "[-a] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_select_window_exec
};
const struct cmd_entry cmd_last_window_entry = {
"last-window", "last",
"t:", 0, 0,
CMD_TARGET_SESSION_USAGE,
0,
cmd_select_window_exec
.name = "last-window",
.alias = "last",
.args = { "t:", 0, 0 },
.usage = CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_select_window_exec
};
enum cmd_retval
cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *wl;
struct session *s;
struct winlink *wl = cmdq->state.tflag.wl;
struct session *s = cmdq->state.tflag.s;
int next, previous, last, activity;
next = self->entry == &cmd_next_window_entry;
@ -79,10 +98,6 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
last = 1;
if (next || previous || last) {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
activity = args_has(self->args, 'a');
if (next) {
if (session_next(s, activity) != 0) {
@ -103,10 +118,6 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
server_redraw_session(s);
} else {
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
if (wl == NULL)
return (CMD_RETURN_ERROR);
/*
* If -T and select-window is invoked on same window as
* current, switch to previous window.

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -30,68 +30,76 @@
enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"lRt:", 0, -1,
"[-lR] " CMD_TARGET_PANE_USAGE " key ...",
0,
cmd_send_keys_exec
.name = "send-keys",
.alias = "send",
.args = { "lRMt:", 0, -1 },
.usage = "[-lRM] " CMD_TARGET_PANE_USAGE " key ...",
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_send_keys_exec
};
const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
"2t:", 0, 0,
"[-2] " CMD_TARGET_PANE_USAGE,
0,
cmd_send_keys_exec
.name = "send-prefix",
.alias = NULL,
.args = { "2t:", 0, 0 },
.usage = "[-2] " CMD_TARGET_PANE_USAGE,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_send_keys_exec
};
enum cmd_retval
cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct window_pane *wp;
struct session *s;
struct input_ctx *ictx;
const u_char *str;
int i, key;
struct window_pane *wp = cmdq->state.tflag.wp;
struct session *s = cmdq->state.tflag.s;
struct mouse_event *m = &cmdq->item->mouse;
const u_char *keystr;
int i, literal;
key_code key;
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
return (CMD_RETURN_ERROR);
if (self->entry == &cmd_send_prefix_entry) {
if (args_has(args, '2'))
key = options_get_number(&s->options, "prefix2");
else
key = options_get_number(&s->options, "prefix");
window_pane_key(wp, s, key);
if (args_has(args, 'M')) {
wp = cmd_mouse_pane(m, &s, NULL);
if (wp == NULL) {
cmdq_error(cmdq, "no mouse target");
return (CMD_RETURN_ERROR);
}
window_pane_key(wp, NULL, s, m->key, m);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'R')) {
ictx = &wp->ictx;
memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell);
memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell);
ictx->old_cx = 0;
ictx->old_cy = 0;
if (wp->mode == NULL)
screen_write_start(&ictx->ctx, wp, &wp->base);
if (self->entry == &cmd_send_prefix_entry) {
if (args_has(args, '2'))
key = options_get_number(s->options, "prefix2");
else
screen_write_start(&ictx->ctx, NULL, &wp->base);
screen_write_reset(&ictx->ctx);
screen_write_stop(&ictx->ctx);
key = options_get_number(s->options, "prefix");
window_pane_key(wp, NULL, s, key, NULL);
return (CMD_RETURN_NORMAL);
}
for (i = 0; i < args->argc; i++) {
str = args->argv[i];
if (args_has(args, 'R'))
input_reset(wp, 1);
if (!args_has(args, 'l') &&
(key = key_string_lookup_string(str)) != KEYC_NONE) {
window_pane_key(wp, s, key);
} else {
for (; *str != '\0'; str++)
window_pane_key(wp, s, *str);
for (i = 0; i < args->argc; i++) {
literal = args_has(args, 'l');
if (!literal) {
key = key_string_lookup_string(args->argv[i]);
if (key != KEYC_NONE && key != KEYC_UNKNOWN)
window_pane_key(wp, NULL, s, key, NULL);
else
literal = 1;
}
if (literal) {
for (keystr = args->argv[i]; *keystr != '\0'; keystr++)
window_pane_key(wp, NULL, s, *keystr, NULL);
}
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -24,17 +24,31 @@
#include "tmux.h"
/*
* Add, set, or append to a paste buffer.
* Add, set, append to or delete a paste buffer.
*/
enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb",
"ab:n:", 0, 1,
"[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
0,
cmd_set_buffer_exec
.name = "set-buffer",
.alias = "setb",
.args = { "ab:n:", 0, 1 },
.usage = "[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
.flags = 0,
.exec = cmd_set_buffer_exec
};
const struct cmd_entry cmd_delete_buffer_entry = {
.name = "delete-buffer",
.alias = "deleteb",
.args = { "b:", 0, 0 },
.usage = CMD_BUFFER_USAGE,
.flags = 0,
.exec = cmd_set_buffer_exec
};
enum cmd_retval
@ -42,36 +56,39 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct paste_buffer *pb;
char *pdata, *cause;
const char *bufname;
size_t psize, newsize;
char *bufdata, *cause;
const char *bufname, *olddata;
size_t bufsize, newsize;
bufname = NULL;
bufname = args_get(args, 'b');
if (bufname == NULL)
pb = NULL;
else
pb = paste_get_name(bufname);
if (args_has(args, 'n')) {
if (args->argc > 0) {
cmdq_error(cmdq, "don't provide data with n flag");
if (self->entry == &cmd_delete_buffer_entry) {
if (pb == NULL)
pb = paste_get_top(&bufname);
if (pb == NULL) {
cmdq_error(cmdq, "no buffer");
return (CMD_RETURN_ERROR);
}
paste_free(pb);
return (CMD_RETURN_NORMAL);
}
if (args_has(args, 'b'))
bufname = args_get(args, 'b');
if (bufname == NULL) {
pb = paste_get_top();
if (pb == NULL) {
cmdq_error(cmdq, "no buffer");
return (CMD_RETURN_ERROR);
}
bufname = pb->name;
if (args_has(args, 'n')) {
if (pb == NULL)
pb = paste_get_top(&bufname);
if (pb == NULL) {
cmdq_error(cmdq, "no buffer");
return (CMD_RETURN_ERROR);
}
if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) {
cmdq_error(cmdq, "%s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
@ -79,37 +96,25 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "no data specified");
return (CMD_RETURN_ERROR);
}
psize = 0;
pdata = NULL;
pb = NULL;
if ((newsize = strlen(args->argv[0])) == 0)
return (CMD_RETURN_NORMAL);
if (args_has(args, 'b')) {
bufname = args_get(args, 'b');
pb = paste_get_name(bufname);
} else if (args_has(args, 'a')) {
pb = paste_get_top();
if (pb != NULL)
bufname = pb->name;
}
bufsize = 0;
bufdata = NULL;
if (args_has(args, 'a') && pb != NULL) {
psize = pb->size;
pdata = xmalloc(psize);
memcpy(pdata, pb->data, psize);
olddata = paste_buffer_data(pb, &bufsize);
bufdata = xmalloc(bufsize);
memcpy(bufdata, olddata, bufsize);
}
pdata = xrealloc(pdata, psize + newsize);
memcpy(pdata + psize, args->argv[0], newsize);
psize += newsize;
bufdata = xrealloc(bufdata, bufsize + newsize);
memcpy(bufdata + bufsize, args->argv[0], newsize);
bufsize += newsize;
if (paste_set(pdata, psize, bufname, &cause) != 0) {
if (paste_set(bufdata, bufsize, bufname, &cause) != 0) {
cmdq_error(cmdq, "%s", cause);
free(pdata);
free(bufdata);
free(cause);
return (CMD_RETURN_ERROR);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -30,20 +30,24 @@
enum cmd_retval cmd_set_environment_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv",
"grt:u", 1, 2,
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
0,
cmd_set_environment_exec
.name = "set-environment",
.alias = "setenv",
.args = { "grt:u", 1, 2 },
.usage = "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
.tflag = CMD_SESSION_CANFAIL,
.flags = 0,
.exec = cmd_set_environment_exec
};
enum cmd_retval
cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct environ *env;
const char *name, *value;
const char *name, *value, *target;
name = args->argv[0];
if (*name == '\0') {
@ -61,11 +65,17 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq)
value = args->argv[1];
if (args_has(self->args, 'g'))
env = &global_environ;
env = global_environ;
else {
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
if (cmdq->state.tflag.s == NULL) {
target = args_get(args, 't');
if (target != NULL)
cmdq_error(cmdq, "no such session: %s", target);
else
cmdq_error(cmdq, "no current session");
return (CMD_RETURN_ERROR);
env = &s->environ;
}
env = cmdq->state.tflag.s->environ;
}
if (args_has(self->args, 'u')) {
@ -79,13 +89,13 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "can't specify a value with -r");
return (CMD_RETURN_ERROR);
}
environ_set(env, name, NULL);
environ_clear(env, name);
} else {
if (value == NULL) {
cmdq_error(cmdq, "no value specified");
return (CMD_RETURN_ERROR);
}
environ_set(env, name, value);
environ_set(env, name, "%s", value);
}
return (CMD_RETURN_NORMAL);

120
cmd-set-hook.c Normal file
View file

@ -0,0 +1,120 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.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 <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Set or show global or session hooks.
*/
enum cmd_retval cmd_set_hook_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_set_hook_entry = {
.name = "set-hook",
.alias = NULL,
.args = { "gt:u", 1, 2 },
.usage = "[-gu] " CMD_TARGET_SESSION_USAGE " hook-name [command]",
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_set_hook_exec
};
const struct cmd_entry cmd_show_hooks_entry = {
.name = "show-hooks",
.alias = NULL,
.args = { "gt:", 0, 1 },
.usage = "[-g] " CMD_TARGET_SESSION_USAGE,
.tflag = CMD_SESSION,
.flags = 0,
.exec = cmd_set_hook_exec
};
enum cmd_retval
cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct cmd_list *cmdlist;
struct hooks *hooks;
struct hook *hook;
char *cause, *tmp;
const char *name, *cmd;
if (args_has(args, 'g'))
hooks = global_hooks;
else
hooks = cmdq->state.tflag.s->hooks;
if (self->entry == &cmd_show_hooks_entry) {
hook = hooks_first(hooks);
while (hook != NULL) {
tmp = cmd_list_print(hook->cmdlist);
cmdq_print(cmdq, "%s -> %s", hook->name, tmp);
free(tmp);
hook = hooks_next(hook);
}
return (CMD_RETURN_NORMAL);
}
name = args->argv[0];
if (*name == '\0') {
cmdq_error(cmdq, "invalid hook name");
return (CMD_RETURN_ERROR);
}
if (args->argc < 2)
cmd = NULL;
else
cmd = args->argv[1];
if (args_has(args, 'u')) {
if (cmd != NULL) {
cmdq_error(cmdq, "command passed to unset hook: %s",
name);
return (CMD_RETURN_ERROR);
}
hooks_remove(hooks, name);
return (CMD_RETURN_NORMAL);
}
if (cmd == NULL) {
cmdq_error(cmdq, "no command to set hook: %s", name);
return (CMD_RETURN_ERROR);
}
if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
if (cause != NULL) {
cmdq_error(cmdq, "%s", cause);
free(cause);
}
return (CMD_RETURN_ERROR);
}
hooks_add(hooks, name, cmdlist);
cmd_list_free(cmdlist);
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -65,33 +65,42 @@ struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *,
const char *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
"agoqst:uw", 1, 2,
"[-agosquw] [-t target-session|target-window] option [value]",
0,
cmd_set_option_exec
.name = "set-option",
.alias = "set",
.args = { "agoqst:uw", 1, 2 },
.usage = "[-agosquw] [-t target-window] option [value]",
.tflag = CMD_WINDOW_CANFAIL,
.flags = 0,
.exec = cmd_set_option_exec
};
const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw",
"agoqt:u", 1, 2,
"[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
0,
cmd_set_option_exec
.name = "set-window-option",
.alias = "setw",
.args = { "agoqt:u", 1, 2 },
.usage = "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
.tflag = CMD_WINDOW_CANFAIL,
.flags = 0,
.exec = cmd_set_option_exec
};
enum cmd_retval
cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
const struct options_table_entry *table, *oe;
struct session *s;
struct winlink *wl;
struct client *c;
struct options *oo;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w;
const char *optstr, *valstr;
u_int i;
struct client *c;
const struct options_table_entry *oe;
struct options *oo;
const char *optstr, *valstr, *target;
/* Get the option name and value. */
optstr = args->argv[0];
@ -109,10 +118,13 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
return (cmd_set_option_user(self, cmdq, optstr, valstr));
/* Find the option entry, try each table. */
table = oe = NULL;
if (options_table_find(optstr, &table, &oe) != 0) {
cmdq_error(cmdq, "ambiguous option: %s", optstr);
return (CMD_RETURN_ERROR);
oe = NULL;
if (options_table_find(optstr, &oe) != 0) {
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "ambiguous option: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
if (oe == NULL) {
if (!args_has(args, 'q')) {
@ -122,37 +134,35 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_NORMAL);
}
/* Work out the tree from the table. */
if (table == server_options_table)
oo = &global_options;
else if (table == window_options_table) {
/* Work out the tree from the scope of the option. */
if (oe->scope == OPTIONS_TABLE_SERVER)
oo = global_options;
else if (oe->scope == OPTIONS_TABLE_WINDOW) {
if (args_has(self->args, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
if (wl == NULL) {
cmdq_error(cmdq,
"couldn't set '%s'%s", optstr,
(!args_has(args, 't') && !args_has(args,
'g')) ? " need target window or -g" : "");
return (CMD_RETURN_ERROR);
}
oo = &wl->window->options;
}
} else if (table == session_options_table) {
oo = global_w_options;
else if (wl == NULL) {
target = args_get(args, 't');
if (target != NULL) {
cmdq_error(cmdq, "no such window: %s",
target);
} else
cmdq_error(cmdq, "no current window");
return (CMD_RETURN_ERROR);
} else
oo = wl->window->options;
} else if (oe->scope == OPTIONS_TABLE_SESSION) {
if (args_has(self->args, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL) {
cmdq_error(cmdq,
"couldn't set '%s'%s", optstr,
(!args_has(args, 't') && !args_has(args,
'g')) ? " need target session or -g" : "");
return (CMD_RETURN_ERROR);
}
oo = &s->options;
}
oo = global_s_options;
else if (s == NULL) {
target = args_get(args, 't');
if (target != NULL) {
cmdq_error(cmdq, "no such session: %s",
target);
} else
cmdq_error(cmdq, "no current session");
return (CMD_RETURN_ERROR);
} else
oo = s->options;
} else {
cmdq_error(cmdq, "unknown table");
return (CMD_RETURN_ERROR);
@ -174,23 +184,27 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
/* Start or stop timers when automatic-rename changed. */
/* Start or stop timers if necessary. */
if (strcmp(oe->name, "automatic-rename") == 0) {
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) == NULL)
continue;
if (options_get_number(&w->options, "automatic-rename"))
queue_window_name(w);
else if (event_initialized(&w->name_timer))
evtimer_del(&w->name_timer);
RB_FOREACH(w, windows, &windows) {
if (options_get_number(w->options, "automatic-rename"))
w->active->flags |= PANE_CHANGED;
}
}
if (strcmp(oe->name, "key-table") == 0) {
TAILQ_FOREACH(c, &clients, entry)
server_client_set_key_table(c, NULL);
}
if (strcmp(oe->name, "status") == 0 ||
strcmp(oe->name, "status-interval") == 0)
status_timer_start_all();
if (strcmp(oe->name, "monitor-silence") == 0)
alerts_reset_all();
/* Update sizes and redraw. May not need it but meh. */
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != NULL)
server_redraw_client(c);
}
@ -203,31 +217,23 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char *optstr,
const char *valstr)
{
struct args *args = self->args;
struct session *s;
struct winlink *wl;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct options *oo;
if (args_has(args, 's'))
oo = &global_options;
oo = global_options;
else if (args_has(self->args, 'w') ||
self->entry == &cmd_set_window_option_entry) {
if (args_has(self->args, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
if (wl == NULL)
return (CMD_RETURN_ERROR);
oo = &wl->window->options;
}
oo = global_w_options;
else
oo = wl->window->options;
} else {
if (args_has(self->args, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
oo = &s->options;
}
oo = global_s_options;
else
oo = s->options;
}
if (args_has(args, 'u')) {
@ -261,7 +267,6 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char *optstr,
return (CMD_RETURN_NORMAL);
}
/* Unset an option. */
int
cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
@ -270,16 +275,25 @@ cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
{
struct args *args = self->args;
if (args_has(args, 'g')) {
cmdq_error(cmdq, "can't unset global option: %s", oe->name);
return (-1);
}
if (value != NULL) {
cmdq_error(cmdq, "value passed to unset option: %s", oe->name);
return (-1);
}
options_remove(oo, oe->name);
if (args_has(args, 'g') || oo == global_options) {
switch (oe->type) {
case OPTIONS_TABLE_STRING:
options_set_string(oo, oe->name, "%s", oe->default_str);
break;
case OPTIONS_TABLE_STYLE:
options_set_style(oo, oe->name, oe->default_str, 0);
break;
default:
options_set_number(oo, oe->name, oe->default_num);
break;
}
} else
options_remove(oo, oe->name);
return (0);
}
@ -291,9 +305,15 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
{
struct options_entry *o;
if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
cmdq_error(cmdq, "empty value");
return (-1);
switch (oe->type) {
case OPTIONS_TABLE_FLAG:
case OPTIONS_TABLE_CHOICE:
break;
default:
if (value == NULL) {
cmdq_error(cmdq, "empty value");
return (-1);
}
}
o = NULL;
@ -334,7 +354,7 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
/* Set a string option. */
struct options_entry *
cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
cmd_set_option_string(struct cmd *self, __unused struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
@ -356,7 +376,7 @@ cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
/* Set a number option. */
struct options_entry *
cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
cmd_set_option_number(__unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
@ -374,13 +394,14 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a key option. */
struct options_entry *
cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
cmd_set_option_key(__unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int key;
key_code key;
if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
key = key_string_lookup_string(value);
if (key == KEYC_UNKNOWN) {
cmdq_error(cmdq, "bad key: %s", value);
return (NULL);
}
@ -390,7 +411,7 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a colour option. */
struct options_entry *
cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
cmd_set_option_colour(__unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
@ -406,7 +427,7 @@ cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
/* Set an attributes option. */
struct options_entry *
cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
cmd_set_option_attributes(__unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
@ -422,7 +443,7 @@ cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a flag option. */
struct options_entry *
cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
cmd_set_option_flag(__unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
@ -450,28 +471,34 @@ cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a choice option. */
struct options_entry *
cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
cmd_set_option_choice(__unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
const char **choicep;
int n, choice = -1;
n = 0;
for (choicep = oe->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (value == NULL) {
choice = options_get_number(oo, oe->name);
if (choice < 2)
choice = !choice;
} else {
n = 0;
for (choicep = oe->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (choice != -1) {
cmdq_error(cmdq, "ambiguous value: %s", value);
if (choice != -1) {
cmdq_error(cmdq, "ambiguous value: %s", value);
return (NULL);
}
choice = n - 1;
}
if (choice == -1) {
cmdq_error(cmdq, "unknown value: %s", value);
return (NULL);
}
choice = n - 1;
}
if (choice == -1) {
cmdq_error(cmdq, "unknown value: %s", value);
return (NULL);
}
return (options_set_number(oo, oe->name, choice));

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -27,30 +27,93 @@
* Show environment.
*/
enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *);
char *cmd_show_environment_escape(struct environ_entry *);
void cmd_show_environment_print(struct cmd *, struct cmd_q *,
struct environ_entry *);
const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv",
"gt:", 0, 1,
"[-g] " CMD_TARGET_SESSION_USAGE " [name]",
0,
cmd_show_environment_exec
.name = "show-environment",
.alias = "showenv",
.args = { "gst:", 0, 1 },
.usage = "[-gs] " CMD_TARGET_SESSION_USAGE " [name]",
.tflag = CMD_SESSION_CANFAIL,
.flags = 0,
.exec = cmd_show_environment_exec
};
char *
cmd_show_environment_escape(struct environ_entry *envent)
{
const char *value = envent->value;
char c, *out, *ret;
out = ret = xmalloc(strlen(value) * 2 + 1); /* at most twice the size */
while ((c = *value++) != '\0') {
/* POSIX interprets $ ` " and \ in double quotes. */
if (c == '$' || c == '`' || c == '"' || c == '\\')
*out++ = '\\';
*out++ = c;
}
*out = '\0';
return (ret);
}
void
cmd_show_environment_print(struct cmd *self, struct cmd_q *cmdq,
struct environ_entry *envent)
{
char *escaped;
if (!args_has(self->args, 's')) {
if (envent->value != NULL)
cmdq_print(cmdq, "%s=%s", envent->name, envent->value);
else
cmdq_print(cmdq, "-%s", envent->name);
return;
}
if (envent->value != NULL) {
escaped = cmd_show_environment_escape(envent);
cmdq_print(cmdq, "%s=\"%s\"; export %s;", envent->name, escaped,
envent->name);
free(escaped);
} else
cmdq_print(cmdq, "unset %s;", envent->name);
}
enum cmd_retval
cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct environ *env;
struct environ_entry *envent;
const char *target;
if ((target = args_get(args, 't')) != NULL) {
if (cmdq->state.tflag.s == NULL) {
cmdq_error(cmdq, "no such session: %s", target);
return (CMD_RETURN_ERROR);
}
}
if (args_has(self->args, 'g'))
env = &global_environ;
env = global_environ;
else {
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
if (cmdq->state.tflag.s == NULL) {
target = args_get(args, 't');
if (target != NULL)
cmdq_error(cmdq, "no such session: %s", target);
else
cmdq_error(cmdq, "no current session");
return (CMD_RETURN_ERROR);
env = &s->environ;
}
env = cmdq->state.tflag.s->environ;
}
if (args->argc != 0) {
@ -59,19 +122,14 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "unknown variable: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
if (envent->value != NULL)
cmdq_print(cmdq, "%s=%s", envent->name, envent->value);
else
cmdq_print(cmdq, "-%s", envent->name);
cmd_show_environment_print(self, cmdq, envent);
return (CMD_RETURN_NORMAL);
}
RB_FOREACH(envent, environ, env) {
if (envent->value != NULL)
cmdq_print(cmdq, "%s=%s", envent->name, envent->value);
else
cmdq_print(cmdq, "-%s", envent->name);
envent = environ_first(env);
while (envent != NULL) {
cmd_show_environment_print(self, cmdq, envent);
envent = environ_next(envent);
}
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -31,133 +31,94 @@
enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
"IJTt:", 0, 0,
"[-IJT] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_show_messages_exec
.name = "show-messages",
.alias = "showmsgs",
.args = { "JTt:", 0, 0 },
.usage = "[-JT] " CMD_TARGET_CLIENT_USAGE,
.tflag = CMD_CLIENT,
.flags = 0,
.exec = cmd_show_messages_exec
};
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
"", 0, 0,
"",
0,
cmd_show_messages_exec
.name = "server-info",
.alias = "info",
.args = { "", 0, 0 },
.usage = "",
.flags = 0,
.exec = cmd_show_messages_exec
};
void cmd_show_messages_server(struct cmd_q *);
void cmd_show_messages_terminals(struct cmd_q *);
void cmd_show_messages_jobs(struct cmd_q *);
int cmd_show_messages_terminals(struct cmd_q *, int);
int cmd_show_messages_jobs(struct cmd_q *, int);
void
cmd_show_messages_server(struct cmd_q *cmdq)
int
cmd_show_messages_terminals(struct cmd_q *cmdq, int blank)
{
char *tim;
tim = ctime(&start_time);
*strchr(tim, '\n') = '\0';
cmdq_print(cmdq, "started %s", tim);
cmdq_print(cmdq, "socket path %s", socket_path);
cmdq_print(cmdq, "debug level %d", debug_level);
cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
}
void
cmd_show_messages_terminals(struct cmd_q *cmdq)
{
struct tty_term *term;
const struct tty_term_code_entry *ent;
struct tty_code *code;
u_int i, n;
char out[80];
struct tty_term *term;
u_int i, n;
n = 0;
LIST_FOREACH(term, &tty_terms, entry) {
cmdq_print(cmdq,
"Terminal %u: %s [references=%u, flags=0x%x]:",
if (blank) {
cmdq_print(cmdq, "%s", "");
blank = 0;
}
cmdq_print(cmdq, "Terminal %u: %s [references=%u, flags=0x%x]:",
n, term->name, term->references, term->flags);
n++;
for (i = 0; i < NTTYCODE; i++) {
ent = &tty_term_codes[i];
code = &term->codes[ent->code];
switch (code->type) {
case TTYCODE_NONE:
cmdq_print(cmdq, "%4u: %s: [missing]",
ent->code, ent->name);
break;
case TTYCODE_STRING:
strnvis(out, code->value.string, sizeof out,
VIS_OCTAL|VIS_TAB|VIS_NL);
cmdq_print(cmdq, "%4u: %s: (string) %s",
ent->code, ent->name, out);
break;
case TTYCODE_NUMBER:
cmdq_print(cmdq, "%4u: %s: (number) %d",
ent->code, ent->name, code->value.number);
break;
case TTYCODE_FLAG:
cmdq_print(cmdq, "%4u: %s: (flag) %s",
ent->code, ent->name,
code->value.flag ? "true" : "false");
break;
}
}
for (i = 0; i < tty_term_ncodes(); i++)
cmdq_print(cmdq, "%s", tty_term_describe(term, i));
}
return (n != 0);
}
void
cmd_show_messages_jobs(struct cmd_q *cmdq)
int
cmd_show_messages_jobs(struct cmd_q *cmdq, int blank)
{
struct job *job;
u_int n;
n = 0;
LIST_FOREACH(job, &all_jobs, lentry) {
cmdq_print(cmdq,
"Job %u: %s [fd=%d, pid=%d, status=%d]",
if (blank) {
cmdq_print(cmdq, "%s", "");
blank = 0;
}
cmdq_print(cmdq, "Job %u: %s [fd=%d, pid=%d, status=%d]",
n, job->cmd, job->fd, job->pid, job->status);
n++;
}
return (n != 0);
}
enum cmd_retval
cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct client *c = cmdq->state.c;
struct message_entry *msg;
char *tim;
u_int i;
int done;
int done, blank;
done = 0;
if (args_has(args, 'I') || self->entry == &cmd_server_info_entry) {
cmd_show_messages_server(cmdq);
done = 1;
}
done = blank = 0;
if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) {
if (done)
cmdq_print(cmdq, "%s", "");
cmd_show_messages_terminals(cmdq);
blank = cmd_show_messages_terminals(cmdq, blank);
done = 1;
}
if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) {
if (done)
cmdq_print(cmdq, "%s", "");
cmd_show_messages_jobs(cmdq);
cmd_show_messages_jobs(cmdq, blank);
done = 1;
}
if (done)
return (CMD_RETURN_NORMAL);
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
msg = &ARRAY_ITEM(&c->message_log, i);
TAILQ_FOREACH(msg, &c->message_log, entry) {
tim = ctime(&msg->msg_time);
*strchr(tim, '\n') = '\0';

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -32,63 +32,80 @@ enum cmd_retval cmd_show_options_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_show_options_one(struct cmd *, struct cmd_q *,
struct options *, int);
enum cmd_retval cmd_show_options_all(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *);
struct options *, enum options_table_scope);
const struct cmd_entry cmd_show_options_entry = {
"show-options", "show",
"gqst:vw", 0, 1,
"[-gqsvw] [-t target-session|target-window] [option]",
0,
cmd_show_options_exec
.name = "show-options",
.alias = "show",
.args = { "gqst:vw", 0, 1 },
.usage = "[-gqsvw] [-t target-session|target-window] [option]",
.tflag = CMD_WINDOW_CANFAIL,
.flags = 0,
.exec = cmd_show_options_exec
};
const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw",
"gvt:", 0, 1,
"[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
0,
cmd_show_options_exec
.name = "show-window-options",
.alias = "showw",
.args = { "gvt:", 0, 1 },
.usage = "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
.tflag = CMD_WINDOW_CANFAIL,
.flags = 0,
.exec = cmd_show_options_exec
};
enum cmd_retval
cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct winlink *wl;
const struct options_table_entry *table;
struct options *oo;
int quiet;
struct args *args = self->args;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct options *oo;
enum options_table_scope scope;
int quiet;
const char *target;
if (args_has(self->args, 's')) {
oo = &global_options;
table = server_options_table;
oo = global_options;
scope = OPTIONS_TABLE_SERVER;
} else if (args_has(self->args, 'w') ||
self->entry == &cmd_show_window_options_entry) {
table = window_options_table;
scope = OPTIONS_TABLE_WINDOW;
if (args_has(self->args, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
if (wl == NULL)
return (CMD_RETURN_ERROR);
oo = &wl->window->options;
}
oo = global_w_options;
else if (wl == NULL) {
target = args_get(args, 't');
if (target != NULL) {
cmdq_error(cmdq, "no such window: %s", target);
} else
cmdq_error(cmdq, "no current window");
return (CMD_RETURN_ERROR);
} else
oo = wl->window->options;
} else {
table = session_options_table;
scope = OPTIONS_TABLE_SESSION;
if (args_has(self->args, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
oo = &s->options;
}
oo = global_s_options;
else if (s == NULL) {
target = args_get(args, 't');
if (target != NULL) {
cmdq_error(cmdq, "no such session: %s", target);
} else
cmdq_error(cmdq, "no current session");
return (CMD_RETURN_ERROR);
} else
oo = s->options;
}
quiet = args_has(self->args, 'q');
if (args->argc == 0)
return (cmd_show_options_all(self, cmdq, table, oo));
return (cmd_show_options_all(self, cmdq, oo, scope));
else
return (cmd_show_options_one(self, cmdq, oo, quiet));
}
@ -99,7 +116,7 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
{
struct args *args = self->args;
const char *name = args->argv[0];
const struct options_table_entry *table, *oe;
const struct options_table_entry *oe;
struct options_entry *o;
const char *optval;
@ -118,14 +135,14 @@ retry:
return (CMD_RETURN_NORMAL);
}
table = oe = NULL;
if (options_table_find(name, &table, &oe) != 0) {
oe = NULL;
if (options_table_find(name, &oe) != 0) {
cmdq_error(cmdq, "ambiguous option: %s", name);
return (CMD_RETURN_ERROR);
}
if (oe == NULL) {
if (quiet)
return (CMD_RETURN_NORMAL);
return (CMD_RETURN_NORMAL);
cmdq_error(cmdq, "unknown option: %s", name);
return (CMD_RETURN_ERROR);
}
@ -144,30 +161,33 @@ retry:
}
enum cmd_retval
cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *table, struct options *oo)
cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq, struct options *oo,
enum options_table_scope scope)
{
const struct options_table_entry *oe;
struct options_entry *o;
const char *optval;
int vflag;
RB_FOREACH(o, options_tree, &oo->tree) {
o = options_first(oo);
while (o != NULL) {
if (*o->name == '@') {
if (args_has(self->args, 'v'))
cmdq_print(cmdq, "%s", o->str);
else
cmdq_print(cmdq, "%s \"%s\"", o->name, o->str);
}
o = options_next(o);
}
for (oe = table; oe->name != NULL; oe++) {
if (oe->style != NULL)
vflag = args_has(self->args, 'v');
for (oe = options_table; oe->name != NULL; oe++) {
if (oe->style != NULL || oe->scope != scope)
continue;
if ((o = options_find1(oo, oe->name)) == NULL)
continue;
optval = options_table_print_entry(oe, o,
args_has(self->args, 'v'));
if (args_has(self->args, 'v'))
optval = options_table_print_entry(oe, o, vflag);
if (vflag)
cmdq_print(cmdq, "%s", optval);
else
cmdq_print(cmdq, "%s %s", oe->name, optval);

View file

@ -31,11 +31,14 @@ enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_q *);
void cmd_source_file_done(struct cmd_q *);
const struct cmd_entry cmd_source_file_entry = {
"source-file", "source",
"", 1, 1,
"path",
0,
cmd_source_file_exec
.name = "source-file",
.alias = "source",
.args = { "", 1, 1 },
.usage = "path",
.flags = 0,
.exec = cmd_source_file_exec
};
enum cmd_retval
@ -45,8 +48,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
struct cmd_q *cmdq1;
char *cause;
cmdq1 = cmdq_new(NULL);
cmdq1->client = cmdq->client;
cmdq1 = cmdq_new(cmdq->client);
cmdq1->emptyfn = cmd_source_file_done;
cmdq1->data = cmdq;

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -35,44 +35,46 @@
enum cmd_retval cmd_split_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"bc:dF:l:hp:Pt:v", 0, -1,
"[-bdhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
CMD_TARGET_PANE_USAGE " [command]",
0,
cmd_split_window_exec
.name = "split-window",
.alias = "splitw",
.args = { "bc:dF:l:hp:Pt:v", 0, -1 },
.usage = "[-bdhvP] [-c start-directory] [-F format] "
"[-p percentage|-l size] " CMD_TARGET_PANE_USAGE " [command]",
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_split_window_exec
};
enum cmd_retval
cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp, *new_wp = NULL;
struct environ env;
const char *cmd, *path, *shell, *template;
struct session *s = cmdq->state.tflag.s;
struct winlink *wl = cmdq->state.tflag.wl;
struct window *w = wl->window;
struct window_pane *wp = cmdq->state.tflag.wp, *new_wp = NULL;
struct environ *env;
const char *cmd, *path, *shell, *template, *cwd, *to_free;
char **argv, *cause, *new_cause, *cp;
u_int hlimit;
int argc, size, percentage, cwd, fd = -1;
int argc, size, percentage;
enum layout_type type;
struct layout_cell *lc;
struct format_tree *ft;
struct environ_entry *envent;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
server_unzoom_window(w);
environ_init(&env);
environ_copy(&global_environ, &env);
environ_copy(&s->environ, &env);
server_fill_environ(s, &env);
env = environ_create();
environ_copy(global_environ, env);
environ_copy(s->environ, env);
server_fill_environ(s, env);
if (args->argc == 0) {
cmd = options_get_string(&s->options, "default-command");
cmd = options_get_string(s->options, "default-command");
if (cmd != NULL && *cmd != '\0') {
argc = 1;
argv = (char **)&cmd;
@ -85,24 +87,12 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
argv = args->argv;
}
to_free = NULL;
if (args_has(args, 'c')) {
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
NULL);
cp = format_expand(ft, args_get(args, 'c'));
ft = format_create(cmdq, 0);
format_defaults(ft, cmdq->state.c, s, NULL, NULL);
to_free = cwd = format_expand(ft, args_get(args, 'c'));
format_free(ft);
if (cp != NULL && *cp != '\0') {
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
} else if (cp != NULL)
free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else
@ -134,9 +124,9 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
else
size = (wp->sx * percentage) / 100;
}
hlimit = options_get_number(&s->options, "history-limit");
hlimit = options_get_number(s->options, "history-limit");
shell = options_get_string(&s->options, "default-shell");
shell = options_get_string(s->options, "default-shell");
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
@ -146,19 +136,19 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
goto error;
}
new_wp = window_add_pane(w, hlimit);
layout_assign_pane(lc, new_wp);
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
envent = environ_find(cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
envent = environ_find(s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, &env,
if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, env,
s->tio, &cause) != 0)
goto error;
layout_assign_pane(lc, new_wp);
server_redraw_window(w);
@ -169,15 +159,14 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
} else
server_status_session(s);
environ_free(&env);
environ_free(env);
if (args_has(args, 'P')) {
if ((template = args_get(args, 'F')) == NULL)
template = SPLIT_WINDOW_TEMPLATE;
ft = format_create();
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
new_wp);
ft = format_create(cmdq, 0);
format_defaults(ft, cmdq->state.c, s, wl, new_wp);
cp = format_expand(ft, template);
cmdq_print(cmdq, "%s", cp);
@ -187,17 +176,20 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
notify_window_layout_changed(w);
if (fd != -1)
close(fd);
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_NORMAL);
error:
environ_free(&env);
if (new_wp != NULL)
environ_free(env);
if (new_wp != NULL) {
layout_close_pane(new_wp);
window_remove_pane(w, new_wp);
}
cmdq_error(cmdq, "create pane failed: %s", cause);
free(cause);
if (fd != -1)
close(fd);
if (to_free != NULL)
free((void *)to_free);
return (CMD_RETURN_ERROR);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -126,7 +126,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
whitespace = argv[0] + strcspn(argv[0], " \t");
if (equals == NULL || equals > whitespace)
break;
environ_put(&global_environ, argv[0]);
environ_put(global_environ, argv[0]);
argc--;
memmove(argv, argv + 1, argc * (sizeof *argv));
}
@ -303,10 +303,14 @@ cmd_string_variable(const char *s, size_t *p)
buf = xrealloc(buf, len + 1);
buf[len] = '\0';
envent = environ_find(&global_environ, buf);
envent = environ_find(global_environ, buf);
free(buf);
if (envent == NULL)
return (xstrdup(""));
#ifdef TMATE
if (envent->value == NULL)
return (xstrdup(""));
#endif
return (xstrdup(envent->value));
error:
@ -326,7 +330,7 @@ cmd_string_expand_tilde(const char *s, size_t *p)
last = cmd_string_getc(s, p);
if (last == EOF || last == '/' || last == ' '|| last == '\t') {
envent = environ_find(&global_environ, "HOME");
envent = environ_find(global_environ, "HOME");
if (envent != NULL && *envent->value != '\0')
home = envent->value;
else if ((pw = getpwuid(getuid())) != NULL)

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,53 +29,53 @@
enum cmd_retval cmd_swap_pane_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp",
"dDs:t:U", 0, 0,
"[-dDU] " CMD_SRCDST_PANE_USAGE,
0,
cmd_swap_pane_exec
.name = "swap-pane",
.alias = "swapp",
.args = { "dDs:t:U", 0, 0 },
.usage = "[-dDU] " CMD_SRCDST_PANE_USAGE,
.sflag = CMD_PANE_MARKED,
.tflag = CMD_PANE,
.flags = 0,
.exec = cmd_swap_pane_exec
};
enum cmd_retval
cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w;
struct window_pane *tmp_wp, *src_wp, *dst_wp;
struct layout_cell *src_lc, *dst_lc;
u_int sx, sy, xoff, yoff;
dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &dst_wp);
if (dst_wl == NULL)
return (CMD_RETURN_ERROR);
dst_w = dst_wl->window;
dst_w = cmdq->state.tflag.wl->window;
dst_wp = cmdq->state.tflag.wp;
src_w = cmdq->state.sflag.wl->window;
src_wp = cmdq->state.sflag.wp;
server_unzoom_window(dst_w);
if (!args_has(args, 's')) {
if (args_has(self->args, 'D')) {
src_w = dst_w;
if (args_has(self->args, 'D')) {
src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes);
} else if (args_has(self->args, 'U')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
} else {
src_wl = cmd_find_pane(cmdq, NULL, NULL, &src_wp);
if (src_wl == NULL)
return (CMD_RETURN_ERROR);
src_w = src_wl->window;
}
} else {
src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
if (src_wl == NULL)
return (CMD_RETURN_ERROR);
src_w = src_wl->window;
src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes);
} else if (args_has(self->args, 'U')) {
src_w = dst_w;
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
}
server_unzoom_window(src_w);
#ifdef TMATE
if (src_w != dst_w) {
cmdq_error(cmdq, "swap pane on different window is not supported with tmate");
return (CMD_RETURN_ERROR);
}
#endif
if (src_wp == dst_wp)
return (CMD_RETURN_NORMAL);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,34 +29,41 @@
enum cmd_retval cmd_swap_window_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw",
"ds:t:", 0, 0,
"[-d] " CMD_SRCDST_WINDOW_USAGE,
0,
cmd_swap_window_exec
.name = "swap-window",
.alias = "swapw",
.args = { "ds:t:", 0, 0 },
.usage = "[-d] " CMD_SRCDST_WINDOW_USAGE,
.sflag = CMD_WINDOW_MARKED,
.tflag = CMD_WINDOW,
.flags = 0,
.exec = cmd_swap_window_exec
};
enum cmd_retval
cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
const char *target_src, *target_dst;
#ifdef TMATE
cmdq_error(cmdq, "swap window is not supported with tmate");
return (CMD_RETURN_ERROR);
#else
struct session *src, *dst;
struct session_group *sg_src, *sg_dst;
struct winlink *wl_src, *wl_dst;
struct window *w;
target_src = args_get(args, 's');
if ((wl_src = cmd_find_window(cmdq, target_src, &src)) == NULL)
return (CMD_RETURN_ERROR);
target_dst = args_get(args, 't');
if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL)
return (CMD_RETURN_ERROR);
wl_src = cmdq->state.sflag.wl;
src = cmdq->state.sflag.s;
sg_src = session_group_find(src);
wl_dst = cmdq->state.tflag.wl;
dst = cmdq->state.tflag.s;
sg_dst = session_group_find(dst);
if (src != dst &&
sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) {
if (src != dst && sg_src != NULL && sg_dst != NULL &&
sg_src == sg_dst) {
cmdq_error(cmdq, "can't move window, sessions are grouped");
return (CMD_RETURN_ERROR);
}
@ -82,4 +89,5 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
recalculate_sizes();
return (CMD_RETURN_NORMAL);
#endif
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -30,35 +30,47 @@
enum cmd_retval cmd_switch_client_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc",
"lc:npt:r", 0, 0,
"[-lnpr] [-c target-client] [-t target-session]",
CMD_READONLY,
cmd_switch_client_exec
.name = "switch-client",
.alias = "switchc",
.args = { "lc:Enpt:rT:", 0, 0 },
.usage = "[-Elnpr] [-c target-client] [-t target-session] "
"[-T key-table]",
.cflag = CMD_CLIENT,
.tflag = CMD_SESSION_WITHPANE,
.flags = CMD_READONLY,
.exec = cmd_switch_client_exec
};
enum cmd_retval
cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct session *s = NULL;
struct winlink *wl = NULL;
struct window *w = NULL;
struct window_pane *wp = NULL;
const char *tflag;
struct cmd_state *state = &cmdq->state;
struct client *c = state->c;
struct session *s = cmdq->state.tflag.s;
struct window_pane *wp;
const char *tablename, *update;
struct key_table *table;
if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
return (CMD_RETURN_ERROR);
if (args_has(args, 'r'))
c->flags ^= CLIENT_READONLY;
if (args_has(args, 'r')) {
if (c->flags & CLIENT_READONLY)
c->flags &= ~CLIENT_READONLY;
else
c->flags |= CLIENT_READONLY;
tablename = args_get(args, 'T');
if (tablename != NULL) {
table = key_bindings_get_table(tablename, 0);
if (table == NULL) {
cmdq_error(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
table->references++;
key_bindings_unref_table(c->keytable);
c->keytable = table;
return (CMD_RETURN_NORMAL);
}
tflag = args_get(args, 't');
if (args_has(args, 'n')) {
if ((s = session_next_session(c->session)) == NULL) {
cmdq_error(cmdq, "can't find next session");
@ -72,47 +84,41 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
} else if (args_has(args, 'l')) {
if (c->last_session != NULL && session_alive(c->last_session))
s = c->last_session;
else
s = NULL;
if (s == NULL) {
cmdq_error(cmdq, "can't find last session");
return (CMD_RETURN_ERROR);
}
} else {
if (tflag == NULL) {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
} else {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
w = cmd_lookup_windowid(tflag);
if (w == NULL &&
(wp = cmd_lookup_paneid(tflag)) != NULL)
w = wp->window;
if (w != NULL)
wl = winlink_find_by_window(&s->windows, w);
}
if (cmdq->client == NULL)
return (CMD_RETURN_NORMAL);
if (wl != NULL) {
if (state->tflag.wl != NULL) {
wp = state->tflag.wp;
if (wp != NULL)
window_set_active_pane(wp->window, wp);
session_set_current(s, wl);
session_set_current(s, state->tflag.wl);
}
}
if (c->session != NULL)
if (c != NULL && !args_has(args, 'E')) {
update = options_get_string(s->options, "update-environment");
environ_update(update, c->environ, s->environ);
}
if (c->session != NULL && c->session != s)
c->last_session = c->session;
c->session = s;
session_update_activity(s);
server_client_set_key_table(c, NULL);
status_timer_start(c);
session_update_activity(s, NULL);
gettimeofday(&s->last_attached_time, NULL);
recalculate_sizes();
server_check_unattached();
server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
alerts_check_session(s);
return (CMD_RETURN_NORMAL);
}

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -26,23 +26,27 @@
* Unbind key from command.
*/
enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_unbind_key_mode_table(struct cmd *, struct cmd_q *, int);
enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmd_q *);
enum cmd_retval cmd_unbind_key_mode_table(struct cmd *, struct cmd_q *,
key_code);
const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind",
"acnt:", 0, 1,
"[-acn] [-t mode-table] key",
0,
cmd_unbind_key_exec
.name = "unbind-key",
.alias = "unbind",
.args = { "acnt:T:", 0, 1 },
.usage = "[-acn] [-t mode-table] [-T key-table] key",
.flags = 0,
.exec = cmd_unbind_key_exec
};
enum cmd_retval
cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct key_binding *bd;
int key;
struct args *args = self->args;
key_code key;
const char *tablename;
if (!args_has(args, 'a')) {
if (args->argc != 1) {
@ -50,7 +54,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
key = key_string_lookup_string(args->argv[0]);
if (key == KEYC_NONE) {
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
return (CMD_RETURN_ERROR);
}
@ -59,28 +63,43 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "key given with -a");
return (CMD_RETURN_ERROR);
}
key = KEYC_NONE;
key = KEYC_UNKNOWN;
}
if (args_has(args, 't'))
return (cmd_unbind_key_mode_table(self, cmdq, key));
if (key == KEYC_NONE) {
while (!RB_EMPTY(&key_bindings)) {
bd = RB_ROOT(&key_bindings);
key_bindings_remove(bd->key);
if (key == KEYC_UNKNOWN) {
tablename = args_get(args, 'T');
if (tablename == NULL) {
key_bindings_remove_table("root");
key_bindings_remove_table("prefix");
return (CMD_RETURN_NORMAL);
}
if (key_bindings_get_table(tablename, 0) == NULL) {
cmdq_error(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
key_bindings_remove_table(tablename);
return (CMD_RETURN_NORMAL);
}
if (!args_has(args, 'n'))
key |= KEYC_PREFIX;
key_bindings_remove(key);
if (args_has(args, 'T')) {
tablename = args_get(args, 'T');
if (key_bindings_get_table(tablename, 0) == NULL) {
cmdq_error(cmdq, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
} else if (args_has(args, 'n'))
tablename = "root";
else
tablename = "prefix";
key_bindings_remove(tablename, key);
return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
{
struct args *args = self->args;
const char *tablename;
@ -93,7 +112,7 @@ cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
return (CMD_RETURN_ERROR);
}
if (key == KEYC_NONE) {
if (key == KEYC_UNKNOWN) {
while (!RB_EMPTY(mtab->tree)) {
mbind = RB_ROOT(mtab->tree);
RB_REMOVE(mode_key_tree, mtab->tree, mbind);

View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
* Copyright (c) 2013 Thiago de Arruda <tpadilha84@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
@ -23,6 +23,7 @@
#include <string.h>
#include "tmux.h"
#include "tmate.h"
/*
* Block or wake a client on a named wait channel.
@ -31,16 +32,20 @@
enum cmd_retval cmd_wait_for_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_wait_for_entry = {
"wait-for", "wait",
"LSU", 1, 1,
"[-L|-S|-U] channel",
0,
cmd_wait_for_exec
.name = "wait-for",
.alias = "wait",
.args = { "LSU", 1, 1 },
.usage = "[-L|-S|-U] channel",
.flags = 0,
.exec = cmd_wait_for_exec
};
struct wait_channel {
const char *name;
int locked;
int woken;
TAILQ_HEAD(, cmd_q) waiters;
TAILQ_HEAD(, cmd_q) lockers;
@ -69,6 +74,46 @@ enum cmd_retval cmd_wait_for_lock(struct cmd_q *, const char *,
enum cmd_retval cmd_wait_for_unlock(struct cmd_q *, const char *,
struct wait_channel *);
struct wait_channel *cmd_wait_for_add(const char *);
void cmd_wait_for_remove(struct wait_channel *wc);
struct wait_channel *
cmd_wait_for_add(const char *name)
{
struct wait_channel *wc;
wc = xmalloc(sizeof *wc);
wc->name = xstrdup(name);
wc->locked = 0;
wc->woken = 0;
TAILQ_INIT(&wc->waiters);
TAILQ_INIT(&wc->lockers);
RB_INSERT(wait_channels, &wait_channels, wc);
log_debug("add wait channel %s", wc->name);
return (wc);
}
void
cmd_wait_for_remove(struct wait_channel *wc)
{
if (wc->locked)
return;
if (!TAILQ_EMPTY(&wc->waiters) || !wc->woken)
return;
log_debug("remove wait channel %s", wc->name);
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void *)wc->name);
free(wc);
}
enum cmd_retval
cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)
{
@ -89,14 +134,42 @@ cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)
}
enum cmd_retval
cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,
cmd_wait_for_signal(__unused struct cmd_q *cmdq, const char *name,
struct wait_channel *wc)
{
struct cmd_q *wq, *wq1;
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (TAILQ_EMPTY(&wc->waiters) && !wc->woken) {
log_debug("signal wait channel %s, no waiters", wc->name);
wc->woken = 1;
return (CMD_RETURN_NORMAL);
}
log_debug("signal wait channel %s, with waiters", wc->name);
TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {
TAILQ_REMOVE(&wc->waiters, wq, waitentry);
if (!cmdq_free(wq))
cmdq_continue(wq);
}
cmd_wait_for_remove(wc);
return (CMD_RETURN_NORMAL);
}
#ifdef TMATE
void signal_waiting_clients(const char *name)
{
struct wait_channel *wc, wc0;
struct cmd_q *wq, *wq1;
wc0.name = name;
wc = RB_FIND(wait_channels, &wait_channels, &wc0);
if (wc == NULL || TAILQ_EMPTY(&wc->waiters)) {
cmdq_error(cmdq, "no waiting clients on %s", name);
return (CMD_RETURN_ERROR);
return;
}
TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {
@ -107,30 +180,37 @@ cmd_wait_for_signal(struct cmd_q *cmdq, const char *name,
if (!wc->locked) {
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void *)wc->name);
free((void*) wc->name);
free(wc);
}
return (CMD_RETURN_NORMAL);
}
#endif
enum cmd_retval
cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
struct wait_channel *wc)
{
if (cmdq->client == NULL || cmdq->client->session != NULL) {
struct client *c = cmdq->client;
#ifdef TMATE
if (!strcmp(name, "tmate-ready") && tmate_session.tmate_env_ready)
return (CMD_RETURN_NORMAL);
#endif
if (c == NULL || c->session != NULL) {
cmdq_error(cmdq, "not able to wait");
return (CMD_RETURN_ERROR);
}
if (wc == NULL) {
wc = xmalloc(sizeof *wc);
wc->name = xstrdup(name);
wc->locked = 0;
TAILQ_INIT(&wc->waiters);
TAILQ_INIT(&wc->lockers);
RB_INSERT(wait_channels, &wait_channels, wc);
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (wc->woken) {
log_debug("wait channel %s already woken (%p)", wc->name, c);
cmd_wait_for_remove(wc);
return (CMD_RETURN_NORMAL);
}
log_debug("wait channel %s not woken (%p)", wc->name, c);
TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry);
cmdq->references++;
@ -147,14 +227,8 @@ cmd_wait_for_lock(struct cmd_q *cmdq, const char *name,
return (CMD_RETURN_ERROR);
}
if (wc == NULL) {
wc = xmalloc(sizeof *wc);
wc->name = xstrdup(name);
wc->locked = 0;
TAILQ_INIT(&wc->waiters);
TAILQ_INIT(&wc->lockers);
RB_INSERT(wait_channels, &wait_channels, wc);
}
if (wc == NULL)
wc = cmd_wait_for_add(name);
if (wc->locked) {
TAILQ_INSERT_TAIL(&wc->lockers, cmdq, waitentry);
@ -183,11 +257,7 @@ cmd_wait_for_unlock(struct cmd_q *cmdq, const char *name,
cmdq_continue(wq);
} else {
wc->locked = 0;
if (TAILQ_EMPTY(&wc->waiters)) {
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void *)wc->name);
free(wc);
}
cmd_wait_for_remove(wc);
}
return (CMD_RETURN_NORMAL);
@ -205,13 +275,13 @@ cmd_wait_for_flush(void)
if (!cmdq_free(wq))
cmdq_continue(wq);
}
while ((wq = TAILQ_FIRST(&wc->lockers)) != NULL) {
wc->woken = 1;
TAILQ_FOREACH_SAFE(wq, &wc->lockers, waitentry, wq1) {
TAILQ_REMOVE(&wc->lockers, wq, waitentry);
if (!cmdq_free(wq))
cmdq_continue(wq);
}
RB_REMOVE(wait_channels, &wait_channels, wc);
free((void *)wc->name);
free(wc);
wc->locked = 0;
cmd_wait_for_remove(wc);
}
}

1290
cmd.c

File diff suppressed because it is too large Load diff

396
colour.c
View file

@ -1,7 +1,7 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -29,91 +29,305 @@
* of the 256 colour palette.
*/
/* An RGB colour. */
struct colour_rgb {
u_char i;
u_char r;
u_char g;
u_char b;
};
/* 256 colour RGB table, generated on first use. */
struct colour_rgb *colour_rgb_256;
const struct colour_rgb colour_from_256[] = {
{ 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
{ 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
{ 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
{ 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
{ 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
{ 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
{ 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
{ 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
{ 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
{ 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
{ 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
{ 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
{ 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
{ 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
{ 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
{ 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
{ 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
{ 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
{ 36, 0x5f, 0x00, 0x00 }, { 37, 0x5f, 0x00, 0x5f },
{ 38, 0x5f, 0x00, 0x87 }, { 39, 0x5f, 0x00, 0xaf },
{ 40, 0x5f, 0x00, 0xd7 }, { 41, 0x5f, 0x00, 0xff },
{ 42, 0x5f, 0x5f, 0x00 }, { 43, 0x5f, 0x5f, 0x5f },
{ 44, 0x5f, 0x5f, 0x87 }, { 45, 0x5f, 0x5f, 0xaf },
{ 46, 0x5f, 0x5f, 0xd7 }, { 47, 0x5f, 0x5f, 0xff },
{ 48, 0x5f, 0x87, 0x00 }, { 49, 0x5f, 0x87, 0x5f },
{ 50, 0x5f, 0x87, 0x87 }, { 51, 0x5f, 0x87, 0xaf },
{ 52, 0x5f, 0x87, 0xd7 }, { 53, 0x5f, 0x87, 0xff },
{ 54, 0x5f, 0xaf, 0x00 }, { 55, 0x5f, 0xaf, 0x5f },
{ 56, 0x5f, 0xaf, 0x87 }, { 57, 0x5f, 0xaf, 0xaf },
{ 58, 0x5f, 0xaf, 0xd7 }, { 59, 0x5f, 0xaf, 0xff },
{ 60, 0x5f, 0xd7, 0x00 }, { 61, 0x5f, 0xd7, 0x5f },
{ 62, 0x5f, 0xd7, 0x87 }, { 63, 0x5f, 0xd7, 0xaf },
{ 64, 0x5f, 0xd7, 0xd7 }, { 65, 0x5f, 0xd7, 0xff },
{ 66, 0x5f, 0xff, 0x00 }, { 67, 0x5f, 0xff, 0x5f },
{ 68, 0x5f, 0xff, 0x87 }, { 69, 0x5f, 0xff, 0xaf },
{ 70, 0x5f, 0xff, 0xd7 }, { 71, 0x5f, 0xff, 0xff },
{ 72, 0x87, 0x00, 0x00 }, { 73, 0x87, 0x00, 0x5f },
{ 74, 0x87, 0x00, 0x87 }, { 75, 0x87, 0x00, 0xaf },
{ 76, 0x87, 0x00, 0xd7 }, { 77, 0x87, 0x00, 0xff },
{ 78, 0x87, 0x5f, 0x00 }, { 79, 0x87, 0x5f, 0x5f },
{ 80, 0x87, 0x5f, 0x87 }, { 81, 0x87, 0x5f, 0xaf },
{ 82, 0x87, 0x5f, 0xd7 }, { 83, 0x87, 0x5f, 0xff },
{ 84, 0x87, 0x87, 0x00 }, { 85, 0x87, 0x87, 0x5f },
{ 86, 0x87, 0x87, 0x87 }, { 87, 0x87, 0x87, 0xaf },
{ 88, 0x87, 0x87, 0xd7 }, { 89, 0x87, 0x87, 0xff },
{ 90, 0x87, 0xaf, 0x00 }, { 91, 0x87, 0xaf, 0x5f },
{ 92, 0x87, 0xaf, 0x87 }, { 93, 0x87, 0xaf, 0xaf },
{ 94, 0x87, 0xaf, 0xd7 }, { 95, 0x87, 0xaf, 0xff },
{ 96, 0x87, 0xd7, 0x00 }, { 97, 0x87, 0xd7, 0x5f },
{ 98, 0x87, 0xd7, 0x87 }, { 99, 0x87, 0xd7, 0xaf },
{ 100, 0x87, 0xd7, 0xd7 }, { 101, 0x87, 0xd7, 0xff },
{ 102, 0x87, 0xff, 0x00 }, { 103, 0x87, 0xff, 0x5f },
{ 104, 0x87, 0xff, 0x87 }, { 105, 0x87, 0xff, 0xaf },
{ 106, 0x87, 0xff, 0xd7 }, { 107, 0x87, 0xff, 0xff },
{ 108, 0xaf, 0x00, 0x00 }, { 109, 0xaf, 0x00, 0x5f },
{ 110, 0xaf, 0x00, 0x87 }, { 111, 0xaf, 0x00, 0xaf },
{ 112, 0xaf, 0x00, 0xd7 }, { 113, 0xaf, 0x00, 0xff },
{ 114, 0xaf, 0x5f, 0x00 }, { 115, 0xaf, 0x5f, 0x5f },
{ 116, 0xaf, 0x5f, 0x87 }, { 117, 0xaf, 0x5f, 0xaf },
{ 118, 0xaf, 0x5f, 0xd7 }, { 119, 0xaf, 0x5f, 0xff },
{ 120, 0xaf, 0x87, 0x00 }, { 121, 0xaf, 0x87, 0x5f },
{ 122, 0xaf, 0x87, 0x87 }, { 123, 0xaf, 0x87, 0xaf },
{ 124, 0xaf, 0x87, 0xd7 }, { 125, 0xaf, 0x87, 0xff },
{ 126, 0xaf, 0xaf, 0x00 }, { 127, 0xaf, 0xaf, 0x5f },
{ 128, 0xaf, 0xaf, 0x87 }, { 129, 0xaf, 0xaf, 0xaf },
{ 130, 0xaf, 0xaf, 0xd7 }, { 131, 0xaf, 0xaf, 0xff },
{ 132, 0xaf, 0xd7, 0x00 }, { 133, 0xaf, 0xd7, 0x5f },
{ 134, 0xaf, 0xd7, 0x87 }, { 135, 0xaf, 0xd7, 0xaf },
{ 136, 0xaf, 0xd7, 0xd7 }, { 137, 0xaf, 0xd7, 0xff },
{ 138, 0xaf, 0xff, 0x00 }, { 139, 0xaf, 0xff, 0x5f },
{ 140, 0xaf, 0xff, 0x87 }, { 141, 0xaf, 0xff, 0xaf },
{ 142, 0xaf, 0xff, 0xd7 }, { 143, 0xaf, 0xff, 0xff },
{ 144, 0xd7, 0x00, 0x00 }, { 145, 0xd7, 0x00, 0x5f },
{ 146, 0xd7, 0x00, 0x87 }, { 147, 0xd7, 0x00, 0xaf },
{ 148, 0xd7, 0x00, 0xd7 }, { 149, 0xd7, 0x00, 0xff },
{ 150, 0xd7, 0x5f, 0x00 }, { 151, 0xd7, 0x5f, 0x5f },
{ 152, 0xd7, 0x5f, 0x87 }, { 153, 0xd7, 0x5f, 0xaf },
{ 154, 0xd7, 0x5f, 0xd7 }, { 155, 0xd7, 0x5f, 0xff },
{ 156, 0xd7, 0x87, 0x00 }, { 157, 0xd7, 0x87, 0x5f },
{ 158, 0xd7, 0x87, 0x87 }, { 159, 0xd7, 0x87, 0xaf },
{ 160, 0xd7, 0x87, 0xd7 }, { 161, 0xd7, 0x87, 0xff },
{ 162, 0xd7, 0xaf, 0x00 }, { 163, 0xd7, 0xaf, 0x5f },
{ 164, 0xd7, 0xaf, 0x87 }, { 165, 0xd7, 0xaf, 0xaf },
{ 166, 0xd7, 0xaf, 0xd7 }, { 167, 0xd7, 0xaf, 0xff },
{ 168, 0xd7, 0xd7, 0x00 }, { 169, 0xd7, 0xd7, 0x5f },
{ 170, 0xd7, 0xd7, 0x87 }, { 171, 0xd7, 0xd7, 0xaf },
{ 172, 0xd7, 0xd7, 0xd7 }, { 173, 0xd7, 0xd7, 0xff },
{ 174, 0xd7, 0xff, 0x00 }, { 175, 0xd7, 0xff, 0x5f },
{ 176, 0xd7, 0xff, 0x87 }, { 177, 0xd7, 0xff, 0xaf },
{ 178, 0xd7, 0xff, 0xd7 }, { 179, 0xd7, 0xff, 0xff },
{ 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
{ 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
{ 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
{ 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
{ 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
{ 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
{ 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
{ 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
{ 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
{ 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
{ 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
{ 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
{ 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
{ 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
{ 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
{ 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
{ 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
{ 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
{ 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
{ 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
{ 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
{ 224, 0x58, 0x58, 0x58 }, { 225, 0x62, 0x62, 0x62 },
{ 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
{ 228, 0x80, 0x80, 0x80 }, { 229, 0x8a, 0x8a, 0x8a },
{ 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
{ 232, 0xa8, 0xa8, 0xa8 }, { 233, 0xb2, 0xb2, 0xb2 },
{ 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
{ 236, 0xd0, 0xd0, 0xd0 }, { 237, 0xda, 0xda, 0xda },
{ 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
};
const struct colour_rgb colour_to_256[] = {
{ 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
{ 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
{ 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
{ 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
{ 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
{ 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
{ 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
{ 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
{ 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
{ 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
{ 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
{ 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
{ 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
{ 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
{ 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
{ 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
{ 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
{ 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
{ 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
{ 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
{ 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
{ 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
{ 224, 0x58, 0x58, 0x58 }, { 36, 0x5f, 0x00, 0x00 },
{ 37, 0x5f, 0x00, 0x5f }, { 38, 0x5f, 0x00, 0x87 },
{ 39, 0x5f, 0x00, 0xaf }, { 40, 0x5f, 0x00, 0xd7 },
{ 41, 0x5f, 0x00, 0xff }, { 42, 0x5f, 0x5f, 0x00 },
{ 43, 0x5f, 0x5f, 0x5f }, { 44, 0x5f, 0x5f, 0x87 },
{ 45, 0x5f, 0x5f, 0xaf }, { 46, 0x5f, 0x5f, 0xd7 },
{ 47, 0x5f, 0x5f, 0xff }, { 48, 0x5f, 0x87, 0x00 },
{ 49, 0x5f, 0x87, 0x5f }, { 50, 0x5f, 0x87, 0x87 },
{ 51, 0x5f, 0x87, 0xaf }, { 52, 0x5f, 0x87, 0xd7 },
{ 53, 0x5f, 0x87, 0xff }, { 54, 0x5f, 0xaf, 0x00 },
{ 55, 0x5f, 0xaf, 0x5f }, { 56, 0x5f, 0xaf, 0x87 },
{ 57, 0x5f, 0xaf, 0xaf }, { 58, 0x5f, 0xaf, 0xd7 },
{ 59, 0x5f, 0xaf, 0xff }, { 60, 0x5f, 0xd7, 0x00 },
{ 61, 0x5f, 0xd7, 0x5f }, { 62, 0x5f, 0xd7, 0x87 },
{ 63, 0x5f, 0xd7, 0xaf }, { 64, 0x5f, 0xd7, 0xd7 },
{ 65, 0x5f, 0xd7, 0xff }, { 66, 0x5f, 0xff, 0x00 },
{ 67, 0x5f, 0xff, 0x5f }, { 68, 0x5f, 0xff, 0x87 },
{ 69, 0x5f, 0xff, 0xaf }, { 70, 0x5f, 0xff, 0xd7 },
{ 71, 0x5f, 0xff, 0xff }, { 225, 0x62, 0x62, 0x62 },
{ 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
{ 228, 0x80, 0x80, 0x80 }, { 72, 0x87, 0x00, 0x00 },
{ 73, 0x87, 0x00, 0x5f }, { 74, 0x87, 0x00, 0x87 },
{ 75, 0x87, 0x00, 0xaf }, { 76, 0x87, 0x00, 0xd7 },
{ 77, 0x87, 0x00, 0xff }, { 78, 0x87, 0x5f, 0x00 },
{ 79, 0x87, 0x5f, 0x5f }, { 80, 0x87, 0x5f, 0x87 },
{ 81, 0x87, 0x5f, 0xaf }, { 82, 0x87, 0x5f, 0xd7 },
{ 83, 0x87, 0x5f, 0xff }, { 84, 0x87, 0x87, 0x00 },
{ 85, 0x87, 0x87, 0x5f }, { 86, 0x87, 0x87, 0x87 },
{ 87, 0x87, 0x87, 0xaf }, { 88, 0x87, 0x87, 0xd7 },
{ 89, 0x87, 0x87, 0xff }, { 90, 0x87, 0xaf, 0x00 },
{ 91, 0x87, 0xaf, 0x5f }, { 92, 0x87, 0xaf, 0x87 },
{ 93, 0x87, 0xaf, 0xaf }, { 94, 0x87, 0xaf, 0xd7 },
{ 95, 0x87, 0xaf, 0xff }, { 96, 0x87, 0xd7, 0x00 },
{ 97, 0x87, 0xd7, 0x5f }, { 98, 0x87, 0xd7, 0x87 },
{ 99, 0x87, 0xd7, 0xaf }, { 100, 0x87, 0xd7, 0xd7 },
{ 101, 0x87, 0xd7, 0xff }, { 102, 0x87, 0xff, 0x00 },
{ 103, 0x87, 0xff, 0x5f }, { 104, 0x87, 0xff, 0x87 },
{ 105, 0x87, 0xff, 0xaf }, { 106, 0x87, 0xff, 0xd7 },
{ 107, 0x87, 0xff, 0xff }, { 229, 0x8a, 0x8a, 0x8a },
{ 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
{ 232, 0xa8, 0xa8, 0xa8 }, { 108, 0xaf, 0x00, 0x00 },
{ 109, 0xaf, 0x00, 0x5f }, { 110, 0xaf, 0x00, 0x87 },
{ 111, 0xaf, 0x00, 0xaf }, { 112, 0xaf, 0x00, 0xd7 },
{ 113, 0xaf, 0x00, 0xff }, { 114, 0xaf, 0x5f, 0x00 },
{ 115, 0xaf, 0x5f, 0x5f }, { 116, 0xaf, 0x5f, 0x87 },
{ 117, 0xaf, 0x5f, 0xaf }, { 118, 0xaf, 0x5f, 0xd7 },
{ 119, 0xaf, 0x5f, 0xff }, { 120, 0xaf, 0x87, 0x00 },
{ 121, 0xaf, 0x87, 0x5f }, { 122, 0xaf, 0x87, 0x87 },
{ 123, 0xaf, 0x87, 0xaf }, { 124, 0xaf, 0x87, 0xd7 },
{ 125, 0xaf, 0x87, 0xff }, { 126, 0xaf, 0xaf, 0x00 },
{ 127, 0xaf, 0xaf, 0x5f }, { 128, 0xaf, 0xaf, 0x87 },
{ 129, 0xaf, 0xaf, 0xaf }, { 130, 0xaf, 0xaf, 0xd7 },
{ 131, 0xaf, 0xaf, 0xff }, { 132, 0xaf, 0xd7, 0x00 },
{ 133, 0xaf, 0xd7, 0x5f }, { 134, 0xaf, 0xd7, 0x87 },
{ 135, 0xaf, 0xd7, 0xaf }, { 136, 0xaf, 0xd7, 0xd7 },
{ 137, 0xaf, 0xd7, 0xff }, { 138, 0xaf, 0xff, 0x00 },
{ 139, 0xaf, 0xff, 0x5f }, { 140, 0xaf, 0xff, 0x87 },
{ 141, 0xaf, 0xff, 0xaf }, { 142, 0xaf, 0xff, 0xd7 },
{ 143, 0xaf, 0xff, 0xff }, { 233, 0xb2, 0xb2, 0xb2 },
{ 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
{ 236, 0xd0, 0xd0, 0xd0 }, { 144, 0xd7, 0x00, 0x00 },
{ 145, 0xd7, 0x00, 0x5f }, { 146, 0xd7, 0x00, 0x87 },
{ 147, 0xd7, 0x00, 0xaf }, { 148, 0xd7, 0x00, 0xd7 },
{ 149, 0xd7, 0x00, 0xff }, { 150, 0xd7, 0x5f, 0x00 },
{ 151, 0xd7, 0x5f, 0x5f }, { 152, 0xd7, 0x5f, 0x87 },
{ 153, 0xd7, 0x5f, 0xaf }, { 154, 0xd7, 0x5f, 0xd7 },
{ 155, 0xd7, 0x5f, 0xff }, { 156, 0xd7, 0x87, 0x00 },
{ 157, 0xd7, 0x87, 0x5f }, { 158, 0xd7, 0x87, 0x87 },
{ 159, 0xd7, 0x87, 0xaf }, { 160, 0xd7, 0x87, 0xd7 },
{ 161, 0xd7, 0x87, 0xff }, { 162, 0xd7, 0xaf, 0x00 },
{ 163, 0xd7, 0xaf, 0x5f }, { 164, 0xd7, 0xaf, 0x87 },
{ 165, 0xd7, 0xaf, 0xaf }, { 166, 0xd7, 0xaf, 0xd7 },
{ 167, 0xd7, 0xaf, 0xff }, { 168, 0xd7, 0xd7, 0x00 },
{ 169, 0xd7, 0xd7, 0x5f }, { 170, 0xd7, 0xd7, 0x87 },
{ 171, 0xd7, 0xd7, 0xaf }, { 172, 0xd7, 0xd7, 0xd7 },
{ 173, 0xd7, 0xd7, 0xff }, { 174, 0xd7, 0xff, 0x00 },
{ 175, 0xd7, 0xff, 0x5f }, { 176, 0xd7, 0xff, 0x87 },
{ 177, 0xd7, 0xff, 0xaf }, { 178, 0xd7, 0xff, 0xd7 },
{ 179, 0xd7, 0xff, 0xff }, { 237, 0xda, 0xda, 0xda },
{ 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
{ 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
{ 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
{ 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
{ 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
{ 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
{ 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
{ 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
{ 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
{ 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
{ 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
{ 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
{ 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
{ 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
{ 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
{ 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
{ 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
{ 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
{ 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
};
void colour_rgb_generate256(void);
u_int colour_rgb_distance(struct colour_rgb *, struct colour_rgb *);
int colour_rgb_find(struct colour_rgb *);
int colour_cmp_rgb(const void *, const void *);
/* Generate 256 colour RGB table. */
void
colour_rgb_generate256(void)
/* Compare function for bsearch(). */
int
colour_cmp_rgb(const void *lhs0, const void *rhs0)
{
struct colour_rgb *rgb;
u_int i, r, g, b;
const struct colour_rgb *lhs = lhs0, *rhs = rhs0;
/*
* Allocate the table. The first 16 colours are often changed by users
* and terminals so don't include them.
*/
colour_rgb_256 = xcalloc(240, sizeof *colour_rgb_256);
if (lhs->r < rhs->r)
return (-1);
if (lhs->r > rhs->r)
return (1);
/* Add the colours first. */
r = g = b = 0;
for (i = 240; i > 24; i--) {
rgb = &colour_rgb_256[240 - i];
if (lhs->g < rhs->g)
return (-1);
if (lhs->g > rhs->g)
return (1);
if (r != 0)
rgb->r = (r * 40) + 55;
if (g != 0)
rgb->g = (g * 40) + 55;
if (b != 0)
rgb->b = (b * 40) + 55;
if (lhs->b < rhs->b)
return (-1);
if (lhs->b > rhs->b)
return (1);
b++;
if (b > 5) {
b = 0;
g++;
}
if (g > 5) {
g = 0;
r++;
}
}
/* Then add the greys. */
for (i = 24; i > 0; i--) {
rgb = &colour_rgb_256[240 - i];
rgb->r = 8 + (24 - i) * 10;
rgb->g = 8 + (24 - i) * 10;
rgb->b = 8 + (24 - i) * 10;
}
}
/* Get colour RGB distance. */
u_int
colour_rgb_distance(struct colour_rgb *rgb1, struct colour_rgb *rgb2)
{
int r, g, b;
r = rgb1->r - rgb2->r;
g = rgb1->g - rgb2->g;
b = rgb1->b - rgb2->b;
return (r * r + g * g + b * b);
return (0);
}
/* Work out the nearest colour from the 256 colour set. */
int
colour_rgb_find(struct colour_rgb *rgb)
colour_find_rgb(u_char r, u_char g, u_char b)
{
u_int distance, lowest, colour, i;
struct colour_rgb rgb = { .r = r, .g = g, .b = b }, *found;
u_int distance, lowest, colour, i;
int dr, dg, db;
if (colour_rgb_256 == NULL)
colour_rgb_generate256();
found = bsearch(&rgb, colour_to_256, nitems(colour_to_256),
sizeof colour_to_256[0], colour_cmp_rgb);
if (found != NULL)
return (16 + found->i);
colour = 16;
lowest = UINT_MAX;
for (i = 0; i < 240; i++) {
distance = colour_rgb_distance(&colour_rgb_256[i], rgb);
dr = (int)colour_from_256[i].r - r;
dg = (int)colour_from_256[i].g - g;
db = (int)colour_from_256[i].b - b;
distance = dr * dr + dg * dg + db * db;
if (distance < lowest) {
lowest = distance;
colour = 16 + i;
@ -147,7 +361,7 @@ colour_tostring(int c)
static char s[32];
if (c & 0x100) {
xsnprintf(s, sizeof s, "colour%u", c & ~0x100);
xsnprintf(s, sizeof s, "colour%d", c & ~0x100);
return (s);
}
@ -194,20 +408,20 @@ colour_tostring(int c)
int
colour_fromstring(const char *s)
{
const char *errstr;
const char *cp;
struct colour_rgb rgb;
int n;
const char *errstr;
const char *cp;
int n;
u_char r, g, b;
if (*s == '#' && strlen(s) == 7) {
for (cp = s + 1; isxdigit((u_char) *cp); cp++)
;
if (*cp != '\0')
return (-1);
n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &rgb.r, &rgb.g, &rgb.b);
n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
if (n != 3)
return (-1);
return (colour_rgb_find(&rgb) | 0x100);
return (colour_find_rgb(r, g, b) | 0x100);
}
if (strncasecmp(s, "colour", (sizeof "colour") - 1) == 0) {
@ -217,47 +431,39 @@ colour_fromstring(const char *s)
return (n | 0x100);
}
if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0'))
if (strcasecmp(s, "black") == 0 || strcmp(s, "0") == 0)
return (0);
if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0'))
if (strcasecmp(s, "red") == 0 || strcmp(s, "1") == 0)
return (1);
if (strcasecmp(s, "green") == 0 || (s[0] == '2' && s[1] == '\0'))
if (strcasecmp(s, "green") == 0 || strcmp(s, "2") == 0)
return (2);
if (strcasecmp(s, "yellow") == 0 || (s[0] == '3' && s[1] == '\0'))
if (strcasecmp(s, "yellow") == 0 || strcmp(s, "3") == 0)
return (3);
if (strcasecmp(s, "blue") == 0 || (s[0] == '4' && s[1] == '\0'))
if (strcasecmp(s, "blue") == 0 || strcmp(s, "4") == 0)
return (4);
if (strcasecmp(s, "magenta") == 0 || (s[0] == '5' && s[1] == '\0'))
if (strcasecmp(s, "magenta") == 0 || strcmp(s, "5") == 0)
return (5);
if (strcasecmp(s, "cyan") == 0 || (s[0] == '6' && s[1] == '\0'))
if (strcasecmp(s, "cyan") == 0 || strcmp(s, "6") == 0)
return (6);
if (strcasecmp(s, "white") == 0 || (s[0] == '7' && s[1] == '\0'))
if (strcasecmp(s, "white") == 0 || strcmp(s, "7") == 0)
return (7);
if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0'))
if (strcasecmp(s, "default") == 0 || strcmp(s, "8") == 0)
return (8);
if (strcasecmp(s, "brightblack") == 0 ||
(s[0] == '9' && s[1] == '0' && s[2] == '\0'))
if (strcasecmp(s, "brightblack") == 0 || strcmp(s, "90") == 0)
return (90);
if (strcasecmp(s, "brightred") == 0 ||
(s[0] == '9' && s[1] == '1' && s[2] == '\0'))
if (strcasecmp(s, "brightred") == 0 || strcmp(s, "91") == 0)
return (91);
if (strcasecmp(s, "brightgreen") == 0 ||
(s[0] == '9' && s[1] == '2' && s[2] == '\0'))
if (strcasecmp(s, "brightgreen") == 0 || strcmp(s, "92") == 0)
return (92);
if (strcasecmp(s, "brightyellow") == 0 ||
(s[0] == '9' && s[1] == '3' && s[2] == '\0'))
if (strcasecmp(s, "brightyellow") == 0 || strcmp(s, "93") == 0)
return (93);
if (strcasecmp(s, "brightblue") == 0 ||
(s[0] == '9' && s[1] == '4' && s[2] == '\0'))
if (strcasecmp(s, "brightblue") == 0 || strcmp(s, "94") == 0)
return (94);
if (strcasecmp(s, "brightmagenta") == 0 ||
(s[0] == '9' && s[1] == '5' && s[2] == '\0'))
if (strcasecmp(s, "brightmagenta") == 0 || strcmp(s, "95") == 0)
return (95);
if (strcasecmp(s, "brightcyan") == 0 ||
(s[0] == '9' && s[1] == '6' && s[2] == '\0'))
if (strcasecmp(s, "brightcyan") == 0 || strcmp(s, "96") == 0)
return (96);
if (strcasecmp(s, "brightwhite") == 0 ||
(s[0] == '9' && s[1] == '7' && s[2] == '\0'))
if (strcasecmp(s, "brightwhite") == 0 || strcmp(s, "97") == 0)
return (97);
return (-1);
}

View file

@ -1,7 +1,5 @@
/* $Id$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -23,6 +21,9 @@
#define __attribute__(a)
#endif
#ifndef __unused
#define __unused __attribute__ ((__unused__))
#endif
#ifndef __dead
#define __dead __attribute__ ((__noreturn__))
#endif
@ -187,11 +188,6 @@ typedef uint64_t u_int64_t;
#define flock(fd, op) (0)
#endif
#ifndef HAVE_BZERO
#undef bzero
#define bzero(buf, len) memset(buf, 0, len);
#endif
#ifndef HAVE_CLOSEFROM
/* closefrom.c */
void closefrom(int);
@ -262,13 +258,18 @@ int unsetenv(const char *);
#ifndef HAVE_CFMAKERAW
/* cfmakeraw.c */
void cfmakeraw(struct termios *);
void cfmakeraw(struct termios *);
#endif
#ifndef HAVE_OPENAT
/* openat.c */
#define AT_FDCWD -100
int openat(int, const char *, int, ...);
int openat(int, const char *, int, ...);
#endif
#ifndef HAVE_REALLOCARRAY
/* reallocarray.c */
void *reallocarray(void *, size_t, size_t size);
#endif
#ifdef HAVE_GETOPT

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2006 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above

View file

@ -52,6 +52,8 @@
#include <stdlib.h>
#include <string.h>
#include "compat.h"
#define Assert(Cond) if (!(Cond)) abort()
static const char Base64[] =
@ -122,7 +124,7 @@ static const char Pad64 = '=';
*/
int
b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
b64_ntop(const char *src, size_t srclength, char *target, size_t targsize) {
size_t datalength = 0;
uint8_t input[3];
uint8_t output[4];

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013 Dagobert Michelsen
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above

View file

@ -14,8 +14,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "tmux.h"
#ifndef HAVE_CLOSEFROM
#include <sys/types.h>
@ -47,6 +45,8 @@
# endif
#endif
#include "tmux.h"
#ifndef OPEN_MAX
# define OPEN_MAX 256
#endif

View file

@ -1,43 +1,26 @@
/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
/*
* Copyright (c) 2015 Joerg Jung <jung@openbsd.org>
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
* 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.
*
* 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 NetBSD Foundation 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
/*
* portable fgetln() version, NOT reentrant
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "tmux.h"
@ -45,41 +28,34 @@ char *
fgetln(FILE *fp, size_t *len)
{
static char *buf = NULL;
static size_t bufsiz = 0;
char *ptr;
static size_t bufsz = 0;
size_t r = 0;
char *p;
int c, e;
if (buf == NULL) {
bufsiz = BUFSIZ;
if ((buf = malloc(bufsiz)) == NULL)
return NULL;
}
if (fgets(buf, bufsiz, fp) == NULL)
if (!fp || !len) {
errno = EINVAL;
return NULL;
*len = 0;
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
size_t nbufsiz = bufsiz + BUFSIZ;
char *nbuf = realloc(buf, nbufsiz);
if (nbuf == NULL) {
int oerrno = errno;
free(buf);
errno = oerrno;
buf = NULL;
return NULL;
} else
buf = nbuf;
*len = bufsiz;
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
return buf;
bufsiz = nbufsiz;
}
*len = (ptr - buf) + 1;
return buf;
if (!buf) {
if (!(buf = calloc(1, BUFSIZ)))
return NULL;
bufsz = BUFSIZ;
}
while ((c = getc(fp)) != EOF) {
buf[r++] = c;
if (r == bufsz) {
if (!(p = reallocarray(buf, 2, bufsz))) {
e = errno;
free(buf);
errno = e;
buf = NULL, bufsz = 0;
return NULL;
}
buf = p, bufsz = 2 * bufsz;
}
if (c == '\n')
break;
}
return (*len = r) ? buf : NULL;
}

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