Add a clear-on-attach option which when turned off scrolls away the

existing terminal state instead of entering the alternate screen. This
is useful in environments where tmux is started as a login shell but it
is important that any pre-tmux messages are still visible. GitHub issue
5508 from Josef Řídký.
This commit is contained in:
nicm
2026-08-25 08:37:08 +00:00
committed by tmux update bot
parent 6f4c9b32af
commit 4157b64754
5 changed files with 48 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: options-table.c,v 1.242 2026/07/27 08:03:01 nicm Exp $ */
/* $OpenBSD: options-table.c,v 1.243 2026/08/25 08:37:08 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -306,6 +306,16 @@ const struct options_table_entry options_table[] = {
"When this is reached, the oldest buffer is deleted."
},
{ .name = "clear-on-attach",
.type = OPTIONS_TABLE_FLAG,
.scope = OPTIONS_TABLE_SERVER,
.default_num = 1,
.text = "Whether to use the alternate screen and clear it when "
"a client is attached. When disabled, tmux does not "
"enter the alternate screen on attach so terminal "
"content before tmux remains in scrollback."
},
{ .name = "command-alias",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SERVER,

13
tmux.1
View File

@@ -1,4 +1,4 @@
.\" $OpenBSD: tmux.1,v 1.1158 2026/08/20 09:19:24 nicm Exp $
.\" $OpenBSD: tmux.1,v 1.1159 2026/08/25 08:37:08 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: August 20 2026 $
.Dd $Mdocdate: August 25 2026 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -4752,6 +4752,15 @@ for backspace.
Set the number of buffers; as new buffers are added to the top of the stack,
old ones are removed from the bottom if necessary to maintain this maximum
length.
.It Xo Ic clear\-on\-attach
.Op Ic on | off
.Xc
When enabled (the default), the client terminal switches to the alternate
screen and clears it when a client is attached.
When disabled,
.Nm
does not enter the alternate screen; instead the existing terminal content is
scrolled into the scrollback buffer so it remains accessible.
.It Xo Ic command\-alias[]
.Ar name=value
.Xc

3
tmux.h
View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tmux.h,v 1.1430 2026/08/24 21:17:19 nicm Exp $ */
/* $OpenBSD: tmux.h,v 1.1431 2026/08/25 08:37:08 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -474,6 +474,7 @@ enum tty_code_code {
TTYC_ICH1,
TTYC_IL,
TTYC_IL1,
TTYC_IND,
TTYC_INDN,
TTYC_INVIS,
TTYC_KCBT,

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tty-term.c,v 1.108 2026/08/17 14:47:41 nicm Exp $ */
/* $OpenBSD: tty-term.c,v 1.109 2026/08/25 08:37:08 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -108,6 +108,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_ICH] = { TTYCODE_STRING, "ich" },
[TTYC_IL1] = { TTYCODE_STRING, "il1" },
[TTYC_IL] = { TTYCODE_STRING, "il" },
[TTYC_IND] = { TTYCODE_STRING, "ind" },
[TTYC_INDN] = { TTYCODE_STRING, "indn" },
[TTYC_INVIS] = { TTYCODE_STRING, "invis" },
[TTYC_KCBT] = { TTYCODE_STRING, "kcbt" },

28
tty.c
View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tty.c,v 1.479 2026/08/18 09:01:20 nicm Exp $ */
/* $OpenBSD: tty.c,v 1.480 2026/08/25 08:37:08 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -333,6 +333,7 @@ tty_start_tty(struct tty *tty)
{
struct client *c = tty->client;
struct termios tio;
u_int i;
setblocking(c->fd, 0);
event_add(&tty->event_in, NULL);
@@ -348,10 +349,21 @@ tty_start_tty(struct tty *tty)
if (tcsetattr(c->fd, TCSANOW, &tio) == 0)
tcflush(c->fd, TCOFLUSH);
tty_putcode(tty, TTYC_SMCUP);
if (options_get_number(global_options, "clear-on-attach")) {
tty_putcode(tty, TTYC_SMCUP);
tty_putcode(tty, TTYC_CLEAR);
} else {
tty_putcode_ii(tty, TTYC_CSR, 0, tty->sy - 1);
tty_putcode_ii(tty, TTYC_CUP, 0, tty->sy - 1);
if (tty_term_has(tty->term, TTYC_INDN))
tty_putcode_i(tty, TTYC_INDN, tty->sy + 1);
else if (tty_term_has(tty->term, TTYC_IND)) {
for (i = 0; i < tty->sy + 1; i++)
tty_putcode(tty, TTYC_IND);
} else
tty_putcode(tty, TTYC_CLEAR);
}
tty_putcode(tty, TTYC_SMKX);
tty_putcode(tty, TTYC_CLEAR);
if (tty_acs_needed(tty)) {
log_debug("%s: using capabilities for ACS", c->name);
@@ -467,7 +479,8 @@ tty_stop_tty(struct tty *tty)
tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
if (options_get_number(global_options, "clear-on-attach"))
tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
if (tty->cstyle != SCREEN_CURSOR_DEFAULT) {
if (tty_term_has(tty->term, TTYC_SE))
tty_raw(tty, tty_term_string(tty->term, TTYC_SE));
@@ -492,7 +505,10 @@ tty_stop_tty(struct tty *tty)
if (tty_use_margin(tty))
tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG));
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
if (options_get_number(global_options, "clear-on-attach"))
tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP));
else
tty_raw(tty, tty_term_string(tty->term, TTYC_CLEAR));
if (tty->term->flags & TERM_VT100LIKE)
tty_raw(tty, "\033[?2031l");