aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CONTRIBUTING.md9
-rw-r--r--.github/ISSUE_TEMPLATE.md3
-rw-r--r--.github/README.md5
-rw-r--r--CHANGES4
-rw-r--r--arguments.c2
-rw-r--r--cmd-attach-session.c27
-rw-r--r--cmd-display-message.c3
-rw-r--r--cmd-new-session.c7
-rw-r--r--cmd-parse.y41
-rw-r--r--configure.ac2
-rw-r--r--input.c1
-rw-r--r--mode-tree.c2
-rw-r--r--options.c3
-rw-r--r--regress/command-order.sh6
-rw-r--r--regress/conf/21867280ff7e99631046f9cc669b80d2.conf8
-rw-r--r--regress/xenl-terminal.sh29
-rw-r--r--tmux.122
-rw-r--r--tmux.h2
-rw-r--r--tty-term.c2
-rw-r--r--tty.c11
-rw-r--r--window-buffer.c2
-rw-r--r--window.c2
22 files changed, 156 insertions, 37 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 49e2b90b..3a589484 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -2,13 +2,20 @@
Before opening an issue, please ensure that:
+- Your problem is a specific problem or question or suggestion, not a general
+ complaint.
+
- `$TERM` inside tmux is screen, screen-256color, tmux or tmux-256color. Check
by running `echo $TERM` inside tmux.
- You can reproduce the problem with the latest tmux release, or a build from
Git master.
-- Your question or issue is not covered in the manual (run man tmux).
+- Your question or issue is not covered [in the
+ manual](https://man.openbsd.org/tmux.1) (run `man tmux`).
+
+- Your problem is not mentioned in the [CHANGES
+ file](https://raw.githubusercontent.com/tmux/tmux/master/CHANGES) file.
- Nobody else has opened the same issue recently.
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index ee457237..8bf1e66a 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -3,6 +3,9 @@
Please read https://github.com/tmux/tmux/blob/master/.github/CONTRIBUTING.md
before opening an issue.
+If you have upgraded, make sure your issue is not covered in the CHANGES file
+for your version: https://raw.githubusercontent.com/tmux/tmux/master/CHANGES
+
Describe the problem and the steps to reproduce. Add a minimal tmux config if
necessary. Screenshots can be helpful, but no more than one or two.
diff --git a/.github/README.md b/.github/README.md
index 6e262ef5..cfff69da 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -50,15 +50,14 @@ welcome. Please send by email to:
tmux-users@googlegroups.com
-Or open a GitHub issue or pull request.
+Or open a GitHub issue or pull request. **Please read [this
+document](CONTRIBUTING.md) before opening an issue.**
There is [a TODO list](https://github.com/tmux/tmux/wiki/Contributing) which
explains some ideas for tmux not yet developed. Please feel free to ask for
clarifications on the mailing list if you're thinking of working on these or
need further information.
-Please read the CONTRIBUTING file before opening an issue.
-
## Documentation
For documentation on using tmux, see the tmux.1 manpage. View it from the
diff --git a/CHANGES b/CHANGES
index 3faf716f..edd4751b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+CHANGES FROM 3.0 to X.X
+
+XXX
+
CHANGES FROM 2.9 to 3.0
* INCOMPATIBLE: Add a new {} syntax to the configuration file. This is a string
diff --git a/arguments.c b/arguments.c
index 38e50829..c8a6ab45 100644
--- a/arguments.c
+++ b/arguments.c
@@ -217,7 +217,7 @@ args_escape(const char *s)
return (escaped);
}
- flags = VIS_OCTAL|VIS_TAB|VIS_NL;
+ flags = VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL;
if (s[strcspn(s, quoted)] != '\0')
flags |= VIS_DQ;
utf8_stravis(&escaped, s, flags);
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index bcd6d895..6de734e5 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -37,8 +37,8 @@ const struct cmd_entry cmd_attach_session_entry = {
.name = "attach-session",
.alias = "attach",
- .args = { "c:dErt:", 0, 0 },
- .usage = "[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
+ .args = { "c:dErt:x", 0, 0 },
+ .usage = "[-dErx] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
/* -t is special */
@@ -48,7 +48,7 @@ const struct cmd_entry cmd_attach_session_entry = {
enum cmd_retval
cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
- int rflag, const char *cflag, int Eflag)
+ int xflag, int rflag, const char *cflag, int Eflag)
{
struct cmd_find_state *current = &item->shared->current;
enum cmd_find_type type;
@@ -58,6 +58,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
struct winlink *wl;
struct window_pane *wp;
char *cause;
+ enum msgtype msgtype;
if (RB_EMPTY(&sessions)) {
cmdq_error(item, "no sessions");
@@ -102,11 +103,15 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
c->last_session = c->session;
if (c->session != NULL) {
- if (dflag) {
+ if (dflag || xflag) {
+ if (xflag)
+ msgtype = MSG_DETACHKILL;
+ else
+ msgtype = MSG_DETACH;
TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue;
- server_client_detach(c_loop, MSG_DETACH);
+ server_client_detach(c_loop, msgtype);
}
}
if (!Eflag)
@@ -131,11 +136,15 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
if (rflag)
c->flags |= CLIENT_READONLY;
- if (dflag) {
+ if (dflag || xflag) {
+ if (xflag)
+ msgtype = MSG_DETACHKILL;
+ else
+ msgtype = MSG_DETACH;
TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue;
- server_client_detach(c_loop, MSG_DETACH);
+ server_client_detach(c_loop, msgtype);
}
}
if (!Eflag)
@@ -169,6 +178,6 @@ cmd_attach_session_exec(struct cmd *self, struct cmdq_item *item)
struct args *args = self->args;
return (cmd_attach_session(item, args_get(args, 't'),
- args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c'),
- args_has(args, 'E')));
+ args_has(args, 'd'), args_has(args, 'x'), args_has(args, 'r'),
+ args_get(args, 'c'), args_has(args, 'E')));
}
diff --git a/cmd-display-message.c b/cmd-display-message.c
index 8c1ad5f6..4d9bccb6 100644
--- a/cmd-display-message.c
+++ b/cmd-display-message.c
@@ -109,8 +109,7 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
format_defaults(ft, target_c, s, wl, wp);
if (args_has(args, 'a')) {
- if (item != NULL)
- format_each(ft, cmd_display_message_each, item);
+ format_each(ft, cmd_display_message_each, item);
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-new-session.c b/cmd-new-session.c
index 559c268c..e0540815 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -39,8 +39,8 @@ const struct cmd_entry cmd_new_session_entry = {
.name = "new-session",
.alias = "new",
- .args = { "Ac:dDEF:n:Ps:t:x:y:", 0, -1 },
- .usage = "[-AdDEP] [-c start-directory] [-F format] [-n window-name] "
+ .args = { "Ac:dDEF:n:Ps:t:x:Xy:", 0, -1 },
+ .usage = "[-AdDEPX] [-c start-directory] [-F format] [-n window-name] "
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
"[-y height] [command]",
@@ -105,7 +105,8 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'A')) {
retval = cmd_attach_session(item,
newname, args_has(args, 'D'),
- 0, NULL, args_has(args, 'E'));
+ args_has(args, 'X'), 0, NULL,
+ args_has(args, 'E'));
free(newname);
return (retval);
}
diff --git a/cmd-parse.y b/cmd-parse.y
index 6feeb35a..e27cdcd8 100644
--- a/cmd-parse.y
+++ b/cmd-parse.y
@@ -1110,17 +1110,54 @@ error:
static int
yylex_token_escape(char **buf, size_t *len)
{
- int ch, type;
+ int ch, type, o2, o3;
u_int size, i, tmp;
char s[9];
struct utf8_data ud;
- switch (ch = yylex_getc()) {
+ ch = yylex_getc();
+
+ if (ch >= '4' && ch <= '7') {
+ yyerror("invalid octal escape");
+ return (0);
+ }
+ if (ch >= '0' && ch <= '3') {
+ o2 = yylex_getc();
+ if (o2 >= '0' && o2 <= '7') {
+ o3 = yylex_getc();
+ if (o3 >= '0' && o3 <= '7') {
+ ch = 64 * (ch - '0') +
+ 8 * (o2 - '0') +
+ (o3 - '0');
+ yylex_append1(buf, len, ch);
+ return (1);
+ }
+ }
+ yyerror("invalid octal escape");
+ return (0);
+ }
+
+ switch (ch) {
case EOF:
return (0);
+ case 'a':
+ ch = '\a';
+ break;
+ case 'b':
+ ch = '\b';
+ break;
case 'e':
ch = '\033';
break;
+ case 'f':
+ ch = '\f';
+ break;
+ case 's':
+ ch = ' ';
+ break;
+ case 'v':
+ ch = '\v';
+ break;
case 'r':
ch = '\r';
break;
diff --git a/configure.ac b/configure.ac
index 8ff6d16e..5fba1eaf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
# configure.ac
-AC_INIT([tmux], 3.0-rc2)
+AC_INIT([tmux], next-3.1)
AC_PREREQ([2.60])
AC_CONFIG_AUX_DIR(etc)
diff --git a/input.c b/input.c
index 4095c05d..e54b5ac0 100644
--- a/input.c
+++ b/input.c
@@ -2409,7 +2409,6 @@ input_osc_52(struct input_ctx *ictx, const char *p)
outlen = 4 * ((len + 2) / 3) + 1;
out = xmalloc(outlen);
if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) {
- abort();
free(out);
return;
}
diff --git a/mode-tree.c b/mode-tree.c
index 75034675..20ac3226 100644
--- a/mode-tree.c
+++ b/mode-tree.c
@@ -480,7 +480,7 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
saved = mode_tree_find_item(&mtd->saved, tag);
if (saved != NULL) {
- if (parent == NULL || (parent != NULL && parent->expanded))
+ if (parent == NULL || parent->expanded)
mti->tagged = saved->tagged;
mti->expanded = saved->expanded;
} else if (expanded == -1)
diff --git a/options.c b/options.c
index 7d79cf30..7e12544d 100644
--- a/options.c
+++ b/options.c
@@ -365,7 +365,8 @@ options_array_set(struct options_entry *o, u_int idx, const char *value,
pr = cmd_parse_from_string(value, NULL);
switch (pr->status) {
case CMD_PARSE_EMPTY:
- *cause = xstrdup("empty command");
+ if (cause != NULL)
+ *cause = xstrdup("empty command");
return (-1);
case CMD_PARSE_ERROR:
if (cause != NULL)
diff --git a/regress/command-order.sh b/regress/command-order.sh
index fb4e0324..04046f0d 100644
--- a/regress/command-order.sh
+++ b/regress/command-order.sh
@@ -1,7 +1,5 @@
#!/bin/sh
-# new-session without clients should be the right size
-
PATH=/bin:/usr/bin
TERM=screen
@@ -19,6 +17,7 @@ EOF
$TMUX -f$TMP start </dev/null || exit 1
sleep 1
$TMUX lsw -aF '#{session_name},#{window_name}'|sort >$TMP || exit 1
+$TMUX kill-server 2>/dev/null
cat <<EOF|cmp -s $TMP - || exit 1
bar,bar0
bar,bar1
@@ -27,7 +26,6 @@ foo,foo0
foo,foo1
foo,foo2
EOF
-$TMUX kill-server 2>/dev/null
cat <<EOF >$TMP
new -sfoo -nfoo0
@@ -40,6 +38,7 @@ EOF
$TMUX -f$TMP start </dev/null || exit 1
sleep 1
$TMUX lsw -aF '#{session_name},#{window_name}'|sort >$TMP || exit 1
+$TMUX kill-server 2>/dev/null
cat <<EOF|cmp -s $TMP - || exit 1
bar,bar0
bar,bar1
@@ -48,6 +47,5 @@ foo,foo0
foo,foo1
foo,foo2
EOF
-$TMUX kill-server 2>/dev/null
exit 0
diff --git a/regress/conf/21867280ff7e99631046f9cc669b80d2.conf b/regress/conf/21867280ff7e99631046f9cc669b80d2.conf
new file mode 100644
index 00000000..43b142b4
--- /dev/null
+++ b/regress/conf/21867280ff7e99631046f9cc669b80d2.conf
@@ -0,0 +1,8 @@
+%if #{l:1}
+set -g status-style fg=cyan,bg='#001040'
+%elif #{l:1}
+set -g status-style fg=white,bg='#400040'
+%else
+set -g status-style fg=white,bg='#800000'
+%endif
+bind ^X last-window
diff --git a/regress/xenl-terminal.sh b/regress/xenl-terminal.sh
new file mode 100644
index 00000000..07469ceb
--- /dev/null
+++ b/regress/xenl-terminal.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+PATH=/bin:/usr/bin
+TERM=screen
+
+[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
+TMUX="$TEST_TMUX -Ltest"
+$TMUX kill-server 2>/dev/null
+TMUX2="$TEST_TMUX -Ltest2"
+$TMUX2 kill-server 2>/dev/null
+
+TMP=$(mktemp)
+trap "rm -f $TMP" 0 1 15
+
+$TMUX2 -f/dev/null new -d || exit 1
+$TMUX2 set -as terminal-overrides ',*:xenl@' || exit 1
+$TMUX2 set -g status-right 'RRR' || exit 1
+$TMUX2 set -g status-left 'LLL' || exit 1
+$TMUX2 set -g window-status-current-format 'WWW' || exit 1
+$TMUX -f/dev/null new -x20 -y2 -d "$TMUX2 attach" || exit 1
+sleep 1
+$TMUX capturep -p|tail -1 >$TMP || exit 1
+$TMUX kill-server 2>/dev/null
+$TMUX2 kill-server 2>/dev/null
+cat <<EOF|cmp -s $TMP - || exit 1
+LLLWWW RR
+EOF
+
+exit 0
diff --git a/tmux.1 b/tmux.1
index 263aecbc..0138c5bd 100644
--- a/tmux.1
+++ b/tmux.1
@@ -520,7 +520,11 @@ the given four or eight digit hexadecimal number.
When preceded (escaped) by a \e, the following characters are replaced: \ee by
the escape character; \er by a carriage return; \en by a newline; and \et by a
tab.
-.Pp
+.It
+\eooo is replaced by a character of the octal value ooo.
+Three octal digits are required, for example \e001.
+The largest valid character is \e377.
+.It
Any other characters preceded by \e are replaced by themselves (that is, the \e
is removed) and are not treated as having any special meaning - so for example
\e; will not mark a command sequence and \e$ will not expand an environment
@@ -919,7 +923,7 @@ section.
The following commands are available to manage clients and sessions:
.Bl -tag -width Ds
.It Xo Ic attach-session
-.Op Fl dEr
+.Op Fl dErx
.Op Fl c Ar working-directory
.Op Fl t Ar target-session
.Xc
@@ -932,6 +936,10 @@ If used from inside, switch the current client.
If
.Fl d
is specified, any other clients attached to the session are detached.
+If
+.Fl x
+is given, send SIGHUP to the parent process of the client as well as
+detaching the client, typically causing it to exit.
.Fl r
signifies the client is read-only (only keys bound to the
.Ic detach-client
@@ -1049,7 +1057,7 @@ command.
Lock all clients attached to
.Ar target-session .
.It Xo Ic new-session
-.Op Fl AdDEP
+.Op Fl AdDEPX
.Op Fl c Ar start-directory
.Op Fl F Ar format
.Op Fl n Ar window-name
@@ -1106,6 +1114,12 @@ already exists; in this case,
behaves like
.Fl d
to
+.Ic attach-session ,
+and
+.Fl X
+behaves like
+.Fl x
+to
.Ic attach-session .
.Pp
If
@@ -4328,7 +4342,7 @@ Align text to the left, centre or right of the available space if appropriate.
.It Xo Ic list=on ,
.Ic list=focus ,
.Ic list=left-marker ,
-.Ic list=right=marker ,
+.Ic list=right-marker ,
.Ic nolist
.Xc
Mark the position of the various window list components in the
diff --git a/tmux.h b/tmux.h
index 3aa6aa81..c66f9a40 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2011,7 +2011,7 @@ extern const struct cmd_entry *cmd_table[];
/* cmd-attach-session.c */
enum cmd_retval cmd_attach_session(struct cmdq_item *, const char *, int, int,
- const char *, int);
+ int, const char *, int);
/* cmd-parse.c */
void cmd_parse_empty(struct cmd_parse_input *);
diff --git a/tty-term.c b/tty-term.c
index b3fc8e0d..d2cdf86a 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -691,7 +691,7 @@ tty_term_describe(struct tty_term *term, enum tty_code_code code)
break;
case TTYCODE_STRING:
strnvis(out, term->codes[code].value.string, sizeof out,
- VIS_OCTAL|VIS_TAB|VIS_NL);
+ VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
xsnprintf(s, sizeof s, "%4u: %s: (string) %s",
code, tty_term_codes[code].name,
out);
diff --git a/tty.c b/tty.c
index 34403a1f..05df4f0f 100644
--- a/tty.c
+++ b/tty.c
@@ -527,6 +527,12 @@ tty_putc(struct tty *tty, u_char ch)
{
const char *acs;
+ if ((tty->term->flags & TERM_EARLYWRAP) &&
+ ch >= 0x20 && ch != 0x7f &&
+ tty->cy == tty->sy - 1 &&
+ tty->cx + 1 >= tty->sx)
+ return;
+
if (tty->cell.attr & GRID_ATTR_CHARSET) {
acs = tty_acs_get(tty, ch);
if (acs != NULL)
@@ -557,6 +563,11 @@ tty_putc(struct tty *tty, u_char ch)
void
tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
{
+ if ((tty->term->flags & TERM_EARLYWRAP) &&
+ tty->cy == tty->sy - 1 &&
+ tty->cx + len >= tty->sx)
+ len = tty->sx - tty->cx - 1;
+
tty_add(tty, buf, len);
if (tty->cx + width > tty->sx) {
tty->cx = (tty->cx + width) - tty->sx;
diff --git a/window-buffer.c b/window-buffer.c
index d65916b5..224dfedb 100644
--- a/window-buffer.c
+++ b/window-buffer.c
@@ -245,7 +245,7 @@ window_buffer_draw(__unused void *modedata, void *itemdata,
at = 0;
while (end != pdata + psize && *end != '\n') {
if ((sizeof line) - at > 5) {
- cp = vis(line + at, *end, VIS_TAB|VIS_OCTAL, 0);
+ cp = vis(line + at, *end, VIS_OCTAL|VIS_TAB, 0);
at = cp - line;
}
end++;
diff --git a/window.c b/window.c
index 1b30c793..99538be9 100644
--- a/window.c
+++ b/window.c
@@ -1137,7 +1137,7 @@ window_pane_reset_mode(struct window_pane *wp)
} else {
log_debug("%s: next mode is %s", __func__, next->mode->name);
wp->screen = next->screen;
- if (next != NULL && next->mode->resize != NULL)
+ if (next->mode->resize != NULL)
next->mode->resize(next, wp->sx, wp->sy);
}
wp->flags |= (PANE_REDRAW|PANE_CHANGED);