mirror of
https://github.com/tmux/tmux.git
synced 2025-03-16 15:38:49 +00:00
Merge branch 'obsd-master' into master
This commit is contained in:
commit
39904f7fc6
@ -38,8 +38,8 @@ const struct cmd_entry cmd_new_window_entry = {
|
|||||||
.name = "new-window",
|
.name = "new-window",
|
||||||
.alias = "neww",
|
.alias = "neww",
|
||||||
|
|
||||||
.args = { "abc:de:F:kn:Pt:", 0, -1 },
|
.args = { "abc:de:F:kn:PSt:", 0, -1 },
|
||||||
.usage = "[-abdkP] [-c start-directory] [-e environment] [-F format] "
|
.usage = "[-abdkPS] [-c start-directory] [-e environment] [-F format] "
|
||||||
"[-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]",
|
"[-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]",
|
||||||
|
|
||||||
.target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX },
|
.target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX },
|
||||||
@ -52,6 +52,7 @@ static enum cmd_retval
|
|||||||
cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
{
|
{
|
||||||
struct args *args = cmd_get_args(self);
|
struct args *args = cmd_get_args(self);
|
||||||
|
struct client *c = cmdq_get_client(item);
|
||||||
struct cmd_find_state *current = cmdq_get_current(item);
|
struct cmd_find_state *current = cmdq_get_current(item);
|
||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
struct spawn_context sc;
|
struct spawn_context sc;
|
||||||
@ -59,12 +60,41 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct session *s = target->s;
|
struct session *s = target->s;
|
||||||
struct winlink *wl = target->wl;
|
struct winlink *wl = target->wl;
|
||||||
int idx = target->idx, before;
|
int idx = target->idx, before;
|
||||||
struct winlink *new_wl;
|
struct winlink *new_wl = NULL;
|
||||||
char *cause = NULL, *cp;
|
char *cause = NULL, *cp;
|
||||||
const char *template, *add;
|
const char *template, *add, *name;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
struct args_value *value;
|
struct args_value *value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If -S and -n are given and -t is not and a single window with this
|
||||||
|
* name already exists, select it.
|
||||||
|
*/
|
||||||
|
name = args_get(args, 'n');
|
||||||
|
if (args_has(args, 'S') && name != NULL && target->idx == -1) {
|
||||||
|
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||||
|
if (strcmp(wl->window->name, name) != 0)
|
||||||
|
continue;
|
||||||
|
if (new_wl == NULL) {
|
||||||
|
new_wl = wl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cmdq_error(item, "multiple windows named %s", name);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
if (new_wl != NULL) {
|
||||||
|
if (args_has(args, 'd'))
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
if (session_set_current(s, new_wl) == 0)
|
||||||
|
server_redraw_session(s);
|
||||||
|
if (c != NULL && c->session != NULL)
|
||||||
|
s->curw->window->latest = c;
|
||||||
|
recalculate_sizes();
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
before = args_has(args, 'b');
|
before = args_has(args, 'b');
|
||||||
if (args_has(args, 'a') || before) {
|
if (args_has(args, 'a') || before) {
|
||||||
idx = winlink_shuffle_up(s, wl, before);
|
idx = winlink_shuffle_up(s, wl, before);
|
||||||
|
61
format.c
61
format.c
@ -100,6 +100,8 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
|
|||||||
#define FORMAT_LENGTH 0x800
|
#define FORMAT_LENGTH 0x800
|
||||||
#define FORMAT_WIDTH 0x1000
|
#define FORMAT_WIDTH 0x1000
|
||||||
#define FORMAT_QUOTE_STYLE 0x2000
|
#define FORMAT_QUOTE_STYLE 0x2000
|
||||||
|
#define FORMAT_WINDOW_NAME 0x4000
|
||||||
|
#define FORMAT_SESSION_NAME 0x8000
|
||||||
|
|
||||||
/* Limit on recursion. */
|
/* Limit on recursion. */
|
||||||
#define FORMAT_LOOP_LIMIT 10
|
#define FORMAT_LOOP_LIMIT 10
|
||||||
@ -1733,7 +1735,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now try single character with arguments. */
|
/* Now try single character with arguments. */
|
||||||
if (strchr("mCst=peq", cp[0]) == NULL)
|
if (strchr("mCNst=peq", cp[0]) == NULL)
|
||||||
break;
|
break;
|
||||||
c = cp[0];
|
c = cp[0];
|
||||||
|
|
||||||
@ -1857,6 +1859,24 @@ format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
|
|||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Does session name exist? */
|
||||||
|
static char *
|
||||||
|
format_session_name(struct format_expand_state *es, const char *fmt)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
struct session *s;
|
||||||
|
|
||||||
|
name = format_expand1(es, fmt);
|
||||||
|
RB_FOREACH(s, sessions, &sessions) {
|
||||||
|
if (strcmp(s->name, name) == 0) {
|
||||||
|
free(name);
|
||||||
|
return (xstrdup("1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
return (xstrdup("0"));
|
||||||
|
}
|
||||||
|
|
||||||
/* Loop over sessions. */
|
/* Loop over sessions. */
|
||||||
static char *
|
static char *
|
||||||
format_loop_sessions(struct format_expand_state *es, const char *fmt)
|
format_loop_sessions(struct format_expand_state *es, const char *fmt)
|
||||||
@ -1892,6 +1912,30 @@ format_loop_sessions(struct format_expand_state *es, const char *fmt)
|
|||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Does window name exist? */
|
||||||
|
static char *
|
||||||
|
format_window_name(struct format_expand_state *es, const char *fmt)
|
||||||
|
{
|
||||||
|
struct format_tree *ft = es->ft;
|
||||||
|
char *name;
|
||||||
|
struct winlink *wl;
|
||||||
|
|
||||||
|
if (ft->s == NULL) {
|
||||||
|
format_log(es, "window name but no session");
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = format_expand1(es, fmt);
|
||||||
|
RB_FOREACH(wl, winlinks, &ft->s->windows) {
|
||||||
|
if (strcmp(wl->window->name, name) == 0) {
|
||||||
|
free(name);
|
||||||
|
return (xstrdup("1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
return (xstrdup("0"));
|
||||||
|
}
|
||||||
|
|
||||||
/* Loop over windows. */
|
/* Loop over windows. */
|
||||||
static char *
|
static char *
|
||||||
format_loop_windows(struct format_expand_state *es, const char *fmt)
|
format_loop_windows(struct format_expand_state *es, const char *fmt)
|
||||||
@ -2251,6 +2295,13 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
|||||||
case 'T':
|
case 'T':
|
||||||
modifiers |= FORMAT_EXPANDTIME;
|
modifiers |= FORMAT_EXPANDTIME;
|
||||||
break;
|
break;
|
||||||
|
case 'N':
|
||||||
|
if (fm->argc < 1 ||
|
||||||
|
strchr(fm->argv[0], 'w') != NULL)
|
||||||
|
modifiers |= FORMAT_WINDOW_NAME;
|
||||||
|
else if (strchr(fm->argv[0], 's') != NULL)
|
||||||
|
modifiers |= FORMAT_SESSION_NAME;
|
||||||
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
modifiers |= FORMAT_SESSIONS;
|
modifiers |= FORMAT_SESSIONS;
|
||||||
break;
|
break;
|
||||||
@ -2291,6 +2342,14 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
|||||||
value = format_loop_panes(es, copy);
|
value = format_loop_panes(es, copy);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
} else if (modifiers & FORMAT_WINDOW_NAME) {
|
||||||
|
value = format_window_name(es, copy);
|
||||||
|
if (value == NULL)
|
||||||
|
goto fail;
|
||||||
|
} else if (modifiers & FORMAT_SESSION_NAME) {
|
||||||
|
value = format_session_name(es, copy);
|
||||||
|
if (value == NULL)
|
||||||
|
goto fail;
|
||||||
} else if (search != NULL) {
|
} else if (search != NULL) {
|
||||||
/* Search in pane. */
|
/* Search in pane. */
|
||||||
new = format_expand1(es, copy);
|
new = format_expand1(es, copy);
|
||||||
|
4
grid.c
4
grid.c
@ -1048,14 +1048,14 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy,
|
|||||||
srcl->cellsize * sizeof *dstl->celldata);
|
srcl->cellsize * sizeof *dstl->celldata);
|
||||||
} else
|
} else
|
||||||
dstl->celldata = NULL;
|
dstl->celldata = NULL;
|
||||||
|
|
||||||
if (srcl->extdsize != 0) {
|
if (srcl->extdsize != 0) {
|
||||||
dstl->extdsize = srcl->extdsize;
|
dstl->extdsize = srcl->extdsize;
|
||||||
dstl->extddata = xreallocarray(NULL, dstl->extdsize,
|
dstl->extddata = xreallocarray(NULL, dstl->extdsize,
|
||||||
sizeof *dstl->extddata);
|
sizeof *dstl->extddata);
|
||||||
memcpy(dstl->extddata, srcl->extddata, dstl->extdsize *
|
memcpy(dstl->extddata, srcl->extddata, dstl->extdsize *
|
||||||
sizeof *dstl->extddata);
|
sizeof *dstl->extddata);
|
||||||
}
|
} else
|
||||||
|
dstl->extddata = NULL;
|
||||||
|
|
||||||
sy++;
|
sy++;
|
||||||
dy++;
|
dy++;
|
||||||
|
@ -32,8 +32,8 @@ static void screen_redraw_set_context(struct client *,
|
|||||||
struct screen_redraw_ctx *);
|
struct screen_redraw_ctx *);
|
||||||
|
|
||||||
#define CELL_INSIDE 0
|
#define CELL_INSIDE 0
|
||||||
#define CELL_LEFTRIGHT 1
|
#define CELL_TOPBOTTOM 1
|
||||||
#define CELL_TOPBOTTOM 2
|
#define CELL_LEFTRIGHT 2
|
||||||
#define CELL_TOPLEFT 3
|
#define CELL_TOPLEFT 3
|
||||||
#define CELL_TOPRIGHT 4
|
#define CELL_TOPRIGHT 4
|
||||||
#define CELL_BOTTOMLEFT 5
|
#define CELL_BOTTOMLEFT 5
|
||||||
@ -47,6 +47,9 @@ static void screen_redraw_set_context(struct client *,
|
|||||||
|
|
||||||
#define CELL_BORDERS " xqlkmjwvtun~"
|
#define CELL_BORDERS " xqlkmjwvtun~"
|
||||||
|
|
||||||
|
#define START_ISOLATE "\342\201\246"
|
||||||
|
#define END_ISOLATE "\342\201\251"
|
||||||
|
|
||||||
static const struct utf8_data screen_redraw_double_borders[] = {
|
static const struct utf8_data screen_redraw_double_borders[] = {
|
||||||
{ "", 0, 0, 0 },
|
{ "", 0, 0, 0 },
|
||||||
{ "\342\225\221", 0, 3, 1 }, /* U+2551 */
|
{ "\342\225\221", 0, 3, 1 }, /* U+2551 */
|
||||||
@ -299,7 +302,7 @@ screen_redraw_type_of_cell(struct client *c, u_int px, u_int py,
|
|||||||
case 13: /* 1101, left right bottom */
|
case 13: /* 1101, left right bottom */
|
||||||
return (CELL_TOPJOIN);
|
return (CELL_TOPJOIN);
|
||||||
case 12: /* 1100, left right */
|
case 12: /* 1100, left right */
|
||||||
return (CELL_TOPBOTTOM);
|
return (CELL_LEFTRIGHT);
|
||||||
case 11: /* 1011, left top bottom */
|
case 11: /* 1011, left top bottom */
|
||||||
return (CELL_RIGHTJOIN);
|
return (CELL_RIGHTJOIN);
|
||||||
case 10: /* 1010, left top */
|
case 10: /* 1010, left top */
|
||||||
@ -313,7 +316,7 @@ screen_redraw_type_of_cell(struct client *c, u_int px, u_int py,
|
|||||||
case 5: /* 0101, right bottom */
|
case 5: /* 0101, right bottom */
|
||||||
return (CELL_TOPLEFT);
|
return (CELL_TOPLEFT);
|
||||||
case 3: /* 0011, top bottom */
|
case 3: /* 0011, top bottom */
|
||||||
return (CELL_LEFTRIGHT);
|
return (CELL_TOPBOTTOM);
|
||||||
}
|
}
|
||||||
return (CELL_OUTSIDE);
|
return (CELL_OUTSIDE);
|
||||||
}
|
}
|
||||||
@ -680,7 +683,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
|||||||
struct tty *tty = &c->tty;
|
struct tty *tty = &c->tty;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int cell_type, x = ctx->ox + i, y = ctx->oy + j;
|
u_int cell_type, x = ctx->ox + i, y = ctx->oy + j;
|
||||||
int pane_status = ctx->pane_status;
|
int pane_status = ctx->pane_status, isolates;
|
||||||
struct grid_cell gc;
|
struct grid_cell gc;
|
||||||
const struct grid_cell *tmp;
|
const struct grid_cell *tmp;
|
||||||
|
|
||||||
@ -705,11 +708,22 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
|||||||
}
|
}
|
||||||
screen_redraw_border_set(wp, ctx->pane_lines, cell_type, &gc);
|
screen_redraw_border_set(wp, ctx->pane_lines, cell_type, &gc);
|
||||||
|
|
||||||
|
if (cell_type == CELL_TOPBOTTOM &&
|
||||||
|
(c->flags & CLIENT_UTF8) &&
|
||||||
|
tty_term_has(tty->term, TTYC_BIDI))
|
||||||
|
isolates = 1;
|
||||||
|
else
|
||||||
|
isolates = 0;
|
||||||
|
|
||||||
if (ctx->statustop)
|
if (ctx->statustop)
|
||||||
tty_cursor(tty, i, ctx->statuslines + j);
|
tty_cursor(tty, i, ctx->statuslines + j);
|
||||||
else
|
else
|
||||||
tty_cursor(tty, i, j);
|
tty_cursor(tty, i, j);
|
||||||
|
if (isolates)
|
||||||
|
tty_puts(tty, END_ISOLATE);
|
||||||
tty_cell(tty, &gc, &grid_default_cell, NULL);
|
tty_cell(tty, &gc, &grid_default_cell, NULL);
|
||||||
|
if (isolates)
|
||||||
|
tty_puts(tty, START_ISOLATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the borders. */
|
/* Draw the borders. */
|
||||||
|
25
tmux.1
25
tmux.1
@ -2348,7 +2348,7 @@ the
|
|||||||
.Ic base-index
|
.Ic base-index
|
||||||
option.
|
option.
|
||||||
.It Xo Ic new-window
|
.It Xo Ic new-window
|
||||||
.Op Fl abdkP
|
.Op Fl abdkPS
|
||||||
.Op Fl c Ar start-directory
|
.Op Fl c Ar start-directory
|
||||||
.Op Fl e Ar environment
|
.Op Fl e Ar environment
|
||||||
.Op Fl F Ar format
|
.Op Fl F Ar format
|
||||||
@ -2377,6 +2377,14 @@ represents the window to be created; if the target already exists an error is
|
|||||||
shown, unless the
|
shown, unless the
|
||||||
.Fl k
|
.Fl k
|
||||||
flag is used, in which case it is destroyed.
|
flag is used, in which case it is destroyed.
|
||||||
|
If
|
||||||
|
.Fl S
|
||||||
|
is given and a window named
|
||||||
|
.Ar window-name
|
||||||
|
already exists, it is selected (unless
|
||||||
|
.Fl d
|
||||||
|
is also given in which case the command does nothing).
|
||||||
|
.Pp
|
||||||
.Ar shell-command
|
.Ar shell-command
|
||||||
is the command to execute.
|
is the command to execute.
|
||||||
If
|
If
|
||||||
@ -4688,6 +4696,17 @@ For example, to get a list of windows formatted like the status line:
|
|||||||
#{W:#{E:window-status-format} ,#{E:window-status-current-format} }
|
#{W:#{E:window-status-format} ,#{E:window-status-current-format} }
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
|
.Ql N:\&
|
||||||
|
checks if a window (without any suffix or with the
|
||||||
|
.Ql w
|
||||||
|
suffix) or a session (with the
|
||||||
|
.Ql s
|
||||||
|
suffix) name exists, for example
|
||||||
|
.Ql `N/w:foo`
|
||||||
|
is replaced with 1 if a window named
|
||||||
|
.Ql foo
|
||||||
|
exists.
|
||||||
|
.Pp
|
||||||
A prefix of the form
|
A prefix of the form
|
||||||
.Ql s/foo/bar/:\&
|
.Ql s/foo/bar/:\&
|
||||||
will substitute
|
will substitute
|
||||||
@ -5934,6 +5953,10 @@ option should be used.
|
|||||||
An existing extension that tells
|
An existing extension that tells
|
||||||
.Nm
|
.Nm
|
||||||
the terminal supports default colours.
|
the terminal supports default colours.
|
||||||
|
.It Em \&Bidi
|
||||||
|
Tell
|
||||||
|
.Nm
|
||||||
|
that the terminal supports the VTE bidirectional text extensions.
|
||||||
.It Em \&Cs , Cr
|
.It Em \&Cs , Cr
|
||||||
Set the cursor colour.
|
Set the cursor colour.
|
||||||
The first takes a single string argument and is used to set the colour;
|
The first takes a single string argument and is used to set the colour;
|
||||||
|
1
tmux.h
1
tmux.h
@ -262,6 +262,7 @@ enum tty_code_code {
|
|||||||
TTYC_AX,
|
TTYC_AX,
|
||||||
TTYC_BCE,
|
TTYC_BCE,
|
||||||
TTYC_BEL,
|
TTYC_BEL,
|
||||||
|
TTYC_BIDI,
|
||||||
TTYC_BLINK,
|
TTYC_BLINK,
|
||||||
TTYC_BOLD,
|
TTYC_BOLD,
|
||||||
TTYC_CIVIS,
|
TTYC_CIVIS,
|
||||||
|
@ -61,6 +61,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
|
|||||||
[TTYC_AX] = { TTYCODE_FLAG, "AX" },
|
[TTYC_AX] = { TTYCODE_FLAG, "AX" },
|
||||||
[TTYC_BCE] = { TTYCODE_FLAG, "bce" },
|
[TTYC_BCE] = { TTYCODE_FLAG, "bce" },
|
||||||
[TTYC_BEL] = { TTYCODE_STRING, "bel" },
|
[TTYC_BEL] = { TTYCODE_STRING, "bel" },
|
||||||
|
[TTYC_BIDI] = { TTYCODE_STRING, "Bidi" },
|
||||||
[TTYC_BLINK] = { TTYCODE_STRING, "blink" },
|
[TTYC_BLINK] = { TTYCODE_STRING, "blink" },
|
||||||
[TTYC_BOLD] = { TTYCODE_STRING, "bold" },
|
[TTYC_BOLD] = { TTYCODE_STRING, "bold" },
|
||||||
[TTYC_CIVIS] = { TTYCODE_STRING, "civis" },
|
[TTYC_CIVIS] = { TTYCODE_STRING, "civis" },
|
||||||
|
Loading…
Reference in New Issue
Block a user