mirror of
https://github.com/tmux/tmux.git
synced 2026-08-03 14:08:59 +00:00
Merge branch 'master' into events
This commit is contained in:
@@ -30,8 +30,8 @@ const struct cmd_entry cmd_copy_mode_entry = {
|
||||
.name = "copy-mode",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "deHMqSs:t:u", 0, 0, NULL },
|
||||
.usage = "[-deHMqSu] [-s src-pane] " CMD_TARGET_PANE_USAGE,
|
||||
.args = { "dekHMqSs:t:u", 0, 0, NULL },
|
||||
.usage = "[-dekHMqSu] [-s src-pane] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.source = { 's', CMD_FIND_PANE, 0 },
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
|
||||
@@ -141,7 +141,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
sc.cwd = args_get(args, 'c');
|
||||
|
||||
sc.flags = 0;
|
||||
if (args_has(args, 'E'))
|
||||
if (args_has(args, 'E') || (count == 1 && *args_string(args, 0) == '\0'))
|
||||
sc.flags |= SPAWN_EMPTY;
|
||||
if (args_has(args, 'd'))
|
||||
sc.flags |= SPAWN_DETACHED;
|
||||
|
||||
@@ -105,7 +105,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
flags |= SPAWN_FULLSIZE;
|
||||
|
||||
input = args_has(args, 'I');
|
||||
if (input)
|
||||
if (input || (count == 1 && *args_string(args, 0) == '\0'))
|
||||
empty = 1;
|
||||
else
|
||||
empty = args_has(args, 'E');
|
||||
|
||||
2
layout.c
2
layout.c
@@ -1310,7 +1310,7 @@ layout_split_sizes(struct layout_cell *lc, int size, int before,
|
||||
s2 = size;
|
||||
if (s2 < PANE_MINIMUM)
|
||||
s2 = PANE_MINIMUM;
|
||||
else if (s2 > sx - 2)
|
||||
else if (s2 > ss - 2)
|
||||
s2 = ss - 2;
|
||||
s1 = ss - 1 - s2;
|
||||
|
||||
|
||||
@@ -101,6 +101,8 @@ $TMUX set -g @ts '1000000000' || exit 1 # 2001-09-09 01:46:40 UTC
|
||||
$TMUX set -g @sp 'a b$c' || exit 1 # shell-special characters for q:
|
||||
$TMUX set -g @hash 'a#b' || exit 1 # a "#" for q/e:
|
||||
$TMUX set -g @sq "a'b" || exit 1 # a single quote for q/s:
|
||||
$TMUX set -g @sub 'abABab' || exit 1
|
||||
$TMUX set -g @slash 'foo/bar foo/' || exit 1
|
||||
$TMUX set -g @nl "$(printf 'a\nb')" || exit 1
|
||||
q_s_nl=$(printf "'a\nb'")
|
||||
|
||||
@@ -426,9 +428,23 @@ test_format "#{=/3/#,:@s}" "abc," # escaped comma in the marker
|
||||
# The truncation marker is itself expanded as a format.
|
||||
test_format "#{=/3/#{l:>}:@s}" "abc>"
|
||||
|
||||
# Substitution flags: a third argument of "i" is case-insensitive; an invalid
|
||||
# regular expression leaves the text unchanged.
|
||||
# Substitution, including regular expressions, back references, different
|
||||
# delimiters, empty matches and the "i" case-insensitive flag.
|
||||
test_format "#{s/z/X/:@s}" "abcdefghij"
|
||||
test_format "#{s/[bd]/X/:@s}" "aXcXefghij"
|
||||
test_format "#{s/A/X/i:@s}" "Xbcdefghij"
|
||||
test_format "#{s/a(.)/\\1x/i:@sub}" "bxBxbx"
|
||||
test_format "#{s/(.)(.)/\\2\\1/:@s}" "badcfehgji"
|
||||
test_format "#{s|foo/|bar/|:@slash}" "bar/bar bar/"
|
||||
test_format "#{s/^abc/ABC/:@s}" "ABCdefghij"
|
||||
test_format "#{s/^(.)(.)/\\2\\1/:@s}" "bacdefghij"
|
||||
test_format "#{s/^x*//:@s}" "abcdefghij"
|
||||
test_format "#{s/^/X/:@s}" "Xabcdefghij"
|
||||
test_format "#{s/^x*/X/:@s}" "Xabcdefghij"
|
||||
test_format "#{s/$/X/:@s}" "abcdefghijX"
|
||||
test_format "#{s/x*//:@s}" "abcdefghij"
|
||||
test_format "#{s/x*/X/:@s}" "aXbXcXdXeXfXgXhXiXjX"
|
||||
# An invalid regular expression leaves the text unchanged.
|
||||
test_format "#{s/[/X/:@s}" "abcdefghij"
|
||||
|
||||
|
||||
|
||||
171
regress/mode-kill.sh
Executable file
171
regress/mode-kill.sh
Executable file
@@ -0,0 +1,171 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Tests of the -k flag on the mode-entering commands (cmd-copy-mode.c and
|
||||
# cmd-choose-tree.c). With -k the pane is killed when the mode is exited: this
|
||||
# is stored on the mode entry in window_pane_set_mode() and acted on in
|
||||
# window_pane_reset_mode() (window.c). It is exercised here for:
|
||||
#
|
||||
# - copy-mode -k (window-copy.c);
|
||||
# - choose-tree -k (window-tree.c);
|
||||
# - choose-buffer -k (window-buffer.c).
|
||||
#
|
||||
# choose-tree and choose-buffer share cmd_choose_tree_exec(), which also backs
|
||||
# choose-client and customize-mode, so those are not repeated.
|
||||
#
|
||||
# Each mode is entered in the active pane of a two-pane window: exiting with
|
||||
# -k must remove that pane and leave the other. copy-mode is left with the
|
||||
# server-side "-X cancel" and needs no client, so those tests run first. The
|
||||
# tree modes only act on a key once the client has drawn the mode, so - as in
|
||||
# choose-tree.sh - a second server then provides a client (an inner "tmux
|
||||
# attach") and its pane is captured to wait until the mode has rendered before
|
||||
# the exit key is sent.
|
||||
|
||||
PATH=/bin:/usr/bin
|
||||
TERM=screen
|
||||
|
||||
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||
TMP=$(mktemp -d) || exit 1
|
||||
TMUX_TMPDIR="$TMP"
|
||||
export TMUX_TMPDIR
|
||||
TMUX="$TEST_TMUX -LtestA$$ -f/dev/null"
|
||||
TMUX2="$TEST_TMUX -LtestB$$ -f/dev/null"
|
||||
|
||||
cleanup()
|
||||
{
|
||||
$TMUX kill-server 2>/dev/null
|
||||
$TMUX2 kill-server 2>/dev/null
|
||||
rm -rf "$TMP"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
fail()
|
||||
{
|
||||
echo "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# capture the screen rendered by the inner client.
|
||||
capture()
|
||||
{
|
||||
$TMUX2 capture-pane -p -t out:0 2>/dev/null
|
||||
}
|
||||
|
||||
# wait_clients $n: wait until the test server has exactly $n clients.
|
||||
wait_clients()
|
||||
{
|
||||
i=0
|
||||
while [ "$i" -lt 50 ]; do
|
||||
c=$($TMUX list-clients -F x 2>/dev/null | grep -c x)
|
||||
[ "$c" -eq "$1" ] && return 0
|
||||
sleep 0.2
|
||||
i=$((i + 1))
|
||||
done
|
||||
fail "expected $1 clients, have $c"
|
||||
}
|
||||
|
||||
# wait_mode $target $state: wait until a pane enters (1) or leaves (0) mode.
|
||||
wait_mode()
|
||||
{
|
||||
i=0
|
||||
while [ "$i" -lt 50 ]; do
|
||||
got=$($TMUX display-message -p -t "$1" '#{pane_in_mode}' \
|
||||
2>/dev/null)
|
||||
[ "$got" = "$2" ] && return 0
|
||||
sleep 0.2
|
||||
i=$((i + 1))
|
||||
done
|
||||
fail "pane $1 mode state is '$got', expected '$2'"
|
||||
}
|
||||
|
||||
# wait_for $marker: wait until the rendered screen contains $marker.
|
||||
wait_for()
|
||||
{
|
||||
i=0
|
||||
while [ "$i" -lt 50 ]; do
|
||||
capture | grep -F -q "$1" && return 0
|
||||
sleep 0.2
|
||||
i=$((i + 1))
|
||||
done
|
||||
fail "timed out waiting for '$1' to render"
|
||||
}
|
||||
|
||||
# pane_gone $pane-id: true if the pane no longer exists. (display-message -t
|
||||
# on a missing pane id falls back to a default target and succeeds, so the
|
||||
# pane list is searched instead.)
|
||||
pane_gone()
|
||||
{
|
||||
! $TMUX list-panes -s -t m -F '#{pane_id}' 2>/dev/null | \
|
||||
grep -q -x "$1"
|
||||
}
|
||||
|
||||
# open_window: make a fresh two-pane window and leave the new (active) pane
|
||||
# as $active and the other as $other.
|
||||
open_window()
|
||||
{
|
||||
$TMUX new-window -t m: -n w 'cat' || fail "new-window failed"
|
||||
$TMUX split-window -t m:w 'cat' || fail "split-window failed"
|
||||
other=$($TMUX display-message -p -t m:w.0 '#{pane_id}')
|
||||
active=$($TMUX display-message -p -t m:w '#{pane_id}')
|
||||
}
|
||||
|
||||
# check_killed $label: wait for the active pane to be killed, leaving only the
|
||||
# other pane, then drop the window.
|
||||
check_killed()
|
||||
{
|
||||
i=0
|
||||
while [ "$i" -lt 50 ]; do
|
||||
pane_gone "$active" && break
|
||||
sleep 0.2
|
||||
i=$((i + 1))
|
||||
done
|
||||
pane_gone "$active" || fail "$1: pane not killed on exit"
|
||||
panes=$($TMUX list-panes -t m:w -F '#{pane_id}' | tr '\n' ' ')
|
||||
[ "$panes" = "$other " ] || \
|
||||
fail "$1: expected only $other left, have $panes"
|
||||
$TMUX kill-window -t m:w 2>/dev/null
|
||||
}
|
||||
|
||||
# Session m; window 0 keeps a live pane so the session (and later the client)
|
||||
# survives each test killing a pane.
|
||||
$TMUX new-session -d -s m -x 80 -y 24 'cat' || exit 1
|
||||
|
||||
# --- copy-mode -k kills the pane, plain copy-mode does not -------------------
|
||||
#
|
||||
# copy-mode is exited with the server-side "-X cancel", so no client is needed
|
||||
# and none is attached yet.
|
||||
open_window
|
||||
$TMUX copy-mode -k -t m:w || fail "copy-mode -k failed"
|
||||
wait_mode "$active" 1
|
||||
$TMUX send-keys -t m:w -X cancel || fail "copy cancel failed"
|
||||
check_killed 'copy-mode -k'
|
||||
|
||||
open_window
|
||||
$TMUX copy-mode -t m:w || fail "copy-mode failed"
|
||||
wait_mode "$active" 1
|
||||
$TMUX send-keys -t m:w -X cancel || fail "copy cancel failed"
|
||||
wait_mode "$active" 0
|
||||
pane_gone "$active" && fail 'copy-mode: pane killed without -k'
|
||||
$TMUX kill-window -t m:w 2>/dev/null
|
||||
|
||||
# --- choose-tree -k and choose-buffer -k kill the pane ----------------------
|
||||
#
|
||||
# These need the client to draw the mode before a key acts, so attach one now.
|
||||
# A paste buffer is needed for choose-buffer to have something to show, and a
|
||||
# distinct -F marker per call is waited for in the capture so the exit key is
|
||||
# only sent once the mode is drawn.
|
||||
$TMUX set-buffer 'mode-kill buffer' || exit 1
|
||||
$TMUX2 new-session -d -s out -x 80 -y 24 "$TMUX attach -t m" || exit 1
|
||||
wait_clients 1
|
||||
open_window
|
||||
$TMUX choose-tree -k -F 'TREEMARK' -t m:w || fail "choose-tree -k failed"
|
||||
wait_for 'TREEMARK'
|
||||
$TMUX send-keys -t m:w q || fail "choose-tree exit failed"
|
||||
check_killed 'choose-tree -k'
|
||||
|
||||
open_window
|
||||
$TMUX choose-buffer -k -F 'BUFMARK' -t m:w || fail "choose-buffer -k failed"
|
||||
wait_for 'BUFMARK'
|
||||
$TMUX send-keys -t m:w q || fail "choose-buffer exit failed"
|
||||
check_killed 'choose-buffer -k'
|
||||
|
||||
exit 0
|
||||
@@ -399,6 +399,19 @@ check_fmt 'P:9.0' '#{pane_pid}' ''
|
||||
check_fail 'command cannot be given for empty pane' \
|
||||
new-window -d -E -t P:10 -n empty 'true'
|
||||
|
||||
# An empty string as the sole argument is equivalent to -E: the pane is
|
||||
# created empty, running no command.
|
||||
check_ok new-window -d -t P:12 -n empty-str ''
|
||||
check_fmt 'P:12.0' '#{pane_dead}' '0'
|
||||
check_fmt 'P:12.0' '#{pane_pid}' ''
|
||||
check_ok kill-window -t P:12
|
||||
|
||||
# A missing command (rather than an empty one) runs the default command, so
|
||||
# the pane is not empty and has a process.
|
||||
check_ok new-window -d -t P:12 -n default-cmd
|
||||
check_fmt 'P:12.0' '#{?pane_pid,live,empty}' 'live'
|
||||
check_ok kill-window -t P:12
|
||||
|
||||
# respawn-pane -E stores the command and cwd without starting it.
|
||||
tmp=${TMPDIR:-/tmp}/tmux-pane-ops-empty-$$
|
||||
rm -f "$tmp"
|
||||
@@ -453,6 +466,13 @@ check_fmt 'P:2' '#{window_panes}' '2'
|
||||
check_fail 'command cannot be given for empty pane' \
|
||||
split-window -d -E -t P:2.0 'sleep 5'
|
||||
|
||||
# An empty string as the sole argument splits with an empty pane, like -E.
|
||||
eid=$($TMUX split-window -d -P -F '#{pane_id}' -t P:2.0 '')
|
||||
check_fmt "$eid" '#{pane_dead}' '0'
|
||||
check_fmt "$eid" '#{pane_pid}' ''
|
||||
check_ok kill-pane -t "$eid"
|
||||
check_fmt 'P:2' '#{window_panes}' '2'
|
||||
|
||||
# -e adds to the new pane's environment.
|
||||
eid=$($TMUX split-window -d -P -F '#{pane_id}' -e GREETING=hello -t P:2.0 \
|
||||
'echo $GREETING; exec cat')
|
||||
|
||||
@@ -105,6 +105,104 @@ check_windows()
|
||||
fi
|
||||
}
|
||||
|
||||
# wait_client_session $expected
|
||||
#
|
||||
# Wait for the only test client to be attached to $expected.
|
||||
wait_client_session()
|
||||
{
|
||||
expected=$1
|
||||
i=0
|
||||
|
||||
while [ $i -lt 30 ]; do
|
||||
out=$($TMUX list-clients -F '#{client_session}' 2>/dev/null ||
|
||||
true)
|
||||
if [ "$out" = "$expected" ]; then
|
||||
return
|
||||
fi
|
||||
i=$((i + 1))
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
echo "Client session wrong."
|
||||
echo "Expected: '$expected'"
|
||||
echo "But got: '$out'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# attach_control_client $session
|
||||
#
|
||||
# Attach a control client to $session and keep its input open on fd 9.
|
||||
attach_control_client()
|
||||
{
|
||||
fifo=$(mktemp -u)
|
||||
|
||||
mkfifo "$fifo" || exit 1
|
||||
$TMUX -C attach-session -t "$1" <"$fifo" >/dev/null 2>&1 &
|
||||
control_pid=$!
|
||||
exec 9>"$fifo"
|
||||
rm -f "$fifo"
|
||||
wait_client_session "$1"
|
||||
}
|
||||
|
||||
# check_attached_destroy $mode
|
||||
#
|
||||
# Run an attached tmux inside a pane and destroy its only session.
|
||||
check_attached_destroy()
|
||||
{
|
||||
mode=$1
|
||||
outer=DODouter$mode
|
||||
outdir=$(mktemp -d) || exit 1
|
||||
script=$outdir/inner.sh
|
||||
rcfile=$outdir/rc
|
||||
|
||||
cat >"$script" <<-EOF
|
||||
#!/bin/sh
|
||||
"$TEST_TMUX" -LtestInner$$-$mode -f/dev/null new \\; \
|
||||
set -g detach-on-destroy $mode \\; send exit Enter
|
||||
printf '%s\n' \$? >"$rcfile"
|
||||
EOF
|
||||
chmod +x "$script" || exit 1
|
||||
|
||||
check_ok new-session -d -s "$outer" -x 80 -y 24
|
||||
check_ok send-keys -t "$outer:0.0" "sh $script" Enter
|
||||
|
||||
i=0
|
||||
while [ $i -lt 50 ]; do
|
||||
[ -f "$rcfile" ] && break
|
||||
i=$((i + 1))
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
pane=$($TMUX capture-pane -pt "$outer:0.0" -S -)
|
||||
if [ ! -f "$rcfile" ]; then
|
||||
echo "Inner tmux did not exit."
|
||||
echo "$pane"
|
||||
$TMUX kill-session -t "$outer" 2>/dev/null || true
|
||||
rm -rf "$outdir"
|
||||
exit 1
|
||||
fi
|
||||
rc=$(cat "$rcfile")
|
||||
if [ "$rc" != 0 ]; then
|
||||
echo "Inner tmux exited with status $rc."
|
||||
echo "$pane"
|
||||
$TMUX kill-session -t "$outer" 2>/dev/null || true
|
||||
rm -rf "$outdir"
|
||||
exit 1
|
||||
fi
|
||||
case "$pane" in
|
||||
*"server exited unexpectedly"*)
|
||||
echo "Inner tmux server crashed."
|
||||
echo "$pane"
|
||||
$TMUX kill-session -t "$outer" 2>/dev/null || true
|
||||
rm -rf "$outdir"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
check_ok kill-session -t "$outer"
|
||||
rm -rf "$outdir"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# new-session and has-session.
|
||||
|
||||
@@ -203,6 +301,38 @@ check_fail '-f only valid with -a' kill-session -f 'x' -t S1
|
||||
check_ok kill-session -C -t S2
|
||||
check_ok has-session -t S2
|
||||
|
||||
# detach-on-destroy previous and next move attached clients in
|
||||
# alphabetical order and must not crash when a session is destroyed.
|
||||
check_ok new-session -d -s DODa -x 80 -y 24
|
||||
check_ok new-session -d -s DODb -x 80 -y 24
|
||||
check_ok new-session -d -s DODc -x 80 -y 24
|
||||
check_ok set-option -t DODb detach-on-destroy previous
|
||||
attach_control_client DODb
|
||||
check_ok kill-session -t DODb
|
||||
wait_client_session DODa
|
||||
exec 9>&-
|
||||
wait "$control_pid" 2>/dev/null || true
|
||||
check_ok kill-session -t DODa
|
||||
check_ok kill-session -t DODc
|
||||
|
||||
check_ok new-session -d -s DODa -x 80 -y 24
|
||||
check_ok new-session -d -s DODb -x 80 -y 24
|
||||
check_ok new-session -d -s DODc -x 80 -y 24
|
||||
check_ok set-option -t DODb detach-on-destroy next
|
||||
attach_control_client DODb
|
||||
check_ok kill-session -t DODb
|
||||
wait_client_session DODc
|
||||
exec 9>&-
|
||||
wait "$control_pid" 2>/dev/null || true
|
||||
check_ok kill-session -t DODa
|
||||
check_ok kill-session -t DODc
|
||||
|
||||
# With only one session, previous and next have no replacement session; the
|
||||
# attached client must exit cleanly rather than being moved to the dying
|
||||
# session.
|
||||
check_attached_destroy previous
|
||||
check_attached_destroy next
|
||||
|
||||
# -a kills every other session.
|
||||
check_ok kill-session -a -t S1
|
||||
check_sessions 'S1'
|
||||
|
||||
57
regress/theme-report.sh
Executable file
57
regress/theme-report.sh
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Test that the theme reported to a pane (mode 2031 / DSR 996) follows the
|
||||
# terminal's reported theme, not a guess from the background colour.
|
||||
#
|
||||
# An inner client is attached inside an outer tmux pane. The outer pane has a
|
||||
# light background, so the outer server answers the inner client's DSR 996 with
|
||||
# light. The inner server is given a dark window background, so a guess from the
|
||||
# background colour would say dark. A pane in the inner server then queries DSR
|
||||
# 996: the answer must be light (2), following the client's reported theme, not
|
||||
# dark (1) from the background.
|
||||
|
||||
PATH=/bin:/usr/bin
|
||||
TERM=screen
|
||||
|
||||
[ -z "$TEST_TMUX" ] && TEST_TMUX=$(readlink -f ../tmux)
|
||||
INNER="$TEST_TMUX -LtestI$$ -f/dev/null"
|
||||
OUTER="$TEST_TMUX -LtestO$$ -f/dev/null"
|
||||
$INNER kill-server 2>/dev/null
|
||||
$OUTER kill-server 2>/dev/null
|
||||
|
||||
TMP=$(mktemp)
|
||||
trap "rm -f $TMP; $INNER kill-server 2>/dev/null; $OUTER kill-server 2>/dev/null" \
|
||||
0 1 15
|
||||
|
||||
# Inner server, dark background, keep panes alive across the query respawn.
|
||||
$INNER new-session -d -x80 -y24 || exit 1
|
||||
$INNER set -g remain-on-exit on
|
||||
$INNER set -g window-style 'bg=black'
|
||||
|
||||
# Outer server with a light background, running the inner client attached so the
|
||||
# inner client has a real terminal that reports a theme.
|
||||
$OUTER new-session -d -x80 -y24 || exit 1
|
||||
$OUTER set -g window-style 'bg=white'
|
||||
$OUTER new-window "$INNER attach" || exit 1
|
||||
sleep 2
|
||||
|
||||
# Query DSR 996 from an inner pane and capture the CSI ? 997 ; Ps n reply.
|
||||
$INNER respawnw -k -t:0 -- sh -c "
|
||||
exec 2>/dev/null
|
||||
stty raw -echo
|
||||
printf '\033[?996n'
|
||||
dd bs=1 count=9 2>/dev/null | cat -v > $TMP
|
||||
sleep 1
|
||||
"
|
||||
sleep 2
|
||||
|
||||
actual=$(cat "$TMP")
|
||||
expected='^[[?997;2n' # 2 = light (from the terminal), not 1 = dark (from bg)
|
||||
|
||||
if [ "$actual" = "$expected" ]; then
|
||||
[ -n "$VERBOSE" ] && echo "[PASS] reported terminal theme ($actual)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "[FAIL] expected '$expected' (light, from terminal), got '$actual'"
|
||||
exit 1
|
||||
@@ -1667,7 +1667,7 @@ redraw_draw(struct client *c, struct window_pane *wp, int flags)
|
||||
}
|
||||
}
|
||||
tty_sync_start(tty);
|
||||
tty_update_mode(tty, 0, NULL);
|
||||
tty_update_mode(tty, tty->mode & ~CURSOR_MODES, NULL);
|
||||
|
||||
if (wp != NULL)
|
||||
redraw_draw_pane_lines(&dctx, wp, flags);
|
||||
|
||||
@@ -464,6 +464,7 @@ server_destroy_session(struct session *s)
|
||||
{
|
||||
struct client *c;
|
||||
struct session *s_new = NULL, *cs_new = NULL, *use_s;
|
||||
struct sort_criteria sort_crit = { .order = SORT_NAME };
|
||||
int detach_on_destroy;
|
||||
|
||||
detach_on_destroy = options_get_number(s->options, "detach-on-destroy");
|
||||
@@ -472,9 +473,11 @@ server_destroy_session(struct session *s)
|
||||
else if (detach_on_destroy == 2)
|
||||
s_new = server_find_session(s, server_newer_detached_session);
|
||||
else if (detach_on_destroy == 3)
|
||||
s_new = session_previous_session(s, NULL);
|
||||
s_new = session_previous_session(s, &sort_crit);
|
||||
else if (detach_on_destroy == 4)
|
||||
s_new = session_next_session(s, NULL);
|
||||
s_new = session_next_session(s, &sort_crit);
|
||||
if (s_new == s)
|
||||
s_new = NULL;
|
||||
|
||||
/*
|
||||
* If no suitable new session was found above, then look for any
|
||||
|
||||
5
tmux.1
5
tmux.1
@@ -2587,7 +2587,7 @@ The synopsis for the
|
||||
command is:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo Ic copy\-mode
|
||||
.Op Fl deHMqSu
|
||||
.Op Fl dekHMqSu
|
||||
.Op Fl s Ar src\-pane
|
||||
.Op Fl t Ar target\-pane
|
||||
.Xc
|
||||
@@ -2627,6 +2627,9 @@ example with:
|
||||
bind PageUp copy\-mode \-eu
|
||||
bind PageDown copy\-mode \-ed
|
||||
.Ed
|
||||
.Pp
|
||||
.Fl k
|
||||
kills the pane when the mode is exited.
|
||||
.El
|
||||
.Pp
|
||||
A number of preset arrangements of panes are available, these are called
|
||||
|
||||
18
window.c
18
window.c
@@ -2461,7 +2461,6 @@ window_pane_get_theme(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct client *loop;
|
||||
enum client_theme theme;
|
||||
int found_light = 0, found_dark = 0;
|
||||
|
||||
if (wp == NULL)
|
||||
@@ -2469,14 +2468,9 @@ window_pane_get_theme(struct window_pane *wp)
|
||||
w = wp->window;
|
||||
|
||||
/*
|
||||
* Derive theme from pane background color, if it's not the default
|
||||
* colour.
|
||||
* Prefer a theme reported by an attached client with mode 2031 or DSR
|
||||
* 996: the terminal knows its own light or dark mode.
|
||||
*/
|
||||
theme = colour_totheme(window_pane_get_bg(wp));
|
||||
if (theme != THEME_UNKNOWN)
|
||||
return (theme);
|
||||
|
||||
/* Try to find a client that has a theme. */
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
if (loop->flags & CLIENT_UNATTACHEDFLAGS)
|
||||
continue;
|
||||
@@ -2493,12 +2487,16 @@ window_pane_get_theme(struct window_pane *wp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_dark && !found_light)
|
||||
return (THEME_DARK);
|
||||
if (found_light && !found_dark)
|
||||
return (THEME_LIGHT);
|
||||
return (THEME_UNKNOWN);
|
||||
|
||||
/*
|
||||
* Otherwise guess from the pane background colour, for terminals which
|
||||
* do not report a theme themselves.
|
||||
*/
|
||||
return (colour_totheme(window_pane_get_bg(wp)));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user