mirror of
https://github.com/tmux/tmux.git
synced 2026-06-04 00:56:17 +00:00
Merge branch 'master' into floating_panes
This commit is contained in:
@@ -110,22 +110,28 @@ cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl,
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
template = "#{pane_index}: "
|
template = "#{pane_index}: "
|
||||||
"[#{pane_width}x#{pane_height}] [history "
|
"[#{pane_width}x#{pane_height}"
|
||||||
|
"#{?pane_floating_flag, "
|
||||||
|
"#{pane_x}#,#{pane_y}#,#{pane_z}}] [history "
|
||||||
"#{history_size}/#{history_limit}, "
|
"#{history_size}/#{history_limit}, "
|
||||||
"#{history_bytes} bytes] #{pane_id}"
|
"#{history_bytes} bytes] #{pane_id}"
|
||||||
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
|
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
template = "#{window_index}.#{pane_index}: "
|
template = "#{window_index}.#{pane_index}: "
|
||||||
"[#{pane_width}x#{pane_height}] [history "
|
"[#{pane_width}x#{pane_height}"
|
||||||
|
"#{?pane_floating_flag, "
|
||||||
|
"#{pane_x}#,#{pane_y}#,#{pane_z}}] [history "
|
||||||
"#{history_size}/#{history_limit}, "
|
"#{history_size}/#{history_limit}, "
|
||||||
"#{history_bytes} bytes] #{pane_id}"
|
"#{history_bytes} bytes] #{pane_id}"
|
||||||
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
|
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
template = "#{session_name}:#{window_index}."
|
template = "#{session_name}:#{window_index}."
|
||||||
"#{pane_index}: [#{pane_width}x#{pane_height}] "
|
"#{pane_index}: [#{pane_width}x#{pane_height}"
|
||||||
"[history #{history_size}/#{history_limit}, "
|
"#{?pane_floating_flag, "
|
||||||
|
"#{pane_x}#,#{pane_y}#,#{pane_z}}] [history "
|
||||||
|
"#{history_size}/#{history_limit}, "
|
||||||
"#{history_bytes} bytes] #{pane_id}"
|
"#{history_bytes} bytes] #{pane_id}"
|
||||||
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
|
"#{?pane_active, (active),}#{?pane_dead, (dead),}";
|
||||||
break;
|
break;
|
||||||
|
|||||||
48
format.c
48
format.c
@@ -2425,6 +2425,45 @@ format_cb_pane_width(struct format_tree *ft)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_x. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_x(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
if (ft->wp != NULL)
|
||||||
|
return (format_printf("%d", ft->wp->xoff));
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_y. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_y(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
if (ft->wp != NULL)
|
||||||
|
return (format_printf("%d", ft->wp->yoff));
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_z. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_z(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
u_int n = 0;
|
||||||
|
|
||||||
|
if (ft->wp != NULL) {
|
||||||
|
if (~ft->wp->flags & PANE_FLOATING)
|
||||||
|
return (xstrdup("0"));
|
||||||
|
TAILQ_FOREACH(wp, &ft->wp->window->z_index, zentry) {
|
||||||
|
if (wp->flags & PANE_FLOATING)
|
||||||
|
n++;
|
||||||
|
if (wp == ft->wp)
|
||||||
|
return (format_printf("%u", n));
|
||||||
|
}
|
||||||
|
return (xstrdup("0"));
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Callback for pane_zoomed_flag. */
|
/* Callback for pane_zoomed_flag. */
|
||||||
static void *
|
static void *
|
||||||
format_cb_pane_zoomed_flag(struct format_tree *ft)
|
format_cb_pane_zoomed_flag(struct format_tree *ft)
|
||||||
@@ -3517,6 +3556,15 @@ static const struct format_table_entry format_table[] = {
|
|||||||
{ "pane_width", FORMAT_TABLE_STRING,
|
{ "pane_width", FORMAT_TABLE_STRING,
|
||||||
format_cb_pane_width
|
format_cb_pane_width
|
||||||
},
|
},
|
||||||
|
{ "pane_x", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_pane_x
|
||||||
|
},
|
||||||
|
{ "pane_y", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_pane_y
|
||||||
|
},
|
||||||
|
{ "pane_z", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_pane_z
|
||||||
|
},
|
||||||
{ "pane_zoomed_flag", FORMAT_TABLE_STRING,
|
{ "pane_zoomed_flag", FORMAT_TABLE_STRING,
|
||||||
format_cb_pane_zoomed_flag
|
format_cb_pane_zoomed_flag
|
||||||
},
|
},
|
||||||
|
|||||||
66
input.c
66
input.c
@@ -281,6 +281,7 @@ enum input_csi_type {
|
|||||||
INPUT_CSI_IL,
|
INPUT_CSI_IL,
|
||||||
INPUT_CSI_MODOFF,
|
INPUT_CSI_MODOFF,
|
||||||
INPUT_CSI_MODSET,
|
INPUT_CSI_MODSET,
|
||||||
|
INPUT_CSI_QUERY,
|
||||||
INPUT_CSI_QUERY_PRIVATE,
|
INPUT_CSI_QUERY_PRIVATE,
|
||||||
INPUT_CSI_RCP,
|
INPUT_CSI_RCP,
|
||||||
INPUT_CSI_REP,
|
INPUT_CSI_REP,
|
||||||
@@ -336,6 +337,7 @@ static const struct input_table_entry input_csi_table[] = {
|
|||||||
{ 'n', "", INPUT_CSI_DSR },
|
{ 'n', "", INPUT_CSI_DSR },
|
||||||
{ 'n', ">", INPUT_CSI_MODOFF },
|
{ 'n', ">", INPUT_CSI_MODOFF },
|
||||||
{ 'n', "?", INPUT_CSI_DSR_PRIVATE },
|
{ 'n', "?", INPUT_CSI_DSR_PRIVATE },
|
||||||
|
{ 'p', "$", INPUT_CSI_QUERY },
|
||||||
{ 'p', "?$", INPUT_CSI_QUERY_PRIVATE },
|
{ 'p', "?$", INPUT_CSI_QUERY_PRIVATE },
|
||||||
{ 'q', " ", INPUT_CSI_DECSCUSR },
|
{ 'q', " ", INPUT_CSI_DECSCUSR },
|
||||||
{ 'q', ">", INPUT_CSI_XDA },
|
{ 'q', ">", INPUT_CSI_XDA },
|
||||||
@@ -1608,8 +1610,34 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case INPUT_CSI_QUERY:
|
||||||
|
m = input_get(ictx, 0, 0, 0);
|
||||||
|
switch (m) {
|
||||||
|
case 4: /* IRM */
|
||||||
|
n = (s->mode & MODE_INSERT) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
n = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m > 0)
|
||||||
|
input_reply(ictx, 1, "\033[%d;%d$y", m, n);
|
||||||
|
break;
|
||||||
case INPUT_CSI_QUERY_PRIVATE:
|
case INPUT_CSI_QUERY_PRIVATE:
|
||||||
switch (input_get(ictx, 0, 0, 0)) {
|
m = input_get(ictx, 0, 0, 0);
|
||||||
|
switch (m) {
|
||||||
|
case 1: /* DECCKM */
|
||||||
|
n = (s->mode & MODE_KCURSOR) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
case 3: /* DECCOLM: always reset */
|
||||||
|
n = 4;
|
||||||
|
break;
|
||||||
|
case 6: /* DECOM */
|
||||||
|
n = (s->mode & MODE_ORIGIN) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
case 7: /* DECAWM */
|
||||||
|
n = (s->mode & MODE_WRAP) ? 1 : 2;
|
||||||
|
break;
|
||||||
case 12: /* cursor blink: 1 = blink, 2 = steady */
|
case 12: /* cursor blink: 1 = blink, 2 = steady */
|
||||||
if (s->cstyle != SCREEN_CURSOR_DEFAULT ||
|
if (s->cstyle != SCREEN_CURSOR_DEFAULT ||
|
||||||
s->mode & MODE_CURSOR_BLINKING_SET)
|
s->mode & MODE_CURSOR_BLINKING_SET)
|
||||||
@@ -1624,28 +1652,48 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
/* blink for 1,3,5; steady for 0,2,4,6 */
|
/* blink for 1,3,5; steady for 0,2,4,6 */
|
||||||
n = (p == 1 || p == 3 || p == 5) ? 1 : 2;
|
n = (p == 1 || p == 3 || p == 5) ? 1 : 2;
|
||||||
}
|
}
|
||||||
input_reply(ictx, 1, "\033[?12;%d$y", n);
|
break;
|
||||||
|
case 25: /* DECTCEM */
|
||||||
|
n = (s->mode & MODE_CURSOR) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
case 47:
|
||||||
|
case 1047:
|
||||||
|
case 1049: /* alternate screen */
|
||||||
|
n = SCREEN_IS_ALTERNATE(s) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
case 1000: /* mouse: normal tracking */
|
||||||
|
n = (s->mode & MODE_MOUSE_STANDARD) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
case 1002: /* mouse: button-event tracking */
|
||||||
|
n = (s->mode & MODE_MOUSE_BUTTON) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
case 1003: /* mouse: any-event tracking */
|
||||||
|
n = (s->mode & MODE_MOUSE_ALL) ? 1 : 2;
|
||||||
break;
|
break;
|
||||||
case 1004: /* focus reporting */
|
case 1004: /* focus reporting */
|
||||||
n = (s->mode & MODE_FOCUSON) ? 1 : 2;
|
n = (s->mode & MODE_FOCUSON) ? 1 : 2;
|
||||||
input_reply(ictx, 1, "\033[?1004;%d$y", n);
|
|
||||||
break;
|
break;
|
||||||
case 1006: /* SGR mouse */
|
case 1005: /* mouse: UTF-8 */
|
||||||
|
n = (s->mode & MODE_MOUSE_UTF8) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
case 1006: /* mouse: SGR */
|
||||||
n = (s->mode & MODE_MOUSE_SGR) ? 1 : 2;
|
n = (s->mode & MODE_MOUSE_SGR) ? 1 : 2;
|
||||||
input_reply(ictx, 1, "\033[?1006;%d$y", n);
|
|
||||||
break;
|
break;
|
||||||
case 2004: /* bracketed paste */
|
case 2004: /* bracketed paste */
|
||||||
n = (s->mode & MODE_BRACKETPASTE) ? 1 : 2;
|
n = (s->mode & MODE_BRACKETPASTE) ? 1 : 2;
|
||||||
input_reply(ictx, 1, "\033[?2004;%d$y", n);
|
|
||||||
break;
|
break;
|
||||||
case 2026: /* synchronized output */
|
case 2026: /* synchronized output */
|
||||||
n = (s->mode & MODE_SYNC) ? 1 : 2;
|
n = (s->mode & MODE_SYNC) ? 1 : 2;
|
||||||
input_reply(ictx, 1, "\033[?2026;%d$y", n);
|
|
||||||
break;
|
break;
|
||||||
case 2031:
|
case 2031: /* theme update notifications */
|
||||||
input_reply(ictx, 1, "\033[?2031;2$y");
|
n = (s->mode & MODE_THEME_UPDATES) ? 1 : 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
n = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (m > 0)
|
||||||
|
input_reply(ictx, 1, "\033[?%d;%d$y", m, n);
|
||||||
break;
|
break;
|
||||||
case INPUT_CSI_DSR:
|
case INPUT_CSI_DSR:
|
||||||
switch (input_get(ictx, 0, 0, 0)) {
|
switch (input_get(ictx, 0, 0, 0)) {
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ sleep 1
|
|||||||
|
|
||||||
TMP=$(mktemp)
|
TMP=$(mktemp)
|
||||||
TMP2=$(mktemp)
|
TMP2=$(mktemp)
|
||||||
trap "rm -f $TMP $TMP2; $TMUX kill-server 2>/dev/null" 0 1 15
|
TMP3=$(mktemp)
|
||||||
|
TMP4=$(mktemp)
|
||||||
|
TMP5=$(mktemp)
|
||||||
|
trap "rm -f $TMP $TMP2 $TMP3 $TMP4 $TMP5; $TMUX kill-server 2>/dev/null" 0 1 15
|
||||||
|
|
||||||
$TMUX -f/dev/null new -d -x80 -y24 || exit 1
|
$TMUX -f/dev/null new -d -x80 -y24 || exit 1
|
||||||
sleep 1
|
sleep 1
|
||||||
@@ -25,18 +28,19 @@ $TMUX set -g remain-on-exit on
|
|||||||
|
|
||||||
exit_status=0
|
exit_status=0
|
||||||
|
|
||||||
# query_decrpm <outfile> [setup_seq]
|
# query_decrpm <outfile> <mode> [setup_seq]
|
||||||
# Spawn a pane that optionally sends setup_seq, then sends DECRQM for
|
# Spawn a pane that optionally sends setup_seq, then sends DECRQM for
|
||||||
# mode 2026 and captures the response into outfile in cat -v form.
|
# mode 2026 and captures the response into outfile in cat -v form.
|
||||||
query_decrpm() {
|
query_decrpm() {
|
||||||
_outfile=$1
|
_outfile=$1
|
||||||
_setup=$2
|
_mode=$2
|
||||||
|
_setup=$3
|
||||||
|
|
||||||
$TMUX respawnw -k -t:0 -- sh -c "
|
$TMUX respawnw -k -t:0 -- sh -c "
|
||||||
exec 2>/dev/null
|
exec 2>/dev/null
|
||||||
stty raw -echo
|
stty raw -echo
|
||||||
${_setup:+printf '$_setup'; sleep 0.2}
|
${_setup:+printf '$_setup'; sleep 0.2}
|
||||||
printf '\033[?2026\$p'
|
printf '\033[%s\$p' "$_mode"
|
||||||
dd bs=1 count=11 2>/dev/null | cat -v > $_outfile
|
dd bs=1 count=11 2>/dev/null | cat -v > $_outfile
|
||||||
sleep 0.2
|
sleep 0.2
|
||||||
" || exit 1
|
" || exit 1
|
||||||
@@ -46,7 +50,7 @@ query_decrpm () {
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Test 1: mode 2026 should be reset by default (Ps=2)
|
# Test 1: mode 2026 should be reset by default (Ps=2)
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
query_decrpm "$TMP"
|
query_decrpm "$TMP" "?2026"
|
||||||
|
|
||||||
actual=$(cat "$TMP")
|
actual=$(cat "$TMP")
|
||||||
expected='^[[?2026;2$y'
|
expected='^[[?2026;2$y'
|
||||||
@@ -63,7 +67,7 @@ fi
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Test 2: set mode 2026 (SM ?2026), then query (expect Ps=1)
|
# Test 2: set mode 2026 (SM ?2026), then query (expect Ps=1)
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
query_decrpm "$TMP2" '\033[?2026h'
|
query_decrpm "$TMP2" "?2026" '\033[?2026h'
|
||||||
|
|
||||||
actual=$(cat "$TMP2")
|
actual=$(cat "$TMP2")
|
||||||
expected='^[[?2026;1$y'
|
expected='^[[?2026;1$y'
|
||||||
@@ -77,6 +81,61 @@ else
|
|||||||
exit_status=1
|
exit_status=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Test 3: mode 25 should return current value
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
query_decrpm "$TMP3" "?25" '\033[?25l'
|
||||||
|
|
||||||
|
actual=$(cat "$TMP3")
|
||||||
|
expected='^[[?25;2$y'
|
||||||
|
|
||||||
|
if [ "$actual" = "$expected" ]; then
|
||||||
|
if [ -n "$VERBOSE" ]; then
|
||||||
|
echo "[PASS] DECTCEM 25 (reset) -> $actual"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "[FAIL] DECTCEM 25 (reset): expected '$expected', got '$actual'"
|
||||||
|
exit_status=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Test 4: mode ?9999 should return not recognized
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
query_decrpm "$TMP4" "?9999" '\033[?9999h'
|
||||||
|
|
||||||
|
actual=$(cat "$TMP4")
|
||||||
|
expected='^[[?9999;0$y'
|
||||||
|
|
||||||
|
if [ "$actual" = "$expected" ]; then
|
||||||
|
if [ -n "$VERBOSE" ]; then
|
||||||
|
echo "[PASS] DECSM 9999 (not recognized) -> $actual"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "[FAIL] DECSM 9999 (not recognized): expected '$expected', got '$actual'"
|
||||||
|
exit_status=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
|
exit $exit_status
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Test 5: mode 4 is reset by default
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
query_decrpm "$TMP5" "4" '\033[4h'
|
||||||
|
|
||||||
|
actual=$(cat "$TMP5")
|
||||||
|
expected='^[[4;1$y'
|
||||||
|
|
||||||
|
if [ "$actual" = "$expected" ]; then
|
||||||
|
if [ -n "$VERBOSE" ]; then
|
||||||
|
echo "[PASS] SM 4 (is set) -> $actual"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "[FAIL] SM 4 (is set): expected '$expected', got '$actual'"
|
||||||
|
exit_status=1
|
||||||
|
fi
|
||||||
|
|
||||||
$TMUX kill-server 2>/dev/null
|
$TMUX kill-server 2>/dev/null
|
||||||
|
|
||||||
exit $exit_status
|
exit $exit_status
|
||||||
3
tmux.1
3
tmux.1
@@ -6689,6 +6689,9 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
|
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
|
||||||
.It Li "pane_unseen_changes" Ta "" Ta "1 if there were changes in pane while in mode"
|
.It Li "pane_unseen_changes" Ta "" Ta "1 if there were changes in pane while in mode"
|
||||||
.It Li "pane_width" Ta "" Ta "Width of pane"
|
.It Li "pane_width" Ta "" Ta "Width of pane"
|
||||||
|
.It Li "pane_x" Ta "" Ta "X position of pane"
|
||||||
|
.It Li "pane_y" Ta "" Ta "Y position of pane"
|
||||||
|
.It Li "pane_z" Ta "" Ta "Z position of pane"
|
||||||
.It Li "pane_zoomed_flag" Ta "" Ta "1 if pane is zoomed"
|
.It Li "pane_zoomed_flag" Ta "" Ta "1 if pane is zoomed"
|
||||||
.It Li "pid" Ta "" Ta "Server PID"
|
.It Li "pid" Ta "" Ta "Server PID"
|
||||||
.It Li "prev_window_active" Ta "" Ta "1 if previous window in W: loop is active"
|
.It Li "prev_window_active" Ta "" Ta "1 if previous window in W: loop is active"
|
||||||
|
|||||||
Reference in New Issue
Block a user