Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
418ba99078 | ||
|
|
648ce2f56a | ||
|
|
0648c58716 | ||
|
|
01da28efb1 | ||
|
|
6d6e1581b5 | ||
|
|
64da762c15 | ||
|
|
8903c1f167 | ||
|
|
a5521597b0 | ||
|
|
fe00607816 | ||
|
|
6e6d756109 | ||
|
|
85531fd404 | ||
|
|
c4c98df4f2 | ||
|
|
a3f4eb7b24 | ||
|
|
fdbfc7e349 | ||
|
|
c2e2107063 | ||
|
|
2ca8b7f359 | ||
|
|
3a09e01a8e | ||
|
|
d31315884c | ||
|
|
57ca428975 | ||
|
|
b0e2ef1a7d | ||
|
|
b237d9dd95 | ||
|
|
de194016ec | ||
|
|
e33ba57c13 | ||
|
|
44f8e1caff | ||
|
|
bc2e4a36df | ||
|
|
675c6b3773 | ||
|
|
f4472c16b2 | ||
|
|
854e8ae04d | ||
|
|
3e6d45acf6 | ||
|
|
a2c8af97e9 | ||
|
|
b18ff67646 | ||
|
|
6a5adfc0ba | ||
|
|
9714880283 | ||
|
|
3a0016a78a | ||
|
|
fb83914bd7 | ||
|
|
d5de489dc4 | ||
|
|
3fa4f691e3 | ||
|
|
8600fe054b | ||
|
|
8378be03d1 | ||
|
|
51a1dbfe09 | ||
|
|
8264e92b37 | ||
|
|
739a76634c | ||
|
|
47c097cb51 | ||
|
|
24d7d073ff | ||
|
|
39631edb98 | ||
|
|
9b8998aeec | ||
|
|
4aa4e9fb26 | ||
|
|
1fcc7f50ac | ||
|
|
6ef4f8e16c | ||
|
|
93224260ae | ||
|
|
991bfcf443 | ||
|
|
d762ced298 | ||
|
|
1bc910a963 | ||
|
|
63f451965c | ||
|
|
260419f48e | ||
|
|
c04aa90207 | ||
|
|
0679eb6a6d | ||
|
|
9a7e5bd1d3 | ||
|
|
827b311c81 | ||
|
|
e4679172e3 | ||
|
|
be10e8eee6 | ||
|
|
cb4553bd06 | ||
|
|
c68efec6c0 | ||
|
|
a75801320d | ||
|
|
241a746f32 | ||
|
|
47fbf87185 | ||
|
|
d210d99cce | ||
|
|
31f93d8445 | ||
|
|
2a609b332f | ||
|
|
18236c1c1b | ||
|
|
596e9d8068 | ||
|
|
589b4b8c6a | ||
|
|
60808bbded | ||
|
|
d4dc52ec84 | ||
|
|
c695c0c085 | ||
|
|
a91c598971 | ||
|
|
bf45619441 | ||
|
|
9b2aabb752 | ||
|
|
c0fb5edff9 | ||
|
|
5cdc9591d3 |
@@ -1,5 +1,10 @@
|
||||
*.o
|
||||
*~
|
||||
*.diff
|
||||
*.patch
|
||||
*.core
|
||||
core
|
||||
tags
|
||||
.deps/
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
|
||||
@@ -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
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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> </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> </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,
|
||||
|
||||
Reference in New Issue
Block a user