80 Commits
Author SHA1 Message Date
Nicholas Marriott 418ba99078 Add to TODO. 2013-02-09 16:21:20 +00:00
Nicholas Marriott 648ce2f56a Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-02-09 14:53:51 +00:00
Nicholas Marriott 0648c58716 Add to TODO list. 2013-02-09 14:52:11 +00:00
Thomas Adam 01da28efb1 Minor update to .gitignore
Now ignores:  corefiles, stray patches and tags file.
2013-02-09 10:26:57 +00:00
Thomas Adam 6d6e1581b5 Use osdep_get_cwd() for format change 2013-02-07 13:06:31 +00:00
Thomas Adam 64da762c15 Merge branch 'obsd-master' 2013-02-07 12:08:55 +00:00
Nicholas Marriott 8903c1f167 Automatically reflow wrapped lines when a pane is resized, requested by
many over the years and finally implemented by Richard Woodbury.
2013-02-05 11:08:59 +00:00
Nicholas Marriott a5521597b0 Don't set some string formats if the string is NULL. 2013-02-05 11:01:45 +00:00
Thomas Adam fe00607816 Only set AUTO{MAKE,CONF}_VERSION on OpenBSD
OpenBSD requires the presence of AUTOMAKE_VERSION and AUTOCONF_VERSION for
bootstrapping purposes.  Setting these on any other system requires that
explicit version to be used, rather than what might already be installed.

Therefore, only do this when the platform is OpenBSD and ignore everything
else.
2013-01-31 00:14:59 +00:00
Thomas Adam 6e6d756109 Corrections to SYNCING
* Reflow some paragraphs due to repo-naming pushing the line length over 80
  chaacters.

* Correct path to git clone commands for each repo.
2013-01-30 23:28:38 +00:00
Nicholas Marriott 85531fd404 Unused variable/type nit from Thomas Adam. 2013-01-30 17:00:17 +00:00
Nicholas Marriott c4c98df4f2 Add -Wdeclaration-after-statement. 2013-01-30 16:35:00 +00:00
Thomas Adam a3f4eb7b24 Merge branch 'obsd-master'
Conflicts:
	Makefile
	grid-utf8.c
2013-01-30 15:27:19 +00:00
Nicholas Marriott fdbfc7e349 Rather than having two grids for each pane, one for ASCII and one for
UTF-8, collapse the two together. Simplifies the code at the expense of
more memory (which can probably be reduced again later).
2013-01-18 02:16:21 +00:00
Nicholas Marriott c2e2107063 Style nits - return (x) not return x. 2013-01-18 02:10:29 +00:00
Thomas Adam 2ca8b7f359 Merge branch 'obsd-master' 2013-01-17 22:14:18 +00:00
Nicholas Marriott 3a09e01a8e Do not allow cursor colours to be set beginning with ? as that will
report the colour, from Hayaki Saito.
2013-01-17 20:30:43 +00:00
Nicholas Marriott d31315884c Fix some blank line nits. 2013-01-17 03:51:21 +00:00
Nicholas Marriott 57ca428975 Merge branch 'master' of ssh://git.code.sf.net/p/tmux/tmux-code 2013-01-17 02:09:18 +00:00
Nicholas Marriott b0e2ef1a7d Update www for new SF URLs. 2013-01-17 02:08:58 +00:00
Thomas Adam b237d9dd95 Updated SYNCING 2013-01-17 02:02:04 +00:00
Thomas Adam de194016ec Merge branch 'obsd-master' 2013-01-17 01:38:21 +00:00
Nicholas Marriott e33ba57c13 Remove the layout undo/redo code which never really worked. 2013-01-17 00:11:22 +00:00
Nicholas Marriott 44f8e1caff Implement ECH (erase character, CSI X). Reported by Christian Neukirchen. 2013-01-15 23:18:55 +00:00
Nicholas Marriott bc2e4a36df If timing between keys is less than (by default) 1 millisecond, assume
the text is being pasted. assume-paste-time option changes the value (0
disables). Based on a diff from Marcin Kulik.
2013-01-15 22:55:29 +00:00
Thomas Adam 675c6b3773 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-12-31 18:50:37 +00:00
Tiago Cunha f4472c16b2 Fix keyword matching.
Per the documentation in *:syn-keyword* (in particular *E789*), the
optional characters inside the square brackets can only be used in the
end. Therefore, unfold some keywords which were being wrongly
recognised.

Noticed by Bruce Wolk.
2012-12-24 17:18:35 +00:00
Nicholas Marriott 854e8ae04d Add ^ and $ special command targets to select lowest and highest
numbered windows, from Raghavendra D Prabhu.
2012-12-24 12:38:57 +00:00
Nicholas Marriott 3e6d45acf6 Add -T option to select-window to toggle to last window if already
current, from Raghavendra D Prabhu.
2012-12-24 12:34:32 +00:00
Nicholas Marriott a2c8af97e9 Add missing function prototype. 2012-12-24 12:33:05 +00:00
Nicholas Marriott b18ff67646 Add a -u flag to choose-tree to start uncollapsed, from Raghavendra D
Prabhu.
2012-12-24 12:25:52 +00:00
millert 6a5adfc0ba We no longer use struct eproc for kinfo_proc in sysctl.h so there
is no direct need for sys/proc.h or sys/resource.h.  Some consumers
of kinfo_proc need these for the proc flags and rlimit defines like
RLIM_INF so add the appropriate includes to them.
OK deraadt@ sthen@
2012-12-18 21:28:45 +00:00
Nicholas Marriott 9714880283 Change load_cfg to fix a crash reported by jasper. 2012-12-13 15:36:16 +00:00
Nicholas Marriott 3a0016a78a Use the CMD_*_USAGE defines consistently, from Thomas Adam. 2012-12-09 23:17:35 +00:00
Thomas Adam fb83914bd7 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-12-08 20:29:37 +00:00
Thomas Adam d5de489dc4 .+ 2012-12-08 19:16:45 +00:00
Nicholas Marriott 3fa4f691e3 Handle resetting 256-colours properly when parsing #[default],
#[fg=default] and #[bg=default] styles.
2012-12-08 17:05:57 +00:00
Nicholas Marriott 8600fe054b Use strlcat not strncat in load_cfg and some other trivial tidying from
Tiago Cunha.
2012-12-06 13:06:05 +00:00
Nicholas Marriott 8378be03d1 Fix argument order in a log statement. 2012-12-06 12:49:13 +00:00
Nicholas Marriott 51a1dbfe09 Simplify command string parsing with a helper function from Tiago Cunha. 2012-12-06 12:47:48 +00:00
Nicholas Marriott 8264e92b37 Fix return value of load_cfg, from Thomas Adam. 2012-11-27 22:59:34 +00:00
Thomas Adam 739a76634c Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-27 22:24:00 +00:00
Nicholas Marriott 47c097cb51 Support middle-click paste, based on a diff from Ailin Nemui. 2012-11-27 20:22:12 +00:00
Nicholas Marriott 24d7d073ff Support the 47 and 1047 SM and RM sequences (alternate screen without
cursor), requested by I forget who ages ago.
2012-11-27 20:08:42 +00:00
Thomas Adam 39631edb98 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-27 18:12:04 +00:00
Nicholas Marriott 9b8998aeec Correctly aggregate together errors from nested config files (with
source-file). Fix by Thomas Adam, reported by Sam Livingstone-Gray
2012-11-27 16:12:29 +00:00
Nicholas Marriott 4aa4e9fb26 Allow cmd-run-shell to accept -t to specify the pane to display the
output, requested by Alexander Tsepkov.
2012-11-27 15:09:35 +00:00
Nicholas Marriott 1fcc7f50ac When scrolling in copy mode with the mouse, scroll screen rather than
moving cursor. This change from Ailin Nemui, alternative to a change
from Stephen Hicks.
2012-11-27 14:42:56 +00:00
Nicholas Marriott 6ef4f8e16c Revert last, after discussion it isn't necessary. 2012-11-27 14:26:48 +00:00
Nicholas Marriott 93224260ae Add window-status-last-* options, from Boris Faure. 2012-11-27 13:52:23 +00:00
Nicholas Marriott 991bfcf443 Fix session choice so that preferring unattached sessions actually
works, reported by Drew Frank.
2012-11-27 09:20:03 +00:00
Nicholas Marriott d762ced298 Call realpath earlier on the socket directory path rather than on the
socket file path because the latter may not exist yet and in that case
realpath is allowed to fail. From Romain Francoise.
2012-11-26 11:35:28 +00:00
Thomas Adam 1bc910a963 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-22 22:19:04 +00:00
Nicholas Marriott 63f451965c Merge branch 'master' of ssh://tmux.git.sourceforge.net/gitroot/tmux/tmux 2012-11-22 16:48:50 +00:00
Nicholas Marriott 260419f48e Put helper function back, will be needed in a bit. 2012-11-22 14:41:11 +00:00
Thomas Adam c04aa90207 Merge branch 'obsd-master'
Sync from OpenBSD.

* obsd-master:
  Add halfpage commands to mode command string table (missed by accident), from Thomas Adam.
  Clarify some points about config files, notably that they are only read at server start. From Thomas Adam.
  Use a utility function for common code to show errors in config file, from Thomas Adam.
2012-11-22 13:24:14 +00:00
Nicholas Marriott 0679eb6a6d Add halfpage commands to mode command string table (missed by accident),
from Thomas Adam.
2012-11-19 10:51:25 +00:00
Nicholas Marriott 9a7e5bd1d3 Clarify some points about config files, notably that they are only read
at server start. From Thomas Adam.
2012-11-19 10:50:24 +00:00
Nicholas Marriott 827b311c81 Use a utility function for common code to show errors in config file,
from Thomas Adam.
2012-11-19 10:38:06 +00:00
Thomas Adam e4679172e3 Sanitise additional .mailmap entries
This sanitises multiple author addresses some more, mapping them back to one
common entity.
2012-11-08 21:39:35 +00:00
Thomas Adam be10e8eee6 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-08 21:27:40 +00:00
Thomas Adam cb4553bd06 Add .mailmap for commit author translations
Because it's not possible to enumerate up-front all of the committers to
tmux coming from OpenBSD, at the time a commit is imported in to git from
the OpenBSD CVS repository, the author information is not known to Git,
necessarily.

But it's possible to alter for output the respective author after the fact,
via Git's .mailmap file.  It is this file which will therefore provide a new
mapping of OpenBSD commiter to an actual real name and real email address.
2012-11-08 21:14:32 +00:00
Nicholas Marriott c68efec6c0 Show last client activity time in default choose-client list. 2012-11-05 13:13:04 +00:00
Thomas Adam a75801320d Merge branch 'obsd-master'
Sync from OpenBSD.
2012-11-04 01:27:57 +00:00
okan 241a746f32 fix an off-by-one
ok nicm@
2012-10-31 19:11:18 +00:00
Thomas Adam 47fbf87185 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-10-26 20:28:58 +01:00
Nicholas Marriott d210d99cce Make mouse event structure clearer by defining events (up, click, drag)
and simplifying how buttons and wheels are represented, from Ailin
Nemui. Should be no functional changes.
2012-10-26 14:35:42 +00:00
Thomas Adam 31f93d8445 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-10-25 23:32:14 +01:00
Nicholas Marriott 2a609b332f Add ability to active pane in list-windows and find-window formats, from
Carl Henrik Lunde.
2012-10-25 11:26:47 +00:00
Nicholas Marriott 18236c1c1b Fix BELL_NONE which had been broken in some code reorganisation or other
also don't redraw unnecessarily. From Seiji Ohashi.
2012-10-25 11:16:53 +00:00
Nicholas Marriott 596e9d8068 Fix bad size in memcpy from Romain Francoise. 2012-10-25 11:14:46 +00:00
Nicholas Marriott 589b4b8c6a Fix typo bell->bells from Thomas Adam. 2012-10-25 11:11:58 +00:00
Nicholas Marriott 60808bbded +. 2012-10-23 18:47:52 +01:00
Thomas Adam d4dc52ec84 Merge branch 'obsd-master'
Sync from OpenBSD.
2012-10-16 18:30:36 +01:00
Nicholas Marriott c695c0c085 Fix some function prototypes from Helmut Tessarek. 2012-10-15 21:53:30 +00:00
Nicholas Marriott a91c598971 Link to git instructions from index.html. 2012-10-15 18:25:44 +01:00
Thomas Adam bf45619441 Don't push all tags when releasing tmux
Pushing all tags with "git push --tags" will also transfer tags from the
tmux-openbsd repository which isn't what we want to do!

Therefore, just specify the newly created tag to push instead for the next
release.
2012-10-13 13:35:35 +01:00
Thomas Adam 9b2aabb752 Merge branch 'master' of ssh://tmux.git.sourceforge.net/gitroot/tmux/tmux 2012-10-13 12:25:08 +01:00
Thomas Adam c0fb5edff9 Update website. 2012-10-13 12:22:11 +01:00
Thomas Adam 5cdc9591d3 Working on 1.8 2012-10-13 12:12:43 +01:00
64 changed files with 1051 additions and 1016 deletions
+5
View File
@@ -1,5 +1,10 @@
*.o
*~
*.diff
*.patch
*.core
core
tags
.deps/
aclocal.m4
autom4te.cache/
+24
View File
@@ -0,0 +1,24 @@
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>
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>
Philip Guenther <guenther@openbsd.org> guenther <guenther>
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>
Thomas Adam <thomas@xteddy.org> Thomas <thomas@xteddy.org>
William Yodlowsky <william@openbsd.org> william <william>
+2 -1
View File
@@ -31,6 +31,7 @@ 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
CPPFLAGS += -DDEBUG
endif
if IS_GCC4
@@ -139,7 +140,7 @@ dist_tmux_SOURCES = \
control-notify.c \
environ.c \
format.c \
grid-utf8.c \
grid-cell.c \
grid-view.c \
grid.c \
input-keys.c \
+35 -34
View File
@@ -1,10 +1,10 @@
Preamble
========
Tmux on SourceForge has two git repositories [1] "tmux" and "tmux-openbsd".
Tmux on SourceForge has two git repositories [1] "tmux-code" and "tmux-openbsd".
Here's a description of them:
* "tmux" is the portable version, the one which contains code for other
* "tmux-code" 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.
@@ -13,10 +13,12 @@ Here's a description of them:
Note: The "tmux-openbsd" repository is actually handled by "git cvsimport"
running at 15 minute intervals, so a commit made to OpenBSD's tmux CVS
repository will take that long to appear in this git repository.
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 repository on SourceForge already.
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:
@@ -35,69 +37,69 @@ this information has ever been set before.
Cloning repositories
====================
This involves having both tmux and tmux-openbsd cloned, as in:
This involves having both tmux-code and tmux-openbsd cloned, as in:
% cd /some/where/useful
% git clone ssh://${USER}@tmux.git.sf.net/gitroot/tmux/tmux
% git clone ssh://${USER}@tmux.git.sf.net/gitroot/tmux/tmux-openbsd
% git clone ssh://${USER}@git.code.sf.net/p/tmux/tmux
% git clone ssh://${USER}@git.code.sf.net/p/tmux/tmux-openbsd
Note that you do not need additoinal checkouts to manage the sync -- an
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
these checkouts existing, skip that.
Adding in git-remotes
=====================
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" repository, as shown by the
following command:
Because the portable "tmux-code" 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
shown by the following command:
% cd /path/to/tmux
% cd /path/to/tmux-code
% 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" repository, which makes sense because it's the "tmux"
portable "tmux-code" 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", we have to ensure the "master" branch from "tmux-openbsd" is
up-to-date first, and then reference that update in "tmux", as in:
"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:
% cd /path/to/tmux-openbsd
% git checkout master
% git pull
Then back in "tmux":
Then back in "tmux-code":
% cd /path/to/tmux
% git fetch obsd-tmux
% cd /path/to/tmux-code
% git fetch obsd-tmux-code
Creating the necessary branches
===============================
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" repository:
Now that "tmux-code" 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:
% git checkout -b obsd-master obsd-tmux/master
Adding in the fake history points
=================================
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"
repository need to be added. To do this, we must add an additional refspec
line, as in:
To tie both the "master" branch from "tmux-code" 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
additional refspec line, as in:
% cd /path/to/tmux
% cd /path/to/tmux-code
% git config --add remote.origin.fetch '+refs/replace/*:refs/replace/*'
% git fetch origin
@@ -108,8 +110,7 @@ Make sure the "master" branch is checked out:
% git checkout master
The following will show commits on OpenBSD not yet synched with tmux
portable:
The following will show commits on OpenBSD not yet synched with "tmux-code":
% git log master..obsd-master
@@ -150,7 +151,7 @@ Release tmux for next version
Push the tag out with:
% git push --tags
% git push 1.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
@@ -170,4 +171,4 @@ Release tmux for next version
9. Update freshmeat.
[1] http://tmux.git.sourceforge.net/git/gitweb-index.cgi
[1] https://sourceforge.net/p/tmux/_list/git
+8
View File
@@ -105,6 +105,7 @@ TMUX UI ISSUES
and a buffer) info() when changing to same window
- way to add dest for break-pane; maybe some easier way to unbreak-pane
- case insensitive searching
- incremental searching in copy mode.
- configurable borders and empty space filler for when panes < window?
- mouse-select-pane will screw up with !MODE_MOUSE_STANDARD (it sets the
flag on w/o checking the others before calling tty_update_mode)
@@ -153,6 +154,13 @@ TMUX UI ISSUES
- choose-mode and copy-mode are very similar. Perhaps make choose-mode a
subset of copy-mode in that it inherits key-bindings and other traits but
not all.
- add -c for new-session like new-window
- flag to choose-* for sort order (eg sort windows/sessions/clients by last
used time) - perhaps using formats (but what about numeric sort)?
- instead of separate window and session options, just one master options list
with each option having a type (window or session), then options on window,
on session, and global. for window options we look window->session->global,
and for session we look session->global
TERMINAL ISSUES
================
+4 -2
View File
@@ -1,8 +1,10 @@
#!/bin/sh
# $Id$
[ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.10
[ -z "$AUTOCONF_VERSION" ] && export AUTOCONF_VERSION=2.65
if [ "x$(uname)" = "xOpenBSD" ]; then
[ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.10
[ -z "$AUTOCONF_VERSION" ] && export AUTOCONF_VERSION=2.65
fi
die()
{
+60 -21
View File
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -34,9 +35,10 @@
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause;
int cfg_finished;
struct causelist cfg_causes = ARRAY_INITIALIZER;
char *cfg_cause;
int cfg_finished;
int cfg_references;
struct causelist cfg_causes;
/* ARGSUSED */
void printflike2
@@ -72,63 +74,77 @@ cfg_add_cause(struct causelist *causes, const char *fmt, ...)
* Load configuration file. Returns -1 for an error with a list of messages in
* causes. Note that causes must be initialised by the caller!
*/
int
enum cmd_retval
load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
{
FILE *f;
u_int n;
char *buf, *line, *cause;
size_t len;
char *buf, *copy, *line, *cause;
size_t len, oldlen;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
enum cmd_retval retval;
if ((f = fopen(path, "rb")) == NULL) {
cfg_add_cause(causes, "%s: %s", path, strerror(errno));
return (-1);
return (CMD_RETURN_ERROR);
}
n = 0;
cfg_references++;
n = 0;
line = NULL;
retval = CMD_RETURN_NORMAL;
while ((buf = fgetln(f, &len))) {
/* Trim \n. */
if (buf[len - 1] == '\n')
len--;
log_debug ("%s: %s", path, buf);
if (line != NULL)
line = xrealloc(line, 1, strlen(line) + len + 1);
else {
/* Current line is the continuation of the previous one. */
if (line != NULL) {
oldlen = strlen(line);
line = xrealloc(line, 1, oldlen + len + 1);
} else {
oldlen = 0;
line = xmalloc(len + 1);
*line = '\0';
}
/* Append buffer to line. strncat will terminate. */
strncat(line, buf, len);
/* Append current line to the previous. */
memcpy(line + oldlen, buf, len);
line[oldlen + len] = '\0';
n++;
/* Continuation: get next line? */
len = strlen(line);
if (len > 0 && line[len - 1] == '\\') {
line[len - 1] = '\0';
/* Ignore escaped backslash at EOL. */
if (len > 1 && line[len - 2] != '\\')
continue;
}
buf = line;
copy = line;
line = NULL;
/* Skip empty lines. */
buf = copy;
while (isspace((u_char)*buf))
buf++;
if (*buf == '\0')
continue;
if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
free(buf);
free(copy);
if (cause == NULL)
continue;
cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
free(cause);
continue;
} else
free(buf);
}
free(copy);
if (cmdlist == NULL)
continue;
cfg_cause = NULL;
if (ctxin == NULL) {
ctx.msgdata = NULL;
@@ -159,8 +175,7 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
}
cmd_list_free(cmdlist);
if (cfg_cause != NULL) {
cfg_add_cause(
causes, "%s: %d: %s", path, n, cfg_cause);
cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause);
free(cfg_cause);
}
}
@@ -171,5 +186,29 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
}
fclose(f);
cfg_references--;
return (retval);
}
void
show_cfg_causes(struct session *s)
{
struct window_pane *wp;
char *cause;
u_int i;
if (s == NULL || ARRAY_EMPTY(&cfg_causes))
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);
}
ARRAY_FREE(&cfg_causes);
}
+2 -1
View File
@@ -32,7 +32,8 @@ enum cmd_retval cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_capture_pane_entry = {
"capture-pane", "capturep",
"b:E:S:t:", 0, 0,
"[-b buffer-index] [-E end-line] [-S start-line] [-t target-pane]",
"[-b buffer-index] [-E end-line] [-S start-line] "
CMD_TARGET_PANE_USAGE,
0,
NULL,
NULL,
-1
View File
@@ -44,7 +44,6 @@ const struct cmd_entry cmd_choose_client_entry = {
struct cmd_choose_client_data {
struct client *client;
char *template;
};
enum cmd_retval
+6 -3
View File
@@ -39,8 +39,8 @@ void cmd_choose_tree_free(struct window_choose_data *);
const struct cmd_entry cmd_choose_tree_entry = {
"choose-tree", NULL,
"S:W:swb:c:t:", 0, 1,
"[-sw] [-b session-template] [-c window template] [-S format] " \
"S:W:swub:c:t:", 0, 1,
"[-swu] [-b session-template] [-c window template] [-S format] " \
"[-W format] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
@@ -219,6 +219,7 @@ windows_only:
free(final_win_action);
}
/*
* If we're just drawing windows, don't consider moving on to
* other sessions as we only list windows in this session.
@@ -232,6 +233,9 @@ windows_only:
window_choose_ready(wl->window->active, cur_win,
cmd_choose_tree_callback, cmd_choose_tree_free);
if (args_has(args, 'u'))
window_choose_expand_all(wl->window->active);
return (CMD_RETURN_NORMAL);
}
@@ -257,5 +261,4 @@ cmd_choose_tree_free(struct window_choose_data *cdata)
free(cdata->command);
format_free(cdata->ft);
free(cdata);
}
+2 -1
View File
@@ -32,7 +32,8 @@ enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_message_entry = {
"display-message", "display",
"c:pt:F:", 0, 1,
"[-p] [-c target-client] [-t target-pane] [-F format] [message]",
"[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE
" [message]",
0,
NULL,
NULL,
+1
View File
@@ -193,6 +193,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
ARRAY_ITEM(&find_list, i).list_ctx);
format_session(cdata->ft, s);
format_winlink(cdata->ft, s, wm);
format_window_pane(cdata->ft, wm->window->active);
window_choose_add(wl->window->active, cdata);
}
+1 -1
View File
@@ -28,7 +28,7 @@
* List all clients.
*/
int cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc",
+1 -1
View File
@@ -97,7 +97,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
return (CMD_RETURN_NORMAL);
}
int
enum cmd_retval
cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
+1 -1
View File
@@ -38,7 +38,7 @@ void cmd_list_panes_window(struct cmd *,
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
"asF:t:", 0, 0,
"[-as] [-F format] [-t target]",
"[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
0,
NULL,
NULL,
+1
View File
@@ -99,6 +99,7 @@ cmd_list_windows_session(
format_add(ft, "line", "%u", n);
format_session(ft, s);
format_winlink(ft, s, wl);
format_window_pane(ft, wl->window->active);
line = format_expand(ft, template);
ctx->print(ctx, "%s", line);
+5 -15
View File
@@ -36,8 +36,8 @@ enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"dn:s:t:x:y:", 0, 1,
"[-d] [-n window-name] [-s session-name] [-t target-session] "
"[-x width] [-y height] [command]",
"[-d] [-n window-name] [-s session-name] " CMD_TARGET_SESSION_USAGE
" [-x width] [-y height] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON,
NULL,
cmd_new_session_check,
@@ -58,14 +58,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct args *args = self->args;
struct session *s, *old_s, *groupwith;
struct window *w;
struct window_pane *wp;
struct environ env;
struct termios tio, *tiop;
struct passwd *pw;
const char *newname, *target, *update, *cwd, *errstr;
char *cmd, *cause;
int detached, idx;
u_int sx, sy, i;
u_int sx, sy;
newname = args_get(args, 's');
if (newname != NULL) {
@@ -257,17 +256,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
* If there are still configuration file errors to display, put the new
* session's current window into more mode and display them now.
*/
if (cfg_finished && !ARRAY_EMPTY(&cfg_causes)) {
wp = s->curw->window->active;
window_pane_set_mode(wp, &window_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);
}
ARRAY_FREE(&cfg_causes);
}
if (cfg_finished)
show_cfg_causes(s);
return (detached ? CMD_RETURN_NORMAL : CMD_RETURN_ATTACH);
}
+2 -2
View File
@@ -26,13 +26,13 @@
* Create a new window.
*/
int cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
enum cmd_retval cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
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] "
"[-t target-window] [command]",
CMD_TARGET_WINDOW_USAGE " [command]",
0,
NULL,
NULL,
+4 -32
View File
@@ -30,12 +30,12 @@
enum cmd_retval cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_paste_buffer_filter(struct window_pane *,
const char *, size_t, const char *, int bracket);
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] [-b buffer-index] [-t target-pane]",
"[-dpr] [-s separator] [-b buffer-index] " CMD_TARGET_PANE_USAGE,
0,
NULL,
NULL,
@@ -86,9 +86,8 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
else
sepstr = "\r";
}
pflag = args_has(args, 'p') &&
(wp->screen->mode & MODE_BRACKETPASTE);
cmd_paste_buffer_filter(wp, pb->data, pb->size, sepstr, pflag);
pflag = (wp->screen->mode & MODE_BRACKETPASTE);
paste_send_pane(pb, wp, sepstr, args_has(args, 'p') && pflag);
}
/* Delete the buffer if -d. */
@@ -101,30 +100,3 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
return (CMD_RETURN_NORMAL);
}
/* Add bytes to a buffer and filter '\n' according to separator. */
void
cmd_paste_buffer_filter(struct window_pane *wp,
const char *data, size_t size, const char *sep, int bracket)
{
const char *end = data + size;
const char *lf;
size_t seplen;
if (bracket)
bufferevent_write(wp->event, "\033[200~", 6);
seplen = strlen(sep);
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
bufferevent_write(wp->event, data, lf - data);
bufferevent_write(wp->event, sep, seplen);
data = lf + 1;
}
if (end != data)
bufferevent_write(wp->event, data, end - data);
if (bracket)
bufferevent_write(wp->event, "\033[201~", 6);
}
-1
View File
@@ -103,7 +103,6 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
layout_list_add(wp->window);
if (args_has(self->args, 'L'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
else if (args_has(self->args, 'R'))
+36 -9
View File
@@ -30,13 +30,15 @@
*/
enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *);
void cmd_run_shell_callback(struct job *);
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",
"", 1, 1,
"command",
"t:", 1, 1,
CMD_TARGET_PANE_USAGE " command",
0,
NULL,
NULL,
@@ -46,17 +48,42 @@ const struct cmd_entry cmd_run_shell_entry = {
struct cmd_run_shell_data {
char *cmd;
struct cmd_ctx ctx;
u_int wp_id;
};
void
cmd_run_shell_print(struct job *job, const char *msg)
{
struct cmd_run_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
struct window_pane *wp;
wp = window_pane_find_by_id(cdata->wp_id);
if (wp == NULL) {
ctx->print(ctx, "%s", msg);
return;
}
if (window_pane_set_mode(wp, &window_copy_mode) == 0)
window_copy_init_for_output(wp);
if (wp->mode == &window_copy_mode)
window_copy_add(wp, "%s", msg);
}
enum cmd_retval
cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct cmd_run_shell_data *cdata;
const char *shellcmd = args->argv[0];
struct window_pane *wp;
if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
return (CMD_RETURN_ERROR);
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(args->argv[0]);
cdata->wp_id = wp->id;
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
@@ -87,7 +114,7 @@ cmd_run_shell_callback(struct job *job)
lines = 0;
do {
if ((line = evbuffer_readline(job->event->input)) != NULL) {
ctx->print(ctx, "%s", line);
cmd_run_shell_print (job, line);
lines++;
}
} while (line != NULL);
@@ -98,7 +125,7 @@ cmd_run_shell_callback(struct job *job)
memcpy(line, EVBUFFER_DATA(job->event->input), size);
line[size] = '\0';
ctx->print(ctx, "%s", line);
cmd_run_shell_print(job, line);
lines++;
free(line);
@@ -115,10 +142,10 @@ cmd_run_shell_callback(struct job *job)
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL) {
if (lines != 0)
ctx->print(ctx, "%s", msg);
else
if (lines == 0)
ctx->info(ctx, "%s", msg);
else
cmd_run_shell_print(job, msg);
free(msg);
}
}
+10 -37
View File
@@ -29,8 +29,8 @@ enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
"nprut:", 0, 1,
"[-npUu] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
"npt:", 0, 1,
"[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
0,
cmd_select_layout_key_binding,
NULL,
@@ -76,14 +76,6 @@ cmd_select_layout_key_binding(struct cmd *self, int key)
case '5' | KEYC_ESCAPE:
self->args = args_create(1, "tiled");
break;
case 'u':
self->args = args_create(0);
args_set(self->args, 'u', NULL);
break;
case 'U':
self->args = args_create(0);
args_set(self->args, 'U', NULL);
break;
default:
self->args = args_create(0);
break;
@@ -95,13 +87,11 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct winlink *wl;
struct window *w;
const char *layoutname;
int next, previous, layout;
if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
w = wl->window;
next = self->entry == &cmd_next_layout_entry;
if (args_has(self->args, 'n'))
@@ -110,21 +100,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
if (args_has(self->args, 'p'))
previous = 1;
layout_list_add(w);
if (args_has(self->args, 'U')) {
if ((layoutname = layout_list_redo(w)) == NULL) {
ctx->info(ctx, "no more layout history");
return (CMD_RETURN_ERROR);
}
goto set_layout;
} else if (args_has(self->args, 'u')) {
if ((layoutname = layout_list_undo(w)) == NULL) {
ctx->info(ctx, "no more layout history");
return (CMD_RETURN_ERROR);
}
goto set_layout;
}
if (next || previous) {
if (next)
layout = layout_set_next(wl->window);
@@ -146,16 +121,14 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
return (CMD_RETURN_NORMAL);
}
if (args->argc == 0)
return (CMD_RETURN_NORMAL);
layoutname = args->argv[0];
set_layout:
if (layout_parse(wl->window, layoutname) == -1) {
ctx->error(ctx, "can't set layout: %s", layoutname);
return (CMD_RETURN_ERROR);
if (args->argc != 0) {
layoutname = args->argv[0];
if (layout_parse(wl->window, layoutname) == -1) {
ctx->error(ctx, "can't set layout: %s", layoutname);
return (CMD_RETURN_ERROR);
}
server_redraw_window(wl->window);
ctx->info(ctx, "arranging in: %s", layoutname);
}
server_redraw_window(wl->window);
ctx->info(ctx, "arranging in: %s", layoutname);
return (CMD_RETURN_NORMAL);
}
+13 -3
View File
@@ -31,8 +31,8 @@ enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw",
"lnpt:", 0, 0,
"[-lnp] " CMD_TARGET_WINDOW_USAGE,
"lnpTt:", 0, 0,
"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
0,
cmd_select_window_key_binding,
NULL,
@@ -130,7 +130,17 @@ cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl == NULL)
return (CMD_RETURN_ERROR);
if (session_select(s, wl->idx) == 0)
/*
* If -T and select-window is invoked on same window as
* current, switch to previous window.
*/
if (args_has(self->args, 'T') && wl == s->curw) {
if (session_last(s) != 0) {
ctx->error(ctx, "no last window");
return (-1);
}
server_redraw_session(s);
} else if (session_select(s, wl->idx) == 0)
server_redraw_session(s);
}
recalculate_sizes();
+1 -1
View File
@@ -32,7 +32,7 @@ enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"lRt:", 0, -1,
"[-lR] [-t target-pane] key ...",
"[-lR] " CMD_TARGET_PANE_USAGE " key ...",
0,
NULL,
NULL,
+14 -22
View File
@@ -58,12 +58,11 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct job *job;
struct grid *gd;
struct grid_line *gl;
u_int i, j, k;
u_int i, j, k, lines;
size_t size;
char out[80];
char *tim;
time_t t;
u_int lines, ulines;
size_t size, usize;
tim = ctime(&start_time);
*strchr(tim, '\n') = '\0';
@@ -89,16 +88,15 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
continue;
ctx->print(ctx,"%2d: %s (%d, %d): %s [%ux%u %s bs=%hho "
"xterm=%u] [flags=0x%x/0x%x, references=%u]", i,
"class=%u] [flags=0x%x/0x%x, references=%u]", i,
c->tty.path, c->ibuf.fd, c->tty.fd, c->session->name,
c->tty.sx, c->tty.sy, c->tty.termname,
c->tty.tio.c_cc[VERASE], c->tty.xterm_version,
c->tty.tio.c_cc[VERASE], c->tty.class,
c->flags, c->tty.flags, c->references);
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8));
ctx->print(ctx, "Sessions: [%zu]", sizeof (struct grid_cell));
RB_FOREACH(s, sessions, &sessions) {
t = s->creation_time.tv_sec;
tim = ctime(&t);
@@ -115,26 +113,20 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
w->lastlayout);
j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0;
lines = size = 0;
gd = wp->base.grid;
for (k = 0; k < gd->hsize + gd->sy; k++) {
gl = &gd->linedata[k];
if (gl->celldata != NULL) {
lines++;
size += gl->cellsize *
sizeof *gl->celldata;
}
if (gl->utf8data != NULL) {
ulines++;
usize += gl->utf8size *
sizeof *gl->utf8data;
}
if (gl->celldata == NULL)
continue;
lines++;
size += gl->cellsize *
sizeof *gl->celldata;
}
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
"bytes; UTF-8 %u/%u, %zu bytes", j,
ctx->print(ctx,
"%6u: %s %lu %d %u/%u, %zu bytes", j,
wp->tty, (u_long) wp->pid, wp->fd, lines,
gd->hsize + gd->sy, size, ulines,
gd->hsize + gd->sy, usize);
gd->hsize + gd->sy, size);
j++;
}
}
+1 -1
View File
@@ -57,7 +57,7 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
return (CMD_RETURN_ERROR);
}
if (args->argc < 1)
if (args->argc < 2)
value = NULL;
else
value = args->argv[1];
+19 -22
View File
@@ -42,35 +42,32 @@ enum cmd_retval
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct args *args = self->args;
struct causelist causes;
char *cause;
struct window_pane *wp;
int retval;
u_int i;
char *cause;
ARRAY_INIT(&causes);
retval = load_cfg(args->argv[0], ctx, &cfg_causes);
retval = load_cfg(args->argv[0], ctx, &causes);
if (ARRAY_EMPTY(&causes))
/*
* If the context for the cmdclient came from tmux's configuration
* file, then return the status of this command now, regardless of the
* error condition. Any errors from parsing a configuration file at
* startup will be handled for us by the server.
*/
if (cfg_references > 0 ||
(ctx->curclient == NULL && ctx->cmdclient == NULL))
return (retval);
if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) {
wp = RB_MIN(sessions, &sessions)->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
window_copy_add(wp, "%s", cause);
free(cause);
}
} else {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
free(cause);
}
/*
* We were called from the command-line in which case print the errors
* gathered here directly.
*/
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
ctx->print(ctx, "%s", cause);
free(cause);
}
ARRAY_FREE(&causes);
ARRAY_FREE(&cfg_causes);
return (retval);
}
+1 -1
View File
@@ -34,7 +34,7 @@ const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"c:dF:l:hp:Pt:v", 0, 1,
"[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
"[-t target-pane] [command]",
CMD_TARGET_PANE_USAGE " [command]",
0,
cmd_split_window_key_binding,
NULL,
+27 -26
View File
@@ -31,11 +31,12 @@
* Parse a command from a string.
*/
int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(size_t *);
char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *);
char *cmd_string_expand_tilde(const char *, size_t *);
int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(size_t *);
void cmd_string_copy(char **, char *, size_t *);
char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *);
char *cmd_string_expand_tilde(const char *, size_t *);
int
cmd_string_getc(const char *s, size_t *p)
@@ -84,26 +85,17 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
case '\'':
if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
cmd_string_copy(&buf, t, &len);
break;
case '"':
if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
cmd_string_copy(&buf, t, &len);
break;
case '$':
if ((t = cmd_string_variable(s, &p)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
cmd_string_copy(&buf, t, &len);
break;
case '#':
/* Comment: discard rest of line. */
@@ -147,12 +139,10 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
goto out;
case '~':
if (buf == NULL) {
if ((t = cmd_string_expand_tilde(s, &p)) == NULL)
t = cmd_string_expand_tilde(s, &p);
if (t == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
cmd_string_copy(&buf, t, &len);
break;
}
/* FALLTHROUGH */
@@ -181,6 +171,20 @@ out:
return (rval);
}
void
cmd_string_copy(char **dst, char *src, size_t *len)
{
size_t srclen;
srclen = strlen(src);
*dst = xrealloc(*dst, 1, *len + srclen + 1);
strlcpy(*dst + *len, src, srclen + 1);
*len += srclen;
free(src);
}
char *
cmd_string_string(const char *s, size_t *p, char endch, int esc)
{
@@ -220,10 +224,7 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
break;
if ((t = cmd_string_variable(s, p)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
free(t);
cmd_string_copy(&buf, t, &len);
continue;
}
+1 -1
View File
@@ -26,7 +26,7 @@
* Swap one window with another.
*/
int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
enum cmd_retval cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw",
+28 -12
View File
@@ -115,6 +115,7 @@ const struct cmd_entry *cmd_table[] = {
NULL
};
int cmd_session_better(struct session *, struct session *, int);
struct session *cmd_choose_session_list(struct sessionslist *);
struct session *cmd_choose_session(int);
struct client *cmd_choose_client(struct clients *);
@@ -370,6 +371,24 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
return (cmd_choose_session(prefer_unattached));
}
/* Is this session better? */
int
cmd_session_better(struct session *s, struct session *best,
int prefer_unattached)
{
if (best == NULL)
return (1);
if (prefer_unattached) {
if (!(best->flags & SESSION_UNATTACHED) &&
(s->flags & SESSION_UNATTACHED))
return (1);
else if ((best->flags & SESSION_UNATTACHED) &&
!(s->flags & SESSION_UNATTACHED))
return (0);
}
return (timercmp(&s->activity_time, &best->activity_time, >));
}
/*
* Find the most recently used session, preferring unattached if the flag is
* set.
@@ -377,21 +396,14 @@ cmd_current_session(struct cmd_ctx *ctx, int prefer_unattached)
struct session *
cmd_choose_session(int prefer_unattached)
{
struct session *s, *sbest;
struct timeval *tv = NULL;
struct session *s, *best;
sbest = NULL;
best = NULL;
RB_FOREACH(s, sessions, &sessions) {
if (tv == NULL || timercmp(&s->activity_time, tv, >) ||
(prefer_unattached &&
!(sbest->flags & SESSION_UNATTACHED) &&
(s->flags & SESSION_UNATTACHED))) {
sbest = s;
tv = &s->activity_time;
}
if (cmd_session_better(s, best, prefer_unattached))
best = s;
}
return (sbest);
return (best);
}
/* Find the most recently used session from a list. */
@@ -850,6 +862,10 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
wl = s->curw;
else if (winptr[0] == '!' && winptr[1] == '\0')
wl = TAILQ_FIRST(&s->lastw);
else if (winptr[0] == '^' && winptr[1] == '\0')
wl = RB_MIN(winlinks, &s->windows);
else if (winptr[0] == '$' && winptr[1] == '\0')
wl = RB_MAX(winlinks, &s->windows);
else if (winptr[0] == '+' || winptr[0] == '-')
wl = cmd_find_window_offset(winptr, s, &ambiguous);
else
+2 -2
View File
@@ -1,7 +1,7 @@
# $Id$
# Miscellaneous autofoo bullshit.
AC_INIT(tmux, 1.7)
AC_INIT(tmux, 1.8)
AC_CONFIG_AUX_DIR(etc)
AM_INIT_AUTOMAKE([foreign])
@@ -41,7 +41,7 @@ AC_CHECK_HEADERS(
)
# Is this a debug build?
#found_debug=yes
found_debug=yes
AC_ARG_ENABLE(
debug,
AC_HELP_STRING(--enable-debug, create a debug build),
+11 -7
View File
@@ -41,7 +41,7 @@ syn keyword tmuxCmds
\ choose-buffer clearhist clear-history deleteb delete-buffer lsb
\ list-buffers loadb load-buffer pasteb paste-buffer saveb save-buffer
\ setb set-buffer showb show-buffer
\ clock-mode if[-shell] lock[-server] run[-shell] [server-]info
\ clock-mode if[-shell] lock[-server] run[-shell] server-info info
\ choose-list
syn keyword tmuxOptsSet
@@ -49,11 +49,14 @@ syn keyword tmuxOptsSet
\ set-clipboard
\ base-index bell-action bell-on-alert default-command default-path
\ default-shell default-terminal destroy-unattached detach-on-destroy
\ display-panes-[active-]colour display-[panes-]time history-limit
\ lock-after-time lock-command lock-server message-[command-]attr
\ message-[command-]bg message-[command-]fg message-limit
\ display-panes-active-colour display-panes-colour display-panes-time
\ display-time history-limit
\ lock-after-time lock-command lock-server
\ message-command-attr message-attr message-command-bg message-bg
\ message-command-fg message-fg message-limit
\ mouse-resize-pane mouse-select-pane mouse-select-window mouse-utf8
\ pane-[active-]border-bg pane-[active-]border-fg prefix prefix2
\ pane-active-border-bg pane-border-bg pane-active-border-fg
\ pane-border-fg prefix prefix2
\ renumber-windows repeat-time set-remain-on-exit set-titles
\ set-titles-string status status-attr status-bg status-fg
\ status-interval status-justify status-keys status-left
@@ -75,8 +78,9 @@ syn keyword tmuxOptsSetw
\ window-status-content-bg window-status-content-fg
\ window-status-activity-attr window-status-activity-bg
\ window-status-activity-fg window-status-attr
\ window-status-[current-]attr window-status-[current-]bg
\ window-status-[current-]fg window-status-[current-]format
\ window-status-current-attr window-status-attr window-status-current-bg
\ window-status-bg window-status-current-fg window-status-fg
\ window-status-current-format window-status-format
\ window-status-separator xterm-keys wrap-search
syn keyword tmuxTodo FIXME NOTE TODO XXX contained
+5 -3
View File
@@ -365,12 +365,12 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp)
unsigned long long size;
u_int i;
u_int idx;
const char *cwd;
size = 0;
for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i];
size += gl->cellsize * sizeof *gl->celldata;
size += gl->utf8size * sizeof *gl->utf8data;
}
size += gd->hsize * sizeof *gd->linedata;
@@ -391,9 +391,11 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp)
format_add(ft, "pane_start_command", "%s", wp->cmd);
if (wp->cwd != NULL)
format_add(ft, "pane_start_path", "%s", wp->cwd);
format_add(ft, "pane_current_path", "%s", osdep_get_cwd(wp->fd));
if ((cwd = osdep_get_cwd(wp->fd)) != NULL)
format_add(ft, "pane_current_path", "%s", cwd);
format_add(ft, "pane_pid", "%ld", (long) wp->pid);
format_add(ft, "pane_tty", "%s", wp->tty);
if (wp->tty != NULL)
format_add(ft, "pane_tty", "%s", wp->tty);
}
void
+55
View File
@@ -0,0 +1,55 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/* Get cell width. */
u_int
grid_cell_width(const struct grid_cell *gc)
{
return (gc->xstate >> 4);
}
/* Get cell data. */
void
grid_cell_get(const struct grid_cell *gc, struct utf8_data *ud)
{
ud->size = gc->xstate & 0xf;
ud->width = gc->xstate >> 4;
memcpy(ud->data, gc->xdata, ud->size);
}
/* Set cell data. */
void
grid_cell_set(struct grid_cell *gc, const struct utf8_data *ud)
{
memcpy(gc->xdata, ud->data, ud->size);
gc->xstate = (ud->width << 4) | ud->size;
}
/* Set a single character as cell data. */
void
grid_cell_one(struct grid_cell *gc, u_char ch)
{
*gc->xdata = ch;
gc->xstate = (1 << 4) | 1;
}
-96
View File
@@ -1,96 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/*
* Grid UTF-8 utility functions.
*/
/* Calculate UTF-8 grid cell size. Data is terminated by 0xff. */
size_t
grid_utf8_size(const struct grid_utf8 *gu)
{
size_t size;
for (size = 0; size < sizeof gu->data; size++) {
if (gu->data[size] == 0xff)
break;
}
return (size);
}
/* Copy UTF-8 out into a buffer. */
size_t
grid_utf8_copy(const struct grid_utf8 *gu, char *buf, size_t len)
{
size_t size;
size = grid_utf8_size(gu);
if (size > len)
fatalx("UTF-8 copy overflow");
memcpy(buf, gu->data, size);
return (size);
}
/* Set UTF-8 grid data from input UTF-8. */
void
grid_utf8_set(struct grid_utf8 *gu, const struct utf8_data *utf8data)
{
if (utf8data->size == 0)
fatalx("UTF-8 data empty");
if (utf8data->size > sizeof gu->data)
fatalx("UTF-8 data too long");
memcpy(gu->data, utf8data->data, utf8data->size);
if (utf8data->size != sizeof gu->data)
gu->data[utf8data->size] = 0xff;
gu->width = utf8data->width;
}
/* Append UTF-8 character onto the cell data (for combined characters). */
int
grid_utf8_append(struct grid_utf8 *gu, const struct utf8_data *utf8data)
{
size_t old_size;
old_size = grid_utf8_size(gu);
if (old_size + utf8data->size > sizeof gu->data)
return (-1);
memcpy(gu->data + old_size, utf8data->data, utf8data->size);
if (old_size + utf8data->size != sizeof gu->data)
gu->data[old_size + utf8data->size] = 0xff;
return (0);
}
/* Compare two UTF-8 cells. */
int
grid_utf8_compare(const struct grid_utf8 *gu1, const struct grid_utf8 *gu2)
{
size_t size;
size = grid_utf8_size(gu1);
if (size != grid_utf8_size(gu2))
return (0);
if (memcmp(gu1->data, gu2->data, size) != 0)
return (0);
return (1);
}
+1 -23
View File
@@ -52,28 +52,6 @@ grid_view_set_cell(
grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
}
/* Get UTF-8 for reading. */
const struct grid_utf8 *
grid_view_peek_utf8(struct grid *gd, u_int px, u_int py)
{
return (grid_peek_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
}
/* Get UTF-8 for writing. */
struct grid_utf8 *
grid_view_get_utf8(struct grid *gd, u_int px, u_int py)
{
return (grid_get_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
}
/* Set UTF-8. */
void
grid_view_set_utf8(
struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gu)
{
grid_set_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py), gu);
}
/* Clear into history. */
void
grid_view_clear_history(struct grid *gd)
@@ -87,7 +65,7 @@ grid_view_clear_history(struct grid *gd)
last = 0;
for (yy = 0; yy < gd->sy; yy++) {
gl = &gd->linedata[grid_view_y(gd, yy)];
if (gl->cellsize != 0 || gl->utf8size != 0)
if (gl->cellsize != 0)
last = yy + 1;
}
if (last == 0)
+52 -92
View File
@@ -36,8 +36,8 @@
*/
/* Default grid cell data. */
const struct grid_cell grid_default_cell = { 0, 0, 8, 8, ' ' };
const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, '_' };
const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " };
const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, (1 << 4) | 1, "_" };
#define grid_put_cell(gd, px, py, gc) do { \
memcpy(&gd->linedata[py].celldata[px], \
@@ -100,7 +100,6 @@ grid_destroy(struct grid *gd)
for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
gl = &gd->linedata[yy];
free(gl->celldata);
free(gl->utf8data);
}
free(gd->linedata);
@@ -114,7 +113,6 @@ grid_compare(struct grid *ga, struct grid *gb)
{
struct grid_line *gla, *glb;
struct grid_cell *gca, *gcb;
struct grid_utf8 *gua, *gub;
u_int xx, yy;
if (ga->sx != gb->sx || ga->sy != ga->sy)
@@ -130,12 +128,6 @@ grid_compare(struct grid *ga, struct grid *gb)
gcb = &glb->celldata[xx];
if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0)
return (1);
if (!(gca->flags & GRID_FLAG_UTF8))
continue;
gua = &gla->utf8data[xx];
gub = &glb->utf8data[xx];
if (memcmp(gua, gub, sizeof (struct grid_utf8)) != 0)
return (1);
}
}
@@ -233,20 +225,6 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx)
gl->cellsize = sx;
}
/* Expand line to fit to cell for UTF-8. */
void
grid_expand_line_utf8(struct grid *gd, u_int py, u_int sx)
{
struct grid_line *gl;
gl = &gd->linedata[py];
if (sx <= gl->utf8size)
return;
gl->utf8data = xrealloc(gl->utf8data, sx, sizeof *gl->utf8data);
gl->utf8size = sx;
}
/* Get cell for reading. */
const struct grid_cell *
grid_peek_cell(struct grid *gd, u_int px, u_int py)
@@ -282,41 +260,6 @@ grid_set_cell(
grid_put_cell(gd, px, py, gc);
}
/* Get UTF-8 for reading. */
const struct grid_utf8 *
grid_peek_utf8(struct grid *gd, u_int px, u_int py)
{
if (grid_check_y(gd, py) != 0)
return (NULL);
if (px >= gd->linedata[py].utf8size)
return (NULL);
return (&gd->linedata[py].utf8data[px]);
}
/* Get utf8 at relative position (for writing). */
struct grid_utf8 *
grid_get_utf8(struct grid *gd, u_int px, u_int py)
{
if (grid_check_y(gd, py) != 0)
return (NULL);
grid_expand_line_utf8(gd, py, px + 1);
return (&gd->linedata[py].utf8data[px]);
}
/* Set utf8 at relative position. */
void
grid_set_utf8(
struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gc)
{
if (grid_check_y(gd, py) != 0)
return;
grid_expand_line_utf8(gd, py, px + 1);
grid_put_utf8(gd, px, py, gc);
}
/* Clear area. */
void
grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
@@ -373,7 +316,6 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny)
for (yy = py; yy < py + ny; yy++) {
gl = &gd->linedata[yy];
free(gl->celldata);
free(gl->utf8data);
memset(gl, 0, sizeof *gl);
}
}
@@ -437,13 +379,6 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
memmove(
&gl->celldata[dx], &gl->celldata[px], nx * sizeof *gl->celldata);
if (gl->utf8data != NULL) {
grid_expand_line_utf8(gd, py, px + nx);
grid_expand_line_utf8(gd, py, dx + nx);
memmove(&gl->utf8data[dx],
&gl->utf8data[px], nx * sizeof *gl->utf8data);
}
/* Wipe any cells that have been moved. */
for (xx = px; xx < px + nx; xx++) {
if (xx >= dx && xx < dx + nx)
@@ -457,9 +392,9 @@ char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
const struct grid_cell *gc;
const struct grid_utf8 *gu;
struct utf8_data ud;
char *buf;
size_t len, off, size;
size_t len, off;
u_int xx;
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
@@ -472,25 +407,15 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
gc = grid_peek_cell(gd, xx, py);
if (gc->flags & GRID_FLAG_PADDING)
continue;
grid_cell_get(gc, &ud);
if (gc->flags & GRID_FLAG_UTF8) {
gu = grid_peek_utf8(gd, xx, py);
size = grid_utf8_size(gu);
while (len < off + size + 1) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
off += grid_utf8_copy(gu, buf + off, len - off);
} else {
while (len < off + 2) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
buf[off++] = gc->data;
while (len < off + ud.size + 1) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
memcpy(buf + off, ud.data, ud.size);
off += ud.size;
}
while (off > 0 && buf[off - 1] == ' ')
@@ -530,14 +455,49 @@ grid_duplicate_lines(
memcpy(dstl->celldata, srcl->celldata,
srcl->cellsize * sizeof *dstl->celldata);
}
if (srcl->utf8size != 0) {
dstl->utf8data = xcalloc(
srcl->utf8size, sizeof *dstl->utf8data);
memcpy(dstl->utf8data, srcl->utf8data,
srcl->utf8size * sizeof *dstl->utf8data);
}
sy++;
dy++;
}
}
/*
* Reflow lines from src grid into dst grid based on width sx. Returns number
* of lines fewer in the visible area, or zero.
*/
u_int
grid_reflow(struct grid *dst, const struct grid *src, u_int sx)
{
u_int px, py, line, cell;
int previous_wrapped;
struct grid_line *gl;
px = py = 0;
previous_wrapped = 1;
for (line = 0; line < src->sy + src->hsize; line++) {
gl = src->linedata + line;
if (!previous_wrapped) {
px = 0;
py++;
if (py >= dst->hsize + dst->sy)
grid_scroll_history(dst);
}
for (cell = 0; cell < gl->cellsize; cell++) {
if (px == sx) {
dst->linedata[py].flags |= GRID_LINE_WRAPPED;
px = 0;
py++;
if (py >= dst->hsize + dst->sy)
grid_scroll_history(dst);
}
grid_set_cell(dst, px, py, gl->celldata + cell);
px++;
}
previous_wrapped = gl->flags & GRID_LINE_WRAPPED;
}
py++; /* account for final line, which never wraps */
if (py > src->sy)
return (0);
return (src->sy - py);
}
+16 -9
View File
@@ -199,22 +199,23 @@ input_key(struct window_pane *wp, int key)
/* Translate mouse and output. */
void
input_mouse(struct window_pane *wp, struct mouse_event *m)
input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m)
{
char buf[10];
size_t len;
char buf[10];
size_t len;
struct paste_buffer *pb;
if (wp->screen->mode & ALL_MOUSE_MODES) {
if (wp->screen->mode & MODE_MOUSE_UTF8) {
len = xsnprintf(buf, sizeof buf, "\033[M");
len += utf8_split2(m->b + 32, &buf[len]);
len += utf8_split2(m->xb + 32, &buf[len]);
len += utf8_split2(m->x + 33, &buf[len]);
len += utf8_split2(m->y + 33, &buf[len]);
} else {
if (m->b > 223 || m->x >= 222 || m->y > 222)
if (m->xb > 223 || m->x >= 222 || m->y > 222)
return;
len = xsnprintf(buf, sizeof buf, "\033[M");
buf[len++] = m->b + 32;
buf[len++] = m->xb + 32;
buf[len++] = m->x + 33;
buf[len++] = m->y + 33;
}
@@ -222,13 +223,19 @@ input_mouse(struct window_pane *wp, struct mouse_event *m)
return;
}
if ((m->b & 3) != 1 &&
if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) &&
options_get_number(&wp->window->options, "mode-mouse") == 1) {
pb = paste_get_top(&global_buffers);
if (pb != NULL) {
paste_send_pane(pb, wp, "\r",
wp->screen->mode & MODE_BRACKETPASTE);
}
} else if ((m->xb & 3) != 1 &&
options_get_number(&wp->window->options, "mode-mouse") == 1) {
if (window_pane_set_mode(wp, &window_copy_mode) == 0) {
window_copy_init_from_pane(wp);
if (wp->mode->mouse != NULL)
wp->mode->mouse(wp, NULL, m);
wp->mode->mouse(wp, s, m);
}
return;
}
}
+22 -9
View File
@@ -135,6 +135,7 @@ enum input_csi_type {
INPUT_CSI_DECSTBM,
INPUT_CSI_DL,
INPUT_CSI_DSR,
INPUT_CSI_ECH,
INPUT_CSI_ED,
INPUT_CSI_EL,
INPUT_CSI_HPA,
@@ -167,6 +168,7 @@ const struct input_table_entry input_csi_table[] = {
{ 'L', "", INPUT_CSI_IL },
{ 'M', "", INPUT_CSI_DL },
{ 'P', "", INPUT_CSI_DCH },
{ 'X', "", INPUT_CSI_ECH },
{ 'Z', "", INPUT_CSI_CBT },
{ 'c', "", INPUT_CSI_DA },
{ 'c', ">", INPUT_CSI_DA_TWO },
@@ -877,8 +879,8 @@ input_clear(struct input_ctx *ictx)
int
input_print(struct input_ctx *ictx)
{
ictx->cell.data = ictx->ch;
screen_write_cell(&ictx->ctx, &ictx->cell, NULL);
grid_cell_one(&ictx->cell, ictx->ch);
screen_write_cell(&ictx->ctx, &ictx->cell);
return (0);
}
@@ -1143,6 +1145,9 @@ input_csi_dispatch(struct input_ctx *ictx)
break;
}
break;
case INPUT_CSI_ECH:
screen_write_clearcharacter(sctx, input_get(ictx, 0, 1, 1));
break;
case INPUT_CSI_DCH:
screen_write_deletecharacter(sctx, input_get(ictx, 0, 1, 1));
break;
@@ -1255,8 +1260,12 @@ input_csi_dispatch(struct input_ctx *ictx)
case 1005:
screen_write_utf8mousemode(&ictx->ctx, 0);
break;
case 47:
case 1047:
window_pane_alternate_off(wp, &ictx->cell, 0);
break;
case 1049:
window_pane_alternate_off(wp, &ictx->cell);
window_pane_alternate_off(wp, &ictx->cell, 1);
break;
case 2004:
screen_write_bracketpaste(&ictx->ctx, 0);
@@ -1310,8 +1319,12 @@ input_csi_dispatch(struct input_ctx *ictx)
case 1005:
screen_write_utf8mousemode(&ictx->ctx, 1);
break;
case 47:
case 1047:
window_pane_alternate_on(wp, &ictx->cell, 0);
break;
case 1049:
window_pane_alternate_on(wp, &ictx->cell);
window_pane_alternate_on(wp, &ictx->cell, 1);
break;
case 2004:
screen_write_bracketpaste(&ictx->ctx, 1);
@@ -1552,10 +1565,11 @@ input_exit_osc(struct input_ctx *ictx)
server_status_window(ictx->wp->window);
break;
case 12:
screen_set_cursor_colour(ictx->ctx.s, p);
if (*p != '?') /* ? is colour request */
screen_set_cursor_colour(ictx->ctx.s, p);
break;
case 112:
if (*p == '\0') /* No arguments allowed. */
if (*p == '\0') /* no arguments allowed */
screen_set_cursor_colour(ictx->ctx.s, "");
break;
default:
@@ -1643,9 +1657,8 @@ input_utf8_close(struct input_ctx *ictx)
utf8_append(&ictx->utf8data, ictx->ch);
ictx->cell.flags |= GRID_FLAG_UTF8;
screen_write_cell(&ictx->ctx, &ictx->cell, &ictx->utf8data);
ictx->cell.flags &= ~GRID_FLAG_UTF8;
grid_cell_set(&ictx->cell, &ictx->utf8data);
screen_write_cell(&ictx->ctx, &ictx->cell);
return (0);
}
-2
View File
@@ -130,7 +130,6 @@ key_bindings_init(void)
{ '?', 0, &cmd_list_keys_entry },
{ 'D', 0, &cmd_choose_client_entry },
{ 'L', 0, &cmd_switch_client_entry },
{ 'U', 1, &cmd_select_layout_entry },
{ '[', 0, &cmd_copy_mode_entry },
{ '\'', 0, &cmd_command_prompt_entry },
{ '\002', /* C-b */ 0, &cmd_send_prefix_entry },
@@ -149,7 +148,6 @@ key_bindings_init(void)
{ 'r', 0, &cmd_refresh_client_entry },
{ 's', 0, &cmd_choose_tree_entry },
{ 't', 0, &cmd_clock_mode_entry },
{ 'u', 1, &cmd_select_layout_entry },
{ 'w', 0, &cmd_choose_window_entry },
{ 'x', 0, &cmd_confirm_before_entry },
{ '{', 0, &cmd_swap_pane_entry },
+21 -92
View File
@@ -19,7 +19,6 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -488,50 +487,51 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change)
}
void
layout_resize_pane_mouse(struct client *c, struct mouse_event *mouse)
layout_resize_pane_mouse(struct client *c)
{
struct window *w;
struct window_pane *wp;
struct mouse_event *m = &c->tty.mouse;
int pane_border;
w = c->session->curw->window;
pane_border = 0;
if ((c->last_mouse.b & MOUSE_BUTTON) != MOUSE_UP &&
(c->last_mouse.b & MOUSE_RESIZE_PANE)) {
if (m->event & MOUSE_EVENT_DRAG && m->flags & MOUSE_RESIZE_PANE) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->xoff + wp->sx == c->last_mouse.x &&
wp->yoff <= 1 + c->last_mouse.y &&
wp->yoff + wp->sy >= c->last_mouse.y) {
if (wp->xoff + wp->sx == m->lx &&
wp->yoff <= 1 + m->ly &&
wp->yoff + wp->sy >= m->ly) {
layout_resize_pane(wp, LAYOUT_LEFTRIGHT,
mouse->x - c->last_mouse.x);
m->x - m->lx);
pane_border = 1;
}
if (wp->yoff + wp->sy == c->last_mouse.y &&
wp->xoff <= 1 + c->last_mouse.x &&
wp->xoff + wp->sx >= c->last_mouse.x) {
if (wp->yoff + wp->sy == m->ly &&
wp->xoff <= 1 + m->lx &&
wp->xoff + wp->sx >= m->lx) {
layout_resize_pane(wp, LAYOUT_TOPBOTTOM,
mouse->y - c->last_mouse.y);
m->y - m->ly);
pane_border = 1;
}
}
if (pane_border)
server_redraw_window(w);
} else if (mouse->b != MOUSE_UP &&
mouse->b == (mouse->b & MOUSE_BUTTON)) {
} else if (~m->event & MOUSE_EVENT_UP) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if ((wp->xoff + wp->sx == mouse->x &&
wp->yoff <= 1 + mouse->y &&
wp->yoff + wp->sy >= mouse->y) ||
(wp->yoff + wp->sy == mouse->y &&
wp->xoff <= 1 + mouse->x &&
wp->xoff + wp->sx >= mouse->x)) {
if ((wp->xoff + wp->sx == m->x &&
wp->yoff <= 1 + m->y &&
wp->yoff + wp->sy >= m->y) ||
(wp->yoff + wp->sy == m->y &&
wp->xoff <= 1 + m->x &&
wp->xoff + wp->sx >= m->x)) {
pane_border = 1;
}
}
}
if (pane_border)
mouse->b |= MOUSE_RESIZE_PANE;
m->flags |= MOUSE_RESIZE_PANE;
else
m->flags &= ~MOUSE_RESIZE_PANE;
}
int
@@ -746,74 +746,3 @@ layout_close_pane(struct window_pane *wp)
}
notify_window_layout_changed(wp->window);
}
/* Add layout to list. */
void
layout_list_add(struct window *w)
{
struct last_layout *ll, *ll_last;
char *layout;
u_int limit;
layout = layout_dump(w);
ll_last = w->layout_list_last;
if (ll_last != NULL && strcmp(ll_last->layout, layout) == 0) {
free(layout);
return;
}
ll = xmalloc(sizeof *ll);
ll->layout = layout;
if (ll_last == NULL)
TAILQ_INSERT_TAIL(&w->layout_list, ll, entry);
else
TAILQ_INSERT_AFTER(&w->layout_list, ll_last, ll, entry);
w->layout_list_size++;
w->layout_list_last = ll;
limit = options_get_number(&w->options, "layout-history-limit");
while (w->layout_list_size > limit) {
ll = TAILQ_LAST(&w->layout_list, last_layouts);
if (ll == w->layout_list_last)
ll = TAILQ_FIRST(&w->layout_list);
TAILQ_REMOVE(&w->layout_list, ll, entry);
w->layout_list_size--;
free(ll->layout);
free(ll);
}
}
/* Apply next layout from list. */
const char *
layout_list_redo(struct window *w)
{
struct last_layout *ll, *ll_last;
ll_last = w->layout_list_last;
if (ll_last == NULL)
return (NULL);
ll = TAILQ_NEXT(ll_last, entry);
if (ll == NULL)
return (NULL);
w->layout_list_last = ll;
return (ll->layout);
}
/* Apply previous layout from list. */
const char *
layout_list_undo(struct window *w)
{
struct last_layout *ll, *ll_last;
ll_last = w->layout_list_last;
if (ll_last == NULL)
return (NULL);
ll = TAILQ_PREV(ll_last, last_layouts, entry);
if (ll == NULL)
return (NULL);
w->layout_list_last = ll;
return (ll->layout);
}
+2
View File
@@ -105,6 +105,8 @@ const struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
{ MODEKEYCOPY_DOWN, "cursor-down" },
{ MODEKEYCOPY_ENDOFLINE, "end-of-line" },
{ MODEKEYCOPY_GOTOLINE, "goto-line" },
{ MODEKEYCOPY_HALFPAGEDOWN, "halfpage-down" },
{ MODEKEYCOPY_HALFPAGEUP, "halfpage-up" },
{ MODEKEYCOPY_HISTORYBOTTOM, "history-bottom" },
{ MODEKEYCOPY_HISTORYTOP, "history-top" },
{ MODEKEYCOPY_JUMP, "jump-forward" },
+1 -1
View File
@@ -76,7 +76,7 @@ window_name_callback(unused int fd, unused short events, void *data)
name != NULL && name[0] == '-' && name[1] != '\0')
wname = parse_window_name(name + 1);
else
wname = parse_window_name(name);
wname = parse_window_name(name);
free(name);
}
+22 -7
View File
@@ -90,6 +90,13 @@ const struct options_table_entry server_options_table[] = {
/* Session options. */
const struct options_table_entry session_options_table[] = {
{ .name = "assume-paste-time",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 1,
},
{ .name = "base-index",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
@@ -509,13 +516,6 @@ const struct options_table_entry window_options_table[] = {
.default_num = 0
},
{ .name = "layout-history-limit",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 1,
.maximum = USHRT_MAX,
.default_num = 20
},
{ .name = "main-pane-height",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 1,
@@ -685,6 +685,21 @@ const struct options_table_entry window_options_table[] = {
.default_str = "#I:#W#F"
},
{ .name = "window-status-last-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "window-status-last-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-last-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
+1
View File
@@ -17,6 +17,7 @@
*/
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
+26
View File
@@ -166,3 +166,29 @@ paste_print(struct paste_buffer *pb, size_t width)
return (buf);
}
/* Paste into a window pane, filtering '\n' according to separator. */
void
paste_send_pane (struct paste_buffer *pb, struct window_pane *wp,
const char *sep, int bracket)
{
const char *data = pb->data, *end = data + pb->size, *lf;
size_t seplen;
if (bracket)
bufferevent_write(wp->event, "\033[200~", 6);
seplen = strlen(sep);
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
bufferevent_write(wp->event, data, lf - data);
bufferevent_write(wp->event, sep, seplen);
data = lf + 1;
}
if (end != data)
bufferevent_write(wp->event, data, end - data);
if (bracket)
bufferevent_write(wp->event, "\033[201~", 6);
}
+67 -78
View File
@@ -67,11 +67,10 @@ screen_write_reset(struct screen_write_ctx *ctx)
/* Write character. */
void
screen_write_putc(
struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch)
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch)
{
gc->data = ch;
screen_write_cell(ctx, gc, NULL);
grid_cell_one(gc, ch);
screen_write_cell(ctx, gc);
}
/* Calculate string length, with embedded formatting. */
@@ -203,9 +202,8 @@ screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
}
size += utf8data.width;
gc->flags |= GRID_FLAG_UTF8;
screen_write_cell(ctx, gc, &utf8data);
gc->flags &= ~GRID_FLAG_UTF8;
grid_cell_set(gc, &utf8data);
screen_write_cell(ctx, gc);
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
@@ -277,9 +275,8 @@ screen_write_cnputs(struct screen_write_ctx *ctx,
}
size += utf8data.width;
lgc.flags |= GRID_FLAG_UTF8;
screen_write_cell(ctx, &lgc, &utf8data);
lgc.flags &= ~GRID_FLAG_UTF8;
grid_cell_set(&lgc, &utf8data);
screen_write_cell(ctx, &lgc);
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
@@ -324,6 +321,9 @@ screen_write_parsestyle(
fg = defgc->fg;
bg = defgc->bg;
attr = defgc->attr;
flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
flags |=
defgc->flags & (GRID_FLAG_FG256|GRID_FLAG_BG256);
} else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
if ((val = colour_fromstring(tmp + 3)) == -1)
return;
@@ -335,8 +335,11 @@ screen_write_parsestyle(
} else
flags &= ~GRID_FLAG_FG256;
fg = val;
} else
} else {
fg = defgc->fg;
flags &= ~GRID_FLAG_FG256;
flags |= defgc->flags & GRID_FLAG_FG256;
}
} else if (*in == 'b' || *in == 'B') {
if (val != 8) {
if (val & 0x100) {
@@ -345,8 +348,11 @@ screen_write_parsestyle(
} else
flags &= ~GRID_FLAG_BG256;
bg = val;
} else
} else {
bg = defgc->bg;
flags &= ~GRID_FLAG_BG256;
flags |= defgc->flags & GRID_FLAG_BG256;
}
} else
return;
} else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) {
@@ -376,8 +382,7 @@ screen_write_copy(struct screen_write_ctx *ctx,
struct grid *gd = src->grid;
struct grid_line *gl;
const struct grid_cell *gc;
const struct grid_utf8 *gu;
struct utf8_data utf8data;
struct utf8_data ud;
u_int xx, yy, cx, cy, ax, bx;
cx = s->cx;
@@ -405,16 +410,8 @@ screen_write_copy(struct screen_write_ctx *ctx,
gc = &grid_default_cell;
else
gc = &gl->celldata[xx];
if (!(gc->flags & GRID_FLAG_UTF8)) {
screen_write_cell(ctx, gc, NULL);
continue;
}
/* Reinject the UTF-8 sequence. */
gu = &gl->utf8data[xx];
utf8data.size = grid_utf8_copy(
gu, utf8data.data, sizeof utf8data.data);
utf8data.width = gu->width;
screen_write_cell(ctx, gc, &utf8data);
grid_cell_get(gc, &ud);
screen_write_cell(ctx, gc);
}
if (px + nx == gd->sx && px + nx > gl->cellsize)
screen_write_clearendofline(ctx);
@@ -433,7 +430,6 @@ screen_write_initctx(
struct screen *s = ctx->s;
struct grid *gd = s->grid;
const struct grid_cell *gc;
const struct grid_utf8 *gu;
u_int xx;
ttyctx->wp = ctx->wp;
@@ -456,10 +452,6 @@ screen_write_initctx(
}
ttyctx->last_width = xx;
memcpy(&ttyctx->last_cell, gc, sizeof ttyctx->last_cell);
if (gc->flags & GRID_FLAG_UTF8) {
gu = grid_view_peek_utf8(gd, screen_size_x(s) - xx, s->cy);
memcpy(&ttyctx->last_utf8, gu, sizeof ttyctx->last_utf8);
}
}
/* Cursor up by ny. */
@@ -575,7 +567,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
screen_write_initctx(ctx, &ttyctx, 0);
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.data = 'E';
grid_cell_one(&gc, 'E');
for (yy = 0; yy < screen_size_y(s); yy++) {
for (xx = 0; xx < screen_size_x(s); xx++)
@@ -640,6 +632,30 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
tty_write(tty_cmd_deletecharacter, &ttyctx);
}
/* Clear nx characters. */
void
screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx)
{
struct screen *s = ctx->s;
struct tty_ctx ttyctx;
if (nx == 0)
nx = 1;
if (nx > screen_size_x(s) - s->cx)
nx = screen_size_x(s) - s->cx;
if (nx == 0)
return;
screen_write_initctx(ctx, &ttyctx, 0);
if (s->cx <= screen_size_x(s) - 1)
grid_view_clear(s->grid, s->cx, s->cy, nx, 1);
ttyctx.num = nx;
tty_write(tty_cmd_clearcharacter, &ttyctx);
}
/* Insert ny lines. */
void
screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
@@ -1033,26 +1049,20 @@ screen_write_clearhistory(struct screen_write_ctx *ctx)
/* Write cell data. */
void
screen_write_cell(struct screen_write_ctx *ctx,
const struct grid_cell *gc, const struct utf8_data *utf8data)
screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
{
struct screen *s = ctx->s;
struct grid *gd = s->grid;
struct tty_ctx ttyctx;
struct grid_utf8 gu;
u_int width, xx;
struct grid_cell tmp_gc, *tmp_gcp;
struct utf8_data ud;
int insert = 0;
/* Ignore padding. */
if (gc->flags & GRID_FLAG_PADDING)
return;
/* Find character width. */
if (gc->flags & GRID_FLAG_UTF8)
width = utf8data->width;
else
width = 1;
width = grid_cell_width(gc);
/*
* If this is a wide character and there is no room on the screen, for
@@ -1069,7 +1079,8 @@ screen_write_cell(struct screen_write_ctx *ctx,
* there is space.
*/
if (width == 0) {
if (screen_write_combine(ctx, utf8data) == 0) {
grid_cell_get(gc, &ud);
if (screen_write_combine(ctx, &ud) == 0) {
screen_write_initctx(ctx, &ttyctx, 0);
tty_write(tty_cmd_utf8character, &ttyctx);
}
@@ -1112,11 +1123,6 @@ screen_write_cell(struct screen_write_ctx *ctx,
/* Set the cell. */
grid_view_set_cell(gd, s->cx, s->cy, gc);
if (gc->flags & GRID_FLAG_UTF8) {
/* Construct UTF-8 and write it. */
grid_utf8_set(&gu, utf8data);
grid_view_set_utf8(gd, s->cx, s->cy, &gu);
}
/* Move the cursor. */
s->cx += width;
@@ -1126,12 +1132,11 @@ screen_write_cell(struct screen_write_ctx *ctx,
ttyctx.num = width;
tty_write(tty_cmd_insertcharacter, &ttyctx);
}
ttyctx.utf8 = &gu;
if (screen_check_selection(s, s->cx - width, s->cy)) {
memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc);
tmp_gc.data = gc->data;
tmp_gc.flags = gc->flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
grid_cell_get(gc, &ud);
grid_cell_set(&tmp_gc, &ud);
tmp_gc.flags = gc->flags & ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmp_gc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
ttyctx.cell = &tmp_gc;
@@ -1144,49 +1149,33 @@ screen_write_cell(struct screen_write_ctx *ctx,
/* Combine a UTF-8 zero-width character onto the previous. */
int
screen_write_combine(
struct screen_write_ctx *ctx, const struct utf8_data *utf8data)
screen_write_combine(struct screen_write_ctx *ctx, const struct utf8_data *ud)
{
struct screen *s = ctx->s;
struct grid *gd = s->grid;
struct grid_cell *gc;
struct grid_utf8 *gu, tmp_gu;
u_int i;
struct utf8_data ud1;
/* Can't combine if at 0. */
if (s->cx == 0)
return (-1);
/* Empty utf8data is out. */
if (utf8data->size == 0)
/* Empty data is out. */
if (ud->size == 0)
fatalx("UTF-8 data empty");
/* Retrieve the previous cell and convert to UTF-8 if not already. */
/* Retrieve the previous cell. */
gc = grid_view_get_cell(gd, s->cx - 1, s->cy);
if (!(gc->flags & GRID_FLAG_UTF8)) {
tmp_gu.data[0] = gc->data;
tmp_gu.data[1] = 0xff;
tmp_gu.width = 1;
grid_cell_get(gc, &ud1);
grid_view_set_utf8(gd, s->cx - 1, s->cy, &tmp_gu);
gc->flags |= GRID_FLAG_UTF8;
}
/* Check there is enough space. */
if (ud1.size + ud->size > sizeof ud1.data)
return (-1);
/* Append the current cell. */
gu = grid_view_get_utf8(gd, s->cx - 1, s->cy);
if (grid_utf8_append(gu, utf8data) != 0) {
/* Failed: scrap this character and replace with underscores. */
if (gu->width == 1) {
gc->data = '_';
gc->flags &= ~GRID_FLAG_UTF8;
} else {
for (i = 0; i < gu->width && i != sizeof gu->data; i++)
gu->data[i] = '_';
if (i != sizeof gu->data)
gu->data[i] = 0xff;
gu->width = i;
}
}
/* Append the data and set the cell. */
memcpy(ud1.data + ud1.size, ud->data, ud->size);
ud1.size += ud->size;
grid_cell_set(gc, &ud1);
return (0);
}
+19 -1
View File
@@ -121,7 +121,7 @@ screen_set_title(struct screen *s, const char *title)
/* Resize screen. */
void
screen_resize(struct screen *s, u_int sx, u_int sy)
screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
{
if (sx < 1)
sx = 1;
@@ -141,6 +141,9 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
if (sy != screen_size_y(s))
screen_resize_y(s, sy);
if (reflow)
screen_reflow(s, sx);
}
void
@@ -357,3 +360,18 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
return (1);
}
/* Reflow wrapped lines. */
void
screen_reflow(struct screen *s, u_int sx)
{
struct grid *old, *new;
old = s->grid;
new = grid_create(old->sx, old->sy, old->hlimit);
s->cy -= grid_reflow(new, old, sx);
s->grid = new;
grid_destroy(old);
}
+70 -52
View File
@@ -27,13 +27,13 @@
#include "tmux.h"
void server_client_check_mouse(struct client *, struct window_pane *,
struct mouse_event *);
void server_client_check_mouse(struct client *, struct window_pane *);
void server_client_repeat_timer(int, short, void *);
void server_client_check_exit(struct client *);
void server_client_check_redraw(struct client *);
void server_client_set_title(struct client *);
void server_client_reset_state(struct client *);
int server_client_assume_paste(struct session *);
int server_client_msg_dispatch(struct client *);
void server_client_msg_command(struct client *, struct msg_command_data *);
@@ -86,8 +86,12 @@ server_client_create(int fd)
c->prompt_buffer = NULL;
c->prompt_index = 0;
c->last_mouse.b = MOUSE_UP;
c->last_mouse.x = c->last_mouse.y = -1;
c->tty.mouse.xb = c->tty.mouse.button = 3;
c->tty.mouse.x = c->tty.mouse.y = -1;
c->tty.mouse.lx = c->tty.mouse.ly = -1;
c->tty.mouse.sx = c->tty.mouse.sy = -1;
c->tty.mouse.event = MOUSE_EVENT_UP;
c->tty.mouse.flags = 0;
evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
@@ -270,37 +274,28 @@ server_client_status_timer(void)
/* Check for mouse keys. */
void
server_client_check_mouse(
struct client *c, struct window_pane *wp, struct mouse_event *mouse)
server_client_check_mouse(struct client *c, struct window_pane *wp)
{
struct session *s = c->session;
struct options *oo = &s->options;
int statusat;
struct session *s = c->session;
struct options *oo = &s->options;
struct mouse_event *m = &c->tty.mouse;
int statusat;
statusat = status_at_line(c);
/* Is this a window selection click on the status line? */
if (statusat != -1 && mouse->y == (u_int)statusat &&
if (statusat != -1 && m->y == (u_int)statusat &&
options_get_number(oo, "mouse-select-window")) {
if (mouse->b == MOUSE_UP && c->last_mouse.b != MOUSE_UP) {
status_set_window_at(c, mouse->x);
recalculate_sizes();
return;
}
if (mouse->b & MOUSE_45) {
if ((mouse->b & MOUSE_BUTTON) == MOUSE_1) {
if (m->event & MOUSE_EVENT_CLICK) {
status_set_window_at(c, m->x);
} else if (m->event == MOUSE_EVENT_WHEEL) {
if (m->wheel == MOUSE_WHEEL_UP)
session_previous(c->session, 0);
server_redraw_session(s);
recalculate_sizes();
}
if ((mouse->b & MOUSE_BUTTON) == MOUSE_2) {
else if (m->wheel == MOUSE_WHEEL_DOWN)
session_next(c->session, 0);
server_redraw_session(s);
recalculate_sizes();
}
return;
server_redraw_session(s);
}
memcpy(&c->last_mouse, mouse, sizeof c->last_mouse);
recalculate_sizes();
return;
}
@@ -309,27 +304,41 @@ server_client_check_mouse(
* top and limit if at the bottom. From here on a struct mouse
* represents the offset onto the window itself.
*/
if (statusat == 0 &&mouse->y > 0)
mouse->y--;
else if (statusat > 0 && mouse->y >= (u_int)statusat)
mouse->y = statusat - 1;
if (statusat == 0 && m->y > 0)
m->y--;
else if (statusat > 0 && m->y >= (u_int)statusat)
m->y = statusat - 1;
/* Is this a pane selection? Allow down only in copy mode. */
if (options_get_number(oo, "mouse-select-pane") &&
((!(mouse->b & MOUSE_DRAG) && mouse->b != MOUSE_UP) ||
wp->mode != &window_copy_mode)) {
window_set_active_at(wp->window, mouse->x, mouse->y);
(m->event == MOUSE_EVENT_DOWN || wp->mode != &window_copy_mode)) {
window_set_active_at(wp->window, m->x, m->y);
server_redraw_window_borders(wp->window);
wp = wp->window->active; /* may have changed */
}
/* Check if trying to resize pane. */
if (options_get_number(oo, "mouse-resize-pane"))
layout_resize_pane_mouse(c, mouse);
layout_resize_pane_mouse(c);
/* Update last and pass through to client. */
memcpy(&c->last_mouse, mouse, sizeof c->last_mouse);
window_pane_mouse(wp, c->session, mouse);
window_pane_mouse(wp, c->session, m);
}
/* Is this fast enough to probably be a paste? */
int
server_client_assume_paste(struct session *s)
{
struct timeval tv;
int t;
if ((t = options_get_number(&s->options, "assume-paste-time")) == 0)
return (0);
timersub(&s->activity_time, &s->last_activity_time, &tv);
if (tv.tv_sec == 0 && tv.tv_usec < t * 1000)
return (1);
return (0);
}
/* Handle data key input from client. */
@@ -341,7 +350,7 @@ server_client_handle_key(struct client *c, int key)
struct window_pane *wp;
struct timeval tv;
struct key_binding *bd;
int xtimeout, isprefix;
int xtimeout, isprefix, ispaste;
/* Check the client is good to accept input. */
if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
@@ -353,6 +362,9 @@ server_client_handle_key(struct client *c, int key)
/* Update the activity timer. */
if (gettimeofday(&c->activity_time, NULL) != 0)
fatal("gettimeofday failed");
memcpy(&s->last_activity_time, &s->activity_time,
sizeof s->last_activity_time);
memcpy(&s->activity_time, &c->activity_time, sizeof s->activity_time);
w = c->session->curw->window;
@@ -384,30 +396,36 @@ server_client_handle_key(struct client *c, int key)
if (key == KEYC_MOUSE) {
if (c->flags & CLIENT_READONLY)
return;
server_client_check_mouse(c, wp, &c->tty.mouse);
server_client_check_mouse(c, wp);
return;
}
/* Is this a prefix key? */
if (key == options_get_number(&c->session->options, "prefix"))
if (key == options_get_number(&s->options, "prefix"))
isprefix = 1;
else if (key == options_get_number(&c->session->options, "prefix2"))
else if (key == options_get_number(&s->options, "prefix2"))
isprefix = 1;
else
isprefix = 0;
/* Treat prefix as a regular key when pasting is detected. */
ispaste = server_client_assume_paste(s);
if (ispaste)
isprefix = 0;
/* No previous prefix key. */
if (!(c->flags & CLIENT_PREFIX)) {
if (isprefix)
if (isprefix) {
c->flags |= CLIENT_PREFIX;
else {
/* Try as a non-prefix key binding. */
if ((bd = key_bindings_lookup(key)) == NULL) {
if (!(c->flags & CLIENT_READONLY))
window_pane_key(wp, c->session, key);
} else
key_bindings_dispatch(bd, c);
return;
}
/* Try as a non-prefix key binding. */
if (ispaste || (bd = key_bindings_lookup(key)) == NULL) {
if (!(c->flags & CLIENT_READONLY))
window_pane_key(wp, s, key);
} else
key_bindings_dispatch(bd, c);
return;
}
@@ -420,7 +438,7 @@ server_client_handle_key(struct client *c, int key)
if (isprefix)
c->flags |= CLIENT_PREFIX;
else if (!(c->flags & CLIENT_READONLY))
window_pane_key(wp, c->session, key);
window_pane_key(wp, s, key);
}
return;
}
@@ -431,12 +449,12 @@ server_client_handle_key(struct client *c, int key)
if (isprefix)
c->flags |= CLIENT_PREFIX;
else if (!(c->flags & CLIENT_READONLY))
window_pane_key(wp, c->session, key);
window_pane_key(wp, s, key);
return;
}
/* If this key can repeat, reset the repeat flags and timer. */
xtimeout = options_get_number(&c->session->options, "repeat-time");
xtimeout = options_get_number(&s->options, "repeat-time");
if (xtimeout != 0 && bd->can_repeat) {
c->flags |= CLIENT_PREFIX|CLIENT_REPEAT;
@@ -523,7 +541,7 @@ server_client_reset_state(struct client *c)
* a smooth appearance.
*/
mode = s->mode;
if ((c->last_mouse.b & MOUSE_RESIZE_PANE) &&
if ((c->tty.mouse.flags & MOUSE_RESIZE_PANE) &&
!(mode & (MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)))
mode |= MODE_MOUSE_BUTTON;
+3 -1
View File
@@ -75,12 +75,14 @@ server_window_check_bell(struct session *s, struct winlink *wl)
if (s->curw != wl || s->flags & SESSION_UNATTACHED)
wl->flags |= WINLINK_BELL;
if (s->flags & SESSION_UNATTACHED)
return (1);
return (0);
if (s->curw->window == wl->window)
w->flags &= ~WINDOW_BELL;
visual = options_get_number(&s->options, "visual-bell");
action = options_get_number(&s->options, "bell-action");
if (action == BELL_NONE)
return (0);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
+6 -17
View File
@@ -105,11 +105,8 @@ server_create_socket(void)
int
server_start(int lockfd, char *lockfile)
{
struct window_pane *wp;
int pair[2];
char *cause;
struct timeval tv;
u_int i;
int pair[2];
struct timeval tv;
/* The first client is special and gets a socketpair; create it. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
@@ -170,7 +167,7 @@ server_start(int lockfd, char *lockfile)
load_cfg(SYSTEM_CFG, NULL, &cfg_causes);
else if (errno != ENOENT) {
cfg_add_cause(
&cfg_causes, "%s: %s", strerror(errno), SYSTEM_CFG);
&cfg_causes, "%s: %s", SYSTEM_CFG, strerror(errno));
}
if (cfg_file != NULL)
load_cfg(cfg_file, NULL, &cfg_causes);
@@ -179,17 +176,9 @@ server_start(int lockfd, char *lockfile)
* If there is a session already, put the current window and pane into
* more mode.
*/
if (!RB_EMPTY(&sessions) && !ARRAY_EMPTY(&cfg_causes)) {
wp = RB_MIN(sessions, &sessions)->curw->window->active;
window_pane_set_mode(wp, &window_copy_mode);
window_copy_init_for_output(wp);
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
window_copy_add(wp, "%s", cause);
free(cause);
}
ARRAY_FREE(&cfg_causes);
}
if (!RB_EMPTY(&sessions) && !ARRAY_EMPTY(&cfg_causes))
show_cfg_causes(RB_MIN(sessions, &sessions));
cfg_finished = 1;
server_add_accept(0);
+11
View File
@@ -705,6 +705,17 @@ status_print(
gc->attr = attr;
fmt = options_get_string(oo, "window-status-current-format");
}
if (wl == TAILQ_FIRST(&s->lastw)) {
fg = options_get_number(oo, "window-status-last-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-last-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-last-attr");
if (attr != 0)
gc->attr = attr;
}
if (wl->flags & WINLINK_BELL) {
fg = options_get_number(oo, "window-status-bell-fg");
+51 -24
View File
@@ -124,13 +124,19 @@ loads the system configuration file from
.Pa /etc/tmux.conf ,
if present, then looks for a user configuration file at
.Pa ~/.tmux.conf .
.Pp
The configuration file is a set of
.Nm
commands which are executed in sequence when the server is first started.
.Pp
If a command in the configuration file fails,
.Nm
will report an error and exit without executing further commands.
loads configuration files once when the server process has started.
The
.Ic source-file
command may be used to load a file later.
.Pp
.Nm
shows any error messages from commands in configuration files in the first
session created, and continues to process the rest of the configuration file.
.It Fl L Ar socket-name
.Nm
stores the server socket in a directory under
@@ -406,11 +412,15 @@ otherwise the current window in
is chosen.
The special character
.Ql \&!
uses the last (previously current) window, or
uses the last (previously current) window,
.Ql ^
selects the highest numbered window,
.Ql $
selects the lowest numbered window, and
.Ql +
and
.Ql -
are the next window or the previous window by number.
select the next window or the previous window by number.
When the argument does not contain a colon,
.Nm
first attempts to parse it as window; if that fails, an attempt is made to
@@ -1124,6 +1134,7 @@ This command works only from inside
.Ic choose-tree
.Op Fl s
.Op Fl w
.Op Fl u
.Op Fl b Ar session-template
.Op Fl c Ar window-template
.Op Fl S Ar format
@@ -1149,6 +1160,9 @@ If
.Fl w
is given, will show windows.
If
.Fl u
is given, the tree is uncollapsed by default.
If
.Fl b
is given, will override the default session command.
Note that
@@ -1591,7 +1605,7 @@ lower) with
.Fl U
or downward (numerically higher).
.It Xo Ic select-layout
.Op Fl npUu
.Op Fl np
.Op Fl t Ar target-window
.Op Ar layout-name
.Xc
@@ -1608,13 +1622,6 @@ are equivalent to the
and
.Ic previous-layout
commands.
.Pp
.Fl U
and
.Fl u
step forward and back through previous layouts, up to the maximum set by the
.Ic layout-history-limit
option.
.It Xo Ic select-pane
.Op Fl lDLRU
.Op Fl t Ar target-pane
@@ -1637,7 +1644,7 @@ is the same as using the
.Ic last-pane
command.
.It Xo Ic select-window
.Op Fl lnp
.Op Fl lnpT
.Op Fl t Ar target-window
.Xc
.D1 (alias: Ic selectw )
@@ -1653,6 +1660,11 @@ are equivalent to the
and
.Ic previous-window
commands.
If
.Fl T
is given and the selected window is already the current window,
the command behaves like
.Ic last-window .
.It Xo Ic split-window
.Op Fl dhvP
.Op Fl c Ar start-directory
@@ -2029,6 +2041,13 @@ interactive menu when required.
.Pp
Available session options are:
.Bl -tag -width Ds
.It Ic assume-paste-time Ar milliseconds
If keys are entered faster than one in
.Ar milliseconds ,
they are assumed to have been pasted rather than typed and
.Nm
key bindings are not processed.
The default is one millisecond and zero disables.
.It Ic base-index Ar index
Set the base index from which an unused index should be searched when a new
window is created.
@@ -2043,7 +2062,7 @@ window of that session,
.Ic none
means all bells are ignored and
.Ic current
means only bell in windows other than the current window are ignored.
means only bells in windows other than the current window are ignored.
.It Xo Ic bell-on-alert
.Op Ic on | off
.Xc
@@ -2655,13 +2674,6 @@ or
.Ar height .
A value of zero restores the default unlimited setting.
.Pp
.It Ic layout-history-limit Ar limit
Set the number of previous layouts stored for recovery with
.Ic select-layout
.Fl U
and
.Fl u .
.Pp
.It Ic main-pane-height Ar height
.It Ic main-pane-width Ar width
Set the width or height of the main (left or top) pane in the
@@ -2821,6 +2833,15 @@ Like
.Ar window-status-format ,
but is the format used when the window is the current window.
.Pp
.It Ic window-status-last-attr Ar attributes
Set status line attributes for the last active window.
.Pp
.It Ic window-status-last-bg Ar colour
Set status line background colour for the last active window.
.Pp
.It Ic window-status-last-fg Ar colour
Set status line foreground colour for the last active window.
.Pp
.It Ic window-status-fg Ar colour
Set status line foreground colour for a single window.
.Pp
@@ -3383,12 +3404,18 @@ otherwise.
Lock each client individually by running the command specified by the
.Ic lock-command
option.
.It Ic run-shell Ar shell-command
.It Xo Ic run-shell
.Op Fl t Ar target-pane
.Ar shell-command
.Xc
.D1 (alias: Ic run )
Execute
.Ar shell-command
in the background without creating a window.
After it finishes, any output to stdout is displayed in copy mode.
After it finishes, any output to stdout is displayed in copy mode (in the pane
specified by
.Fl t
or the current pane if omitted).
If the command doesn't return success, the exit status is also displayed.
.It Ic server-info
.D1 (alias: Ic info )
+8 -4
View File
@@ -162,7 +162,7 @@ parseenvironment(void)
char *
makesocketpath(const char *label)
{
char base[MAXPATHLEN], *path, *s;
char base[MAXPATHLEN], realbase[MAXPATHLEN], *path, *s;
struct stat sb;
u_int uid;
@@ -186,7 +186,10 @@ makesocketpath(const char *label)
return (NULL);
}
xasprintf(&path, "%s/%s", base, label);
if (realpath(base, realbase) == NULL)
strlcpy(realbase, base, sizeof realbase);
xasprintf(&path, "%s/%s", realbase, label);
return (path);
}
@@ -333,6 +336,8 @@ main(int argc, char **argv)
options_init(&global_w_options, NULL);
options_table_populate_tree(window_options_table, &global_w_options);
ARRAY_INIT(&cfg_causes);
/* Enable UTF-8 if the first client is on UTF-8 terminal. */
if (flags & IDENTIFY_UTF8) {
options_set_number(&global_s_options, "status-utf8", 1);
@@ -390,8 +395,7 @@ main(int argc, char **argv)
}
}
free(label);
if (realpath(path, socket_path) == NULL)
strlcpy(socket_path, path, sizeof socket_path);
strlcpy(socket_path, path, sizeof socket_path);
free(path);
#ifdef HAVE_SETPROCTITLE
+81 -92
View File
@@ -96,7 +96,8 @@ extern char **environ;
#define CHOOSE_CLIENT_TEMPLATE \
"#{client_tty}: #{session_name} " \
"[#{client_width}x#{client_height} #{client_termname}]" \
"#{?client_utf8, (utf8),} #{?client_readonly, (ro),}"
"#{?client_utf8, (utf8),}#{?client_readonly, (ro),} " \
"(last used #{client_activity_string})"
/* Default templates for choose-tree. */
#define CHOOSE_TREE_SESSION_TEMPLATE \
@@ -269,6 +270,7 @@ enum tty_code_code {
TTYC_DL, /* parm_delete_line, DL */
TTYC_DL1, /* delete_line, dl */
TTYC_E3,
TTYC_ECH, /* erase_chars, ec */
TTYC_EL, /* clr_eol, ce */
TTYC_EL1, /* clr_bol, cb */
TTYC_ENACS, /* ena_acs, eA */
@@ -663,13 +665,7 @@ struct mode_key_table {
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)
/*
* A single UTF-8 character.
*
* The data member in this must be UTF8_SIZE to allow screen_write_copy to
* reinject stored UTF-8 data back into screen_write_cell after combining (ugh
* XXX XXX).
*/
/* A single UTF-8 character. */
struct utf8_data {
u_char data[UTF8_SIZE];
@@ -703,7 +699,6 @@ struct utf8_data {
#define GRID_FLAG_FG256 0x1
#define GRID_FLAG_BG256 0x2
#define GRID_FLAG_PADDING 0x4
#define GRID_FLAG_UTF8 0x8
/* Grid line flags. */
#define GRID_LINE_WRAPPED 0x1
@@ -714,13 +709,9 @@ struct grid_cell {
u_char flags;
u_char fg;
u_char bg;
u_char data;
} __packed;
/* Grid cell UTF-8 data. Used instead of data in grid_cell for UTF-8 cells. */
struct grid_utf8 {
u_char width;
u_char data[UTF8_SIZE];
u_char xstate; /* top 4 bits width, bottom 4 bits size */
u_char xdata[UTF8_SIZE];
} __packed;
/* Grid line. */
@@ -728,9 +719,6 @@ struct grid_line {
u_int cellsize;
struct grid_cell *celldata;
u_int utf8size;
struct grid_utf8 *utf8data;
int flags;
} __packed;
@@ -968,13 +956,6 @@ struct window_pane {
TAILQ_HEAD(window_panes, window_pane);
RB_HEAD(window_pane_tree, window_pane);
/* Window last layout. */
struct last_layout {
char *layout;
TAILQ_ENTRY(last_layout) entry;
};
/* Window structure. */
struct window {
u_int id;
@@ -988,9 +969,6 @@ struct window {
int lastlayout;
struct layout_cell *layout_root;
TAILQ_HEAD(last_layouts, last_layout) layout_list;
u_int layout_list_size;
struct last_layout *layout_list_last;
u_int sx;
u_int sy;
@@ -1090,6 +1068,7 @@ struct session {
struct timeval creation_time;
struct timeval activity_time;
struct timeval last_activity_time;
u_int sx;
u_int sy;
@@ -1115,29 +1094,6 @@ struct session {
RB_HEAD(sessions, session);
ARRAY_DECL(sessionslist, struct session *);
/*
* Mouse input. xterm mouse mode is fairly silly. Buttons are in the bottom two
* bits: 0 = button 1; 1 = button 2; 2 = button 3; 3 = buttons released. Bits
* 3, 4 and 5 are for keys. Bit 6 is set for dragging and 7 for mouse buttons 4
* and 5.
*/
struct mouse_event {
u_int b;
#define MOUSE_1 0
#define MOUSE_2 1
#define MOUSE_3 2
#define MOUSE_UP 3
#define MOUSE_BUTTON 3
#define MOUSE_SHIFT 4
#define MOUSE_ESCAPE 8
#define MOUSE_CTRL 16
#define MOUSE_DRAG 32
#define MOUSE_45 64
#define MOUSE_RESIZE_PANE 128 /* marker for resizing */
u_int x;
u_int y;
};
/* TTY information. */
struct tty_key {
char ch;
@@ -1166,11 +1122,52 @@ struct tty_term {
};
LIST_HEAD(tty_terms, tty_term);
/* Mouse wheel states. */
#define MOUSE_WHEEL_UP 0
#define MOUSE_WHEEL_DOWN 1
/* Mouse events. */
#define MOUSE_EVENT_DOWN (1 << 0)
#define MOUSE_EVENT_DRAG (1 << 1)
#define MOUSE_EVENT_UP (1 << 2)
#define MOUSE_EVENT_CLICK (1 << 3)
#define MOUSE_EVENT_WHEEL (1 << 4)
/* Mouse flags. */
#define MOUSE_RESIZE_PANE (1 << 0)
/*
* Mouse input. When sent by xterm:
*
* - buttons are in the bottom two bits: 0 = b1; 1 = b2; 2 = b3; 3 = released
* - bits 3, 4 and 5 are for keys
* - bit 6 is set for dragging
* - bit 7 for buttons 4 and 5
*/
struct mouse_event {
u_int xb;
u_int x;
u_int lx;
u_int sx;
u_int y;
u_int ly;
u_int sy;
u_int button;
u_int clicks;
int wheel;
int event;
int flags;
};
struct tty {
struct client *client;
char *path;
u_int xterm_version;
u_int class;
u_int sx;
u_int sy;
@@ -1218,7 +1215,6 @@ struct tty_ctx {
struct window_pane *wp;
const struct grid_cell *cell;
const struct grid_utf8 *utf8;
u_int num;
void *ptr;
@@ -1239,7 +1235,6 @@ struct tty_ctx {
/* Saved last cell on line. */
struct grid_cell last_cell;
struct grid_utf8 last_utf8;
u_int last_width;
};
@@ -1326,8 +1321,6 @@ struct client {
struct session *session;
struct session *last_session;
struct mouse_event last_mouse;
int wlmouse;
int references;
@@ -1496,9 +1489,11 @@ __dead void shell_exec(const char *, const char *);
/* cfg.c */
extern int cfg_finished;
extern int cfg_references;
extern struct causelist cfg_causes;
void printflike2 cfg_add_cause(struct causelist *, const char *, ...);
int load_cfg(const char *, struct cmd_ctx *, struct causelist *);
enum cmd_retval load_cfg(const char *, struct cmd_ctx *, struct causelist *);
void show_cfg_causes(struct session *);
/* format.c */
int format_cmp(struct format_entry *, struct format_entry *);
@@ -1608,15 +1603,16 @@ void tty_putcode(struct tty *, enum tty_code_code);
void tty_putcode1(struct tty *, enum tty_code_code, int);
void tty_putcode2(struct tty *, enum tty_code_code, int, int);
void tty_putcode_ptr1(struct tty *, enum tty_code_code, const void *);
void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, const void *);
void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *,
const void *);
void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, u_char);
void tty_pututf8(struct tty *, const struct grid_utf8 *);
void tty_putn(struct tty *, const void *, size_t, u_int);
void tty_init(struct tty *, struct client *, int, char *);
int tty_resize(struct tty *);
int tty_set_size(struct tty *, u_int, u_int);
void tty_set_class(struct tty *, u_int);
void tty_start_tty(struct tty *);
void tty_set_version(struct tty *, u_int);
void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
@@ -1636,6 +1632,7 @@ void tty_cmd_clearscreen(struct tty *, const struct tty_ctx *);
void tty_cmd_clearstartofline(struct tty *, const struct tty_ctx *);
void tty_cmd_clearstartofscreen(struct tty *, const struct tty_ctx *);
void tty_cmd_deletecharacter(struct tty *, const struct tty_ctx *);
void tty_cmd_clearcharacter(struct tty *, const struct tty_ctx *);
void tty_cmd_deleteline(struct tty *, const struct tty_ctx *);
void tty_cmd_erasecharacter(struct tty *, const struct tty_ctx *);
void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *);
@@ -1659,8 +1656,8 @@ const char *tty_term_string2(
struct tty_term *, enum tty_code_code, int, int);
const char *tty_term_ptr1(
struct tty_term *, enum tty_code_code, const void *);
const char *tty_term_ptr2(
struct tty_term *, enum tty_code_code, const void *, const void *);
const char *tty_term_ptr2(struct tty_term *, enum tty_code_code,
const void *, const void *);
int tty_term_number(struct tty_term *, enum tty_code_code);
int tty_term_flag(struct tty_term *, enum tty_code_code);
@@ -1681,6 +1678,8 @@ int paste_free_index(struct paste_stack *, u_int);
void paste_add(struct paste_stack *, char *, size_t, u_int);
int paste_replace(struct paste_stack *, u_int, char *, size_t);
char *paste_print(struct paste_buffer *, size_t);
void paste_send_pane(struct paste_buffer *, struct window_pane *,
const char *, int);
/* clock.c */
extern const char clock_table[14][5][5];
@@ -1883,7 +1882,7 @@ void server_unlink_window(struct session *, struct winlink *);
void server_destroy_pane(struct window_pane *);
void server_destroy_session_group(struct session *);
void server_destroy_session(struct session *);
void server_check_unattached (void);
void server_check_unattached(void);
void server_set_identify(struct client *);
void server_clear_identify(struct client *);
void server_update_event(struct client *);
@@ -1922,7 +1921,8 @@ void input_parse(struct window_pane *);
/* input-key.c */
void input_key(struct window_pane *, int);
void input_mouse(struct window_pane *, struct mouse_event *);
void input_mouse(struct window_pane *, struct session *,
struct mouse_event *);
/* xterm-keys.c */
char *xterm_keys_lookup(int);
@@ -1950,13 +1950,9 @@ void grid_collect_history(struct grid *);
void grid_scroll_history(struct grid *);
void grid_scroll_history_region(struct grid *, u_int, u_int);
void grid_expand_line(struct grid *, u_int, u_int);
void grid_expand_line_utf8(struct grid *, u_int, u_int);
const struct grid_cell *grid_peek_cell(struct grid *, u_int, u_int);
struct grid_cell *grid_get_cell(struct grid *, u_int, u_int);
void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *);
const struct grid_utf8 *grid_peek_utf8(struct grid *, u_int, u_int);
struct grid_utf8 *grid_get_utf8(struct grid *, u_int, u_int);
void grid_set_utf8(struct grid *, u_int, u_int, const struct grid_utf8 *);
void grid_clear(struct grid *, u_int, u_int, u_int, u_int);
void grid_clear_lines(struct grid *, u_int, u_int);
void grid_move_lines(struct grid *, u_int, u_int, u_int);
@@ -1964,23 +1960,19 @@ void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int);
char *grid_string_cells(struct grid *, u_int, u_int, u_int);
void grid_duplicate_lines(
struct grid *, u_int, struct grid *, u_int, u_int);
u_int grid_reflow(struct grid *, const struct grid *, u_int);
/* grid-utf8.c */
size_t grid_utf8_size(const struct grid_utf8 *);
size_t grid_utf8_copy(const struct grid_utf8 *, char *, size_t);
void grid_utf8_set(struct grid_utf8 *, const struct utf8_data *);
int grid_utf8_append(struct grid_utf8 *, const struct utf8_data *);
int grid_utf8_compare(const struct grid_utf8 *, const struct grid_utf8 *);
/* grid-cell.c */
u_int grid_cell_width(const struct grid_cell *);
void grid_cell_get(const struct grid_cell *, struct utf8_data *);
void grid_cell_set(struct grid_cell *, const struct utf8_data *);
void grid_cell_one(struct grid_cell *, u_char);
/* grid-view.c */
const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int);
struct grid_cell *grid_view_get_cell(struct grid *, u_int, u_int);
void grid_view_set_cell(
struct grid *, u_int, u_int, const struct grid_cell *);
const struct grid_utf8 *grid_view_peek_utf8(struct grid *, u_int, u_int);
struct grid_utf8 *grid_view_get_utf8(struct grid *, u_int, u_int);
void grid_view_set_utf8(
struct grid *, u_int, u_int, const struct grid_utf8 *);
void grid_view_clear_history(struct grid *);
void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int);
void grid_view_scroll_region_up(struct grid *, u_int, u_int);
@@ -2022,6 +2014,7 @@ void screen_write_cursorleft(struct screen_write_ctx *, u_int);
void screen_write_alignmenttest(struct screen_write_ctx *);
void screen_write_insertcharacter(struct screen_write_ctx *, u_int);
void screen_write_deletecharacter(struct screen_write_ctx *, u_int);
void screen_write_clearcharacter(struct screen_write_ctx *, u_int);
void screen_write_insertline(struct screen_write_ctx *, u_int);
void screen_write_deleteline(struct screen_write_ctx *, u_int);
void screen_write_clearline(struct screen_write_ctx *);
@@ -2044,8 +2037,7 @@ void screen_write_clearendofscreen(struct screen_write_ctx *);
void screen_write_clearstartofscreen(struct screen_write_ctx *);
void screen_write_clearscreen(struct screen_write_ctx *);
void screen_write_clearhistory(struct screen_write_ctx *);
void screen_write_cell(struct screen_write_ctx *,
const struct grid_cell *, const struct utf8_data *);
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
void screen_write_bracketpaste(struct screen_write_ctx *, int);
@@ -2062,11 +2054,12 @@ void screen_reset_tabs(struct screen *);
void screen_set_cursor_style(struct screen *, u_int);
void screen_set_cursor_colour(struct screen *, const char *);
void screen_set_title(struct screen *, const char *);
void screen_resize(struct screen *, u_int, u_int);
void screen_resize(struct screen *, u_int, u_int, int);
void screen_set_selection(struct screen *,
u_int, u_int, u_int, u_int, u_int, struct grid_cell *);
void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);
void screen_reflow(struct screen *, u_int);
/* window.c */
extern struct windows windows;
@@ -2121,10 +2114,10 @@ int window_pane_spawn(struct window_pane *, const char *,
const char *, const char *, struct environ *,
struct termios *, char **);
void window_pane_resize(struct window_pane *, u_int, u_int);
void window_pane_alternate_on(
struct window_pane *, struct grid_cell *);
void window_pane_alternate_off(
struct window_pane *, struct grid_cell *);
void window_pane_alternate_on(struct window_pane *,
struct grid_cell *, int);
void window_pane_alternate_off(struct window_pane *,
struct grid_cell *, int);
int window_pane_set_mode(
struct window_pane *, const struct window_mode *);
void window_pane_reset_mode(struct window_pane *);
@@ -2149,8 +2142,7 @@ u_int layout_count_cells(struct layout_cell *);
struct layout_cell *layout_create_cell(struct layout_cell *);
void layout_free_cell(struct layout_cell *);
void layout_print_cell(struct layout_cell *, const char *, u_int);
void layout_destroy_cell(
struct layout_cell *, struct layout_cell **);
void layout_destroy_cell(struct layout_cell *, struct layout_cell **);
void layout_set_size(
struct layout_cell *, u_int, u_int, u_int, u_int);
void layout_make_leaf(
@@ -2166,15 +2158,11 @@ void layout_free(struct window *);
void layout_resize(struct window *, u_int, u_int);
void layout_resize_pane(
struct window_pane *, enum layout_type, int);
void layout_resize_pane_mouse(
struct client *c, struct mouse_event *mouse);
void layout_resize_pane_mouse(struct client *c);
void layout_assign_pane(struct layout_cell *, struct window_pane *);
struct layout_cell *layout_split_pane(
struct window_pane *, enum layout_type, int, int);
void layout_close_pane(struct window_pane *);
void layout_list_add(struct window *);
const char *layout_list_redo(struct window *);
const char *layout_list_undo(struct window *);
/* layout-custom.c */
char *layout_dump(struct window *);
@@ -2217,6 +2205,7 @@ struct window_choose_data *window_choose_add_session(struct window_pane *,
struct window_choose_data *window_choose_add_item(struct window_pane *,
struct cmd_ctx *, struct winlink *, const char *,
char *, u_int);
void window_choose_expand_all(struct window_pane *);
/* names.c */
void queue_window_name(struct window *);
+58 -26
View File
@@ -611,7 +611,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
{
struct mouse_event *m = &tty->mouse;
struct utf8_data utf8data;
u_int i, value;
u_int i, value, x, y, b;
/*
* Standard mouse sequences are \033[M followed by three characters
@@ -622,6 +622,7 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
*/
*size = 0;
x = y = b = 0;
/* First three bytes are always \033[M. */
if (buf[0] != '\033')
@@ -661,21 +662,58 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
}
if (i == 0)
m->b = value;
b = value;
else if (i == 1)
m->x = value;
x = value;
else
m->y = value;
y = value;
}
log_debug("mouse input: %.*s", (int) *size, buf);
/* Check and return the mouse input. */
if (m->b < 32 || m->x < 33 || m->y < 33)
if (b < 32 || x < 33 || y < 33)
return (-1);
m->b -= 32;
m->x -= 33;
m->y -= 33;
log_debug("mouse position: x=%u y=%u b=%u", m->x, m->y, m->b);
b -= 32;
x -= 33;
y -= 33;
log_debug("mouse position: x=%u y=%u b=%u", x, y, b);
/* Fill in mouse structure. */
if (~m->event & MOUSE_EVENT_WHEEL) {
m->lx = m->x;
m->ly = m->y;
}
m->xb = b;
if (b & 64) { /* wheel button */
b &= 3;
if (b == 0)
m->wheel = MOUSE_WHEEL_UP;
else if (b == 1)
m->wheel = MOUSE_WHEEL_DOWN;
m->event = MOUSE_EVENT_WHEEL;
} else if ((b & 3) == 3) {
if (~m->event & MOUSE_EVENT_DRAG && x == m->x && y == m->y) {
m->event = MOUSE_EVENT_CLICK;
} else
m->event = MOUSE_EVENT_DRAG;
m->event |= MOUSE_EVENT_UP;
} else {
if (b & 32) /* drag motion */
m->event = MOUSE_EVENT_DRAG;
else {
if (m->event & MOUSE_EVENT_UP && x == m->x && y == m->y)
m->clicks = (m->clicks + 1) % 3;
else
m->clicks = 0;
m->sx = x;
m->sy = y;
m->event = MOUSE_EVENT_DOWN;
}
m->button = (b & 3);
}
m->x = x;
m->y = y;
return (0);
}
@@ -686,18 +724,17 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size)
int
tty_keys_device(struct tty *tty, const char *buf, size_t len, size_t *size)
{
u_int i, a, b;
u_int i, class;
char tmp[64], *endptr;
/*
* Primary device attributes are \033[?a;b and secondary are
* \033[>a;b;c. We only request attributes on xterm, so we only care
* about the middle values which is the xterm version.
* \033[>a;b;c.
*/
*size = 0;
/* First three bytes are always \033[>. */
/* First three bytes are always \033[?. */
if (buf[0] != '\033')
return (-1);
if (len == 1)
@@ -722,22 +759,17 @@ tty_keys_device(struct tty *tty, const char *buf, size_t len, size_t *size)
tmp[i] = '\0';
*size = 4 + i;
/* Only secondary is of interest. */
if (buf[2] != '>')
/* Only primary is of interest. */
if (buf[2] != '?')
return (0);
/* Convert version numbers. */
a = strtoul(tmp, &endptr, 10);
if (*endptr == ';') {
b = strtoul(endptr + 1, &endptr, 10);
if (*endptr != '\0' && *endptr != ';')
b = 0;
} else
a = b = 0;
/* Convert service class. */
class = strtoul(tmp, &endptr, 10);
if (*endptr != ';')
class = 0;
log_debug("received xterm version %u", b);
if (b < 500)
tty_set_version(tty, b);
log_debug("received service class %u", class);
tty_set_class(tty, class);
return (0);
}
+1
View File
@@ -65,6 +65,7 @@ const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
{ TTYC_DL, TTYCODE_STRING, "dl" },
{ TTYC_DL1, TTYCODE_STRING, "dl1" },
{ TTYC_E3, TTYCODE_STRING, "E3" },
{ TTYC_ECH, TTYCODE_STRING, "ech" },
{ TTYC_EL, TTYCODE_STRING, "el" },
{ TTYC_EL1, TTYCODE_STRING, "el1" },
{ TTYC_ENACS, TTYCODE_STRING, "enacs" },
+47 -49
View File
@@ -48,8 +48,7 @@ void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
void tty_cell(struct tty *,
const struct grid_cell *, const struct grid_utf8 *);
void tty_cell(struct tty *, const struct grid_cell *);
#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -224,7 +223,7 @@ tty_start_tty(struct tty *tty)
tty_puts(tty, "\033[?1000l");
if (tty_term_has(tty->term, TTYC_XT))
tty_puts(tty, "\033[>c");
tty_puts(tty, "\033[c");
tty->cx = UINT_MAX;
tty->cy = UINT_MAX;
@@ -240,11 +239,11 @@ tty_start_tty(struct tty *tty)
}
void
tty_set_version(struct tty *tty, u_int version)
tty_set_class(struct tty *tty, u_int class)
{
if (tty->xterm_version != 0)
if (tty->class != 0)
return;
tty->xterm_version = version;
tty->class = class;
}
void
@@ -289,9 +288,6 @@ tty_stop_tty(struct tty *tty)
tty_raw(tty, "\033[?1000l");
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
if (tty->xterm_version > 270)
tty_raw(tty, "\033[61;1\"p");
}
void
@@ -419,15 +415,12 @@ tty_putc(struct tty *tty, u_char ch)
}
void
tty_pututf8(struct tty *tty, const struct grid_utf8 *gu)
tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
{
size_t size;
size = grid_utf8_size(gu);
bufferevent_write(tty->event, gu->data, size);
bufferevent_write(tty->event, buf, len);
if (tty->log_fd != -1)
write(tty->log_fd, gu->data, size);
tty->cx += gu->width;
write(tty->log_fd, buf, len);
tty->cx += width;
}
void
@@ -585,7 +578,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
const struct grid_cell *gc;
struct grid_line *gl;
struct grid_cell tmpgc;
const struct grid_utf8 *gu;
struct utf8_data ud;
u_int i, sx;
tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s);
@@ -610,21 +603,17 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
gu = NULL;
if (gc->flags & GRID_FLAG_UTF8)
gu = grid_view_peek_utf8(s->grid, i, py);
if (screen_check_selection(s, i, py)) {
memcpy(&tmpgc, &s->sel.cell, sizeof tmpgc);
tmpgc.data = gc->data;
grid_cell_get(gc, &ud);
grid_cell_set(&tmpgc, &ud);
tmpgc.flags = gc->flags &
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
tty_cell(tty, &tmpgc, gu);
tty_cell(tty, &tmpgc);
} else
tty_cell(tty, gc, gu);
tty_cell(tty, gc);
}
if (sx >= tty->sx) {
@@ -721,6 +710,23 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num);
}
void
tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
tty_reset(tty);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
if (tty_term_has(tty->term, TTYC_ECH))
tty_putcode1(tty, TTYC_ECH, ctx->num);
else {
for (i = 0; i < ctx->num; i++)
tty_putc(tty, ' ');
}
}
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
@@ -970,17 +976,11 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int cx;
u_int width;
const struct grid_cell *gc = ctx->cell;
const struct grid_utf8 *gu = ctx->utf8;
if (gc->flags & GRID_FLAG_UTF8)
width = gu->width;
else
width = 1;
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
/* Is the cursor in the very last position? */
width = grid_cell_width(ctx->cell);
if (ctx->ocx > wp->sx - width) {
if (ctx->xoff != 0 || wp->sx != tty->sx) {
/*
@@ -997,17 +997,14 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
* move as far left as possible and redraw the last
* cell to move into the last position.
*/
if (ctx->last_cell.flags & GRID_FLAG_UTF8)
cx = screen_size_x(s) - ctx->last_utf8.width;
else
cx = screen_size_x(s) - 1;
cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
tty_cell(tty, &ctx->last_cell, &ctx->last_utf8);
tty_cell(tty, &ctx->last_cell);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_cell(tty, ctx->cell, ctx->utf8);
tty_cell(tty, ctx->cell);
}
void
@@ -1057,10 +1054,10 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
}
void
tty_cell(
struct tty *tty, const struct grid_cell *gc, const struct grid_utf8 *gu)
tty_cell(struct tty *tty, const struct grid_cell *gc)
{
u_int i;
struct utf8_data ud;
u_int i;
/* Skip last character if terminal is stupid. */
if (tty->term->flags & TERM_EARLYWRAP &&
@@ -1074,23 +1071,24 @@ tty_cell(
/* Set the attributes. */
tty_attributes(tty, gc);
/* If not UTF-8, write directly. */
if (!(gc->flags & GRID_FLAG_UTF8)) {
if (gc->data < 0x20 || gc->data == 0x7f)
/* Get the cell and if ASCII write with putc to do ACS translation. */
grid_cell_get(gc, &ud);
if (ud.size == 1) {
if (*ud.data < 0x20 || *ud.data == 0x7f)
return;
tty_putc(tty, gc->data);
tty_putc(tty, *ud.data);
return;
}
/* If the terminal doesn't support UTF-8, write underscores. */
/* If not UTF-8, write _. */
if (!(tty->flags & TTY_UTF8)) {
for (i = 0; i < gu->width; i++)
for (i = 0; i < ud.width; i++)
tty_putc(tty, '_');
return;
}
/* Otherwise, write UTF-8. */
tty_pututf8(tty, gu);
/* Write the data. */
tty_putn(tty, ud.data, ud.size, ud.width);
}
void
+2 -4
View File
@@ -43,7 +43,6 @@ void window_choose_scroll_down(struct window_pane *);
void window_choose_collapse(struct window_pane *, struct session *);
void window_choose_expand(struct window_pane *, struct session *, u_int);
void window_choose_collapse_all(struct window_pane *);
void window_choose_expand_all(struct window_pane *);
enum window_choose_input_type {
WINDOW_CHOOSE_NORMAL = -1,
@@ -118,7 +117,6 @@ window_choose_ready(struct window_pane *wp, u_int cur,
ARRAY_CONCAT(&data->old_list, &data->list);
window_choose_collapse_all(wp);
window_choose_redraw_screen(wp);
}
struct screen *
@@ -205,7 +203,7 @@ window_choose_resize(struct window_pane *wp, u_int sx, u_int sy)
if (data->selected > sy - 1)
data->top = data->selected - (sy - 1);
screen_resize(s, sx, sy);
screen_resize(s, sx, sy, 0);
window_choose_redraw_screen(wp);
}
@@ -623,7 +621,7 @@ window_choose_mouse(
struct window_choose_mode_item *item;
u_int idx;
if ((m->b & 3) == 3)
if (~m->event & MOUSE_EVENT_CLICK)
return;
if (m->x >= screen_size_x(s))
return;
+1 -1
View File
@@ -79,7 +79,7 @@ window_clock_resize(struct window_pane *wp, u_int sx, u_int sy)
struct window_clock_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
screen_resize(s, sx, sy);
screen_resize(s, sx, sy, 0);
window_clock_draw_screen(wp);
}
+47 -54
View File
@@ -335,9 +335,9 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
screen_resize(s, sx, sy);
screen_resize(s, sx, sy, 0);
if (data->backing != &wp->base)
screen_resize(data->backing, sx, sy);
screen_resize(data->backing, sx, sy, 0);
if (data->cy > sy - 1)
data->cy = sy - 1;
@@ -829,13 +829,13 @@ window_copy_mouse(
return;
/* If mouse wheel (buttons 4 and 5), scroll. */
if ((m->b & MOUSE_45)) {
if ((m->b & MOUSE_BUTTON) == MOUSE_1) {
if (m->event == MOUSE_EVENT_WHEEL) {
if (m->wheel == MOUSE_WHEEL_UP) {
for (i = 0; i < 5; i++)
window_copy_cursor_up(wp, 0);
} else if ((m->b & MOUSE_BUTTON) == MOUSE_2) {
window_copy_cursor_up(wp, 1);
} else if (m->wheel == MOUSE_WHEEL_DOWN) {
for (i = 0; i < 5; i++)
window_copy_cursor_down(wp, 0);
window_copy_cursor_down(wp, 1);
if (data->oy == 0)
goto reset_mode;
}
@@ -847,7 +847,7 @@ window_copy_mouse(
* pressed, or stop the selection on their release.
*/
if (s->mode & MODE_MOUSE_BUTTON) {
if ((m->b & MOUSE_BUTTON) != MOUSE_UP) {
if (~m->event & MOUSE_EVENT_UP) {
window_copy_update_cursor(wp, m->x, m->y);
if (window_copy_update_selection(wp))
window_copy_redraw_screen(wp);
@@ -857,7 +857,7 @@ window_copy_mouse(
}
/* Otherwise if other buttons pressed, start selection and motion. */
if ((m->b & MOUSE_BUTTON) != MOUSE_UP) {
if (~m->event & MOUSE_EVENT_UP) {
s->mode &= ~MODE_MOUSE_STANDARD;
s->mode |= MODE_MOUSE_BUTTON;
@@ -908,24 +908,16 @@ window_copy_search_compare(
struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx)
{
const struct grid_cell *gc, *sgc;
const struct grid_utf8 *gu, *sgu;
struct utf8_data ud, sud;
gc = grid_peek_cell(gd, px, py);
grid_cell_get(gc, &ud);
sgc = grid_peek_cell(sgd, spx, 0);
grid_cell_get(sgc, &sud);
if ((gc->flags & GRID_FLAG_UTF8) != (sgc->flags & GRID_FLAG_UTF8))
if (ud.size != sud.size || ud.width != sud.width)
return (0);
if (gc->flags & GRID_FLAG_UTF8) {
gu = grid_peek_utf8(gd, px, py);
sgu = grid_peek_utf8(sgd, spx, 0);
if (grid_utf8_compare(gu, sgu))
return (1);
} else {
if (gc->data == sgc->data)
return (1);
}
return (0);
return (memcmp(ud.data, sud.data, ud.size) == 0);
}
int
@@ -1395,10 +1387,9 @@ window_copy_copy_line(struct window_pane *wp,
struct window_copy_mode_data *data = wp->modedata;
struct grid *gd = data->backing->grid;
const struct grid_cell *gc;
const struct grid_utf8 *gu;
struct grid_line *gl;
struct utf8_data ud;
u_int i, xx, wrapped = 0;
size_t size;
if (sx > ex)
return;
@@ -1426,15 +1417,11 @@ window_copy_copy_line(struct window_pane *wp,
gc = grid_peek_cell(gd, i, sy);
if (gc->flags & GRID_FLAG_PADDING)
continue;
if (!(gc->flags & GRID_FLAG_UTF8)) {
*buf = xrealloc(*buf, 1, (*off) + 1);
(*buf)[(*off)++] = gc->data;
} else {
gu = grid_peek_utf8(gd, i, sy);
size = grid_utf8_size(gu);
*buf = xrealloc(*buf, 1, (*off) + size);
*off += grid_utf8_copy(gu, *buf + *off, size);
}
grid_cell_get(gc, &ud);
*buf = xrealloc(*buf, 1, (*off) + ud.size);
memcpy(*buf + *off, ud.data, ud.size);
*off += ud.size;
}
}
@@ -1464,13 +1451,15 @@ window_copy_in_set(struct window_pane *wp, u_int px, u_int py, const char *set)
{
struct window_copy_mode_data *data = wp->modedata;
const struct grid_cell *gc;
struct utf8_data ud;
gc = grid_peek_cell(data->backing->grid, px, py);
if (gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8))
grid_cell_get(gc, &ud);
if (ud.size != 1 || gc->flags & GRID_FLAG_PADDING)
return (0);
if (gc->data == 0x00 || gc->data == 0x7f)
if (*ud.data == 0x00 || *ud.data == 0x7f)
return (0);
return (strchr(set, gc->data) != NULL);
return (strchr(set, *ud.data) != NULL);
}
u_int
@@ -1479,6 +1468,7 @@ window_copy_find_length(struct window_pane *wp, u_int py)
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = data->backing;
const struct grid_cell *gc;
struct utf8_data ud;
u_int px;
/*
@@ -1492,9 +1482,8 @@ window_copy_find_length(struct window_pane *wp, u_int py)
px = screen_size_x(s);
while (px > 0) {
gc = grid_peek_cell(s->grid, px - 1, py);
if (gc->flags & GRID_FLAG_UTF8)
break;
if (gc->data != ' ')
grid_cell_get(gc, &ud);
if (ud.size != 1 || *ud.data != ' ')
break;
px--;
}
@@ -1527,6 +1516,7 @@ window_copy_cursor_back_to_indentation(struct window_pane *wp)
struct window_copy_mode_data *data = wp->modedata;
u_int px, py, xx;
const struct grid_cell *gc;
struct utf8_data ud;
px = 0;
py = screen_hsize(data->backing) + data->cy - data->oy;
@@ -1534,9 +1524,8 @@ window_copy_cursor_back_to_indentation(struct window_pane *wp)
while (px < xx) {
gc = grid_peek_cell(data->backing->grid, px, py);
if (gc->flags & GRID_FLAG_UTF8)
break;
if (gc->data != ' ')
grid_cell_get(gc, &ud);
if (ud.size != 1 || *ud.data != ' ')
break;
px++;
}
@@ -1696,6 +1685,7 @@ window_copy_cursor_jump(struct window_pane *wp)
struct window_copy_mode_data *data = wp->modedata;
struct screen *back_s = data->backing;
const struct grid_cell *gc;
struct utf8_data ud;
u_int px, py, xx;
px = data->cx + 1;
@@ -1704,9 +1694,9 @@ window_copy_cursor_jump(struct window_pane *wp)
while (px < xx) {
gc = grid_peek_cell(back_s->grid, px, py);
if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
&& gc->data == data->jumpchar) {
grid_cell_get(gc, &ud);
if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp))
window_copy_redraw_lines(wp, data->cy, 1);
@@ -1722,6 +1712,7 @@ window_copy_cursor_jump_back(struct window_pane *wp)
struct window_copy_mode_data *data = wp->modedata;
struct screen *back_s = data->backing;
const struct grid_cell *gc;
struct utf8_data ud;
u_int px, py;
px = data->cx;
@@ -1732,9 +1723,9 @@ window_copy_cursor_jump_back(struct window_pane *wp)
for (;;) {
gc = grid_peek_cell(back_s->grid, px, py);
if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
&& gc->data == data->jumpchar) {
grid_cell_get(gc, &ud);
if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px, data->cy);
if (window_copy_update_selection(wp))
window_copy_redraw_lines(wp, data->cy, 1);
@@ -1752,6 +1743,7 @@ window_copy_cursor_jump_to(struct window_pane *wp)
struct window_copy_mode_data *data = wp->modedata;
struct screen *back_s = data->backing;
const struct grid_cell *gc;
struct utf8_data ud;
u_int px, py, xx;
px = data->cx + 1;
@@ -1760,9 +1752,9 @@ window_copy_cursor_jump_to(struct window_pane *wp)
while (px < xx) {
gc = grid_peek_cell(back_s->grid, px, py);
if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
&& gc->data == data->jumpchar) {
grid_cell_get(gc, &ud);
if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px - 1, data->cy);
if (window_copy_update_selection(wp))
window_copy_redraw_lines(wp, data->cy, 1);
@@ -1778,6 +1770,7 @@ window_copy_cursor_jump_to_back(struct window_pane *wp)
struct window_copy_mode_data *data = wp->modedata;
struct screen *back_s = data->backing;
const struct grid_cell *gc;
struct utf8_data ud;
u_int px, py;
px = data->cx;
@@ -1788,9 +1781,9 @@ window_copy_cursor_jump_to_back(struct window_pane *wp)
for (;;) {
gc = grid_peek_cell(back_s->grid, px, py);
if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
&& gc->data == data->jumpchar) {
grid_cell_get(gc, &ud);
if (!(gc->flags & GRID_FLAG_PADDING) &&
ud.size == 1 && *ud.data == data->jumpchar) {
window_copy_update_cursor(wp, px + 1, data->cy);
if (window_copy_update_selection(wp))
window_copy_redraw_lines(wp, data->cy, 1);
+18 -13
View File
@@ -283,7 +283,6 @@ window_create1(u_int sx, u_int sy)
w->lastlayout = -1;
w->layout_root = NULL;
TAILQ_INIT(&w->layout_list);
w->sx = sx;
w->sy = sy;
@@ -855,7 +854,7 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
ws.ws_col = sx;
ws.ws_row = sy;
screen_resize(&wp->base, sx, sy);
screen_resize(&wp->base, sx, sy, wp->saved_grid == NULL);
if (wp->mode != NULL)
wp->mode->resize(wp, sx, sy);
@@ -877,7 +876,8 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
* history is not updated
*/
void
window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc)
window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc,
int cursor)
{
struct screen *s = &wp->base;
u_int sx, sy;
@@ -891,8 +891,10 @@ window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc)
wp->saved_grid = grid_create(sx, sy, 0);
grid_duplicate_lines(wp->saved_grid, 0, s->grid, screen_hsize(s), sy);
wp->saved_cx = s->cx;
wp->saved_cy = s->cy;
if (cursor) {
wp->saved_cx = s->cx;
wp->saved_cy = s->cy;
}
memcpy(&wp->saved_cell, gc, sizeof wp->saved_cell);
grid_view_clear(s->grid, 0, 0, sx, sy);
@@ -904,7 +906,8 @@ window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc)
/* Exit alternate screen mode and restore the copied grid. */
void
window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc)
window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc,
int cursor)
{
struct screen *s = &wp->base;
u_int sx, sy;
@@ -921,14 +924,16 @@ window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc)
* before copying back.
*/
if (sy > wp->saved_grid->sy)
screen_resize(s, sx, wp->saved_grid->sy);
screen_resize(s, sx, wp->saved_grid->sy, 1);
/* Restore the grid, cursor position and cell. */
grid_duplicate_lines(s->grid, screen_hsize(s), wp->saved_grid, 0, sy);
s->cx = wp->saved_cx;
if (cursor)
s->cx = wp->saved_cx;
if (s->cx > screen_size_x(s) - 1)
s->cx = screen_size_x(s) - 1;
s->cy = wp->saved_cy;
if (cursor)
s->cy = wp->saved_cy;
if (s->cy > screen_size_y(s) - 1)
s->cy = screen_size_y(s) - 1;
memcpy(gc, &wp->saved_cell, sizeof *gc);
@@ -938,8 +943,8 @@ window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc)
* the current size.
*/
wp->base.grid->flags |= GRID_HISTORY;
if (sy > wp->saved_grid->sy)
screen_resize(s, sx, sy);
if (sy > wp->saved_grid->sy || sx != wp->saved_grid->sx)
screen_resize(s, sx, sy, 1);
grid_destroy(wp->saved_grid);
wp->saved_grid = NULL;
@@ -1021,7 +1026,7 @@ window_pane_mouse(
options_get_number(&wp->window->options, "mode-mouse"))
wp->mode->mouse(wp, sess, m);
} else if (wp->fd != -1)
input_mouse(wp, m);
input_mouse(wp, sess, m);
}
int
@@ -1203,7 +1208,7 @@ winlink_clear_flags(struct winlink *wl)
void
window_mode_attrs(struct grid_cell *gc, struct options *oo)
{
memcpy(gc, &grid_default_cell, sizeof gc);
memcpy(gc, &grid_default_cell, sizeof *gc);
colour_set_fg(gc, options_get_number(oo, "mode-fg"));
colour_set_bg(gc, options_get_number(oo, "mode-bg"));
gc->attr |= options_get_number(oo, "mode-attr");
+9 -5
View File
@@ -12,14 +12,14 @@
<p id="upper-left-title">tmux</p>
<ul id="left-menu">
<li><a href="http://downloads.sourceforge.net/tmux/tmux-%%VERSION%%.tar.gz">Download</a></li>
<li><a href="http://tmux.git.sourceforge.net/git/gitweb.cgi?p=tmux/tmux;a=blob;f=NOTES">Release Notes</a></li>
<li><a href="https://sourceforge.net/p/tmux/tmux-code/ci/master/tree/NOTES">Release Notes</a></li>
<li><a href="http://www.openbsd.org/cgi-bin/man.cgi?query=tmux&sektion=1">Manual Page</a></li>
<li><a href="http://tmux.git.sourceforge.net/git/gitweb.cgi?p=tmux/tmux;a=blob;f=FAQ">FAQ</a></li>
<li><a href="https://sourceforge.net/p/tmux/tmux-code/ci/master/tree/FAQ">FAQ</a></li>
<li><a href="http://www.openbsd.org/faq/faq7.html#tmux">tmux in the OpenBSD FAQ</a></li>
<li><a href="http://tmux.git.sourceforge.net/git/gitweb.cgi?p=tmux/tmux;a=tree;f=examples">Examples</a></li>
<li><a href="https://sourceforge.net/p/tmux/tmux-code/ci/master/tree/examples/">Examples</a></li>
<li>&nbsp;</li>
<li class="menu-headings">Source Code</li>
<li><a href="http://tmux.git.sourceforge.net/git/gitweb.cgi?p=tmux/tmux;a=tree">SourceForge</a></li>
<li><a href="https://sourceforge.net/p/tmux/tmux-code/ci/master/tree/">SourceForge</a></li>
<li><a href="http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/tmux/">OpenBSD</a></li>
<li>&nbsp;</li>
<li class="menu-headings">Support</li>
@@ -36,7 +36,11 @@ windows), each running a separate program, to be created, accessed, and
controlled from a single screen. tmux may be detached from a screen and
continue running in the background, then later reattached.</p>
<p>The latest version is <a href="http://downloads.sourceforge.net/tmux/tmux-%%VERSION%%.tar.gz">tmux %%VERSION%%</a>.</p>
<p>The
<a href="http://downloads.sourceforge.net/tmux/tmux-%%VERSION%%.tar.gz">
latest release is tmux %%VERSION%%</a> or
<a href="https://sourceforge.net/p/tmux/tmux-code/ci/master/tree/">
get the development version from git.</a></p>
<p>tmux uses a client-server model. The server holds multiple sessions and each
window is an independent entity which may be freely linked to multiple sessions,