summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2021-02-05 14:01:23 +0000
committerThomas Adam <thomas@xteddy.org>2021-02-05 14:01:23 +0000
commit39904f7fc6e64356fe23de6264d5b03bec280d75 (patch)
tree0794a32b596d10982f8987453b08f3578a18858a
parente3d71d9bdfa31fb658794759f07af43d53253e5f (diff)
parent3dddc11603b1bd66b5586b47795716e87921a096 (diff)
Merge branch 'obsd-master' into master
-rw-r--r--cmd-new-window.c38
-rw-r--r--format.c61
-rw-r--r--grid.c4
-rw-r--r--screen-redraw.c24
-rw-r--r--tmux.125
-rw-r--r--tmux.h1
-rw-r--r--tty-term.c1
7 files changed, 141 insertions, 13 deletions
diff --git a/cmd-new-window.c b/cmd-new-window.c
index ca3e66c4..712e2a79 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -38,8 +38,8 @@ const struct cmd_entry cmd_new_window_entry = {
.name = "new-window",
.alias = "neww",
- .args = { "abc:de:F:kn:Pt:", 0, -1 },
- .usage = "[-abdkP] [-c start-directory] [-e environment] [-F format] "
+ .args = { "abc:de:F:kn:PSt:", 0, -1 },
+ .usage = "[-abdkPS] [-c start-directory] [-e environment] [-F format] "
"[-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]",
.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)
{
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 *target = cmdq_get_target(item);
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 winlink *wl = target->wl;
int idx = target->idx, before;
- struct winlink *new_wl;
+ struct winlink *new_wl = NULL;
char *cause = NULL, *cp;
- const char *template, *add;
+ const char *template, *add, *name;
struct cmd_find_state fs;
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');
if (args_has(args, 'a') || before) {
idx = winlink_shuffle_up(s, wl, before);
diff --git a/format.c b/format.c
index c2b9df21..de11fc8b 100644
--- a/format.c
+++ b/format.c
@@ -100,6 +100,8 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
#define FORMAT_LENGTH 0x800
#define FORMAT_WIDTH 0x1000
#define FORMAT_QUOTE_STYLE 0x2000
+#define FORMAT_WINDOW_NAME 0x4000
+#define FORMAT_SESSION_NAME 0x8000
/* Limit on recursion. */
#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. */
- if (strchr("mCst=peq", cp[0]) == NULL)
+ if (strchr("mCNst=peq", cp[0]) == NULL)
break;
c = cp[0];
@@ -1857,6 +1859,24 @@ format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
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. */
static char *
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);
}
+/* 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. */
static char *
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':
modifiers |= FORMAT_EXPANDTIME;
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':
modifiers |= FORMAT_SESSIONS;
break;
@@ -2291,6 +2342,14 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
value = format_loop_panes(es, copy);
if (value == NULL)
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) {
/* Search in pane. */
new = format_expand1(es, copy);
diff --git a/grid.c b/grid.c
index 3eeb7a27..1822f2b5 100644
--- a/grid.c
+++ b/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);
} else
dstl->celldata = NULL;
-
if (srcl->extdsize != 0) {
dstl->extdsize = srcl->extdsize;
dstl->extddata = xreallocarray(NULL, dstl->extdsize,
sizeof *dstl->extddata);
memcpy(dstl->extddata, srcl->extddata, dstl->extdsize *
sizeof *dstl->extddata);
- }
+ } else
+ dstl->extddata = NULL;
sy++;
dy++;
diff --git a/screen-redraw.c b/screen-redraw.c
index 47c1a838..6ddabc52 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -32,8 +32,8 @@ static void screen_redraw_set_context(struct client *,
struct screen_redraw_ctx *);
#define CELL_INSIDE 0
-#define CELL_LEFTRIGHT 1
-#define CELL_TOPBOTTOM 2
+#define CELL_TOPBOTTOM 1
+#define CELL_LEFTRIGHT 2
#define CELL_TOPLEFT 3
#define CELL_TOPRIGHT 4
#define CELL_BOTTOMLEFT 5
@@ -47,6 +47,9 @@ static void screen_redraw_set_context(struct client *,
#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[] = {
{ "", 0, 0, 0 },
{ "\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 */
return (CELL_TOPJOIN);
case 12: /* 1100, left right */
- return (CELL_TOPBOTTOM);
+ return (CELL_LEFTRIGHT);
case 11: /* 1011, left top bottom */
return (CELL_RIGHTJOIN);
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 */
return (CELL_TOPLEFT);
case 3: /* 0011, top bottom */
- return (CELL_LEFTRIGHT);
+ return (CELL_TOPBOTTOM);
}
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 window_pane *wp;
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;
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);
+ if (cell_type == CELL_TOPBOTTOM &&
+ (c->flags & CLIENT_UTF8) &&
+ tty_term_has(tty->term, TTYC_BIDI))
+ isolates = 1;
+ else
+ isolates = 0;
+
if (ctx->statustop)
tty_cursor(tty, i, ctx->statuslines + j);
else
tty_cursor(tty, i, j);
+ if (isolates)
+ tty_puts(tty, END_ISOLATE);
tty_cell(tty, &gc, &grid_default_cell, NULL);
+ if (isolates)
+ tty_puts(tty, START_ISOLATE);
}
/* Draw the borders. */
diff --git a/tmux.1 b/tmux.1
index f5988c42..9f617c76 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2348,7 +2348,7 @@ the
.Ic base-index
option.
.It Xo Ic new-window
-.Op Fl abdkP
+.Op Fl abdkPS
.Op Fl c Ar start-directory
.Op Fl e Ar environment
.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
.Fl k
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
is the command to execute.
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} }
.Ed
.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
.Ql s/foo/bar/:\&
will substitute
@@ -5934,6 +5953,10 @@ option should be used.
An existing extension that tells
.Nm
the terminal supports default colours.
+.It Em \&Bidi
+Tell
+.Nm
+that the terminal supports the VTE bidirectional text extensions.
.It Em \&Cs , Cr
Set the cursor colour.
The first takes a single string argument and is used to set the colour;
diff --git a/tmux.h b/tmux.h
index 885492f7..3c496ae0 100644
--- a/tmux.h
+++ b/tmux.h
@@ -262,6 +262,7 @@ enum tty_code_code {
TTYC_AX,
TTYC_BCE,
TTYC_BEL,
+ TTYC_BIDI,
TTYC_BLINK,
TTYC_BOLD,
TTYC_CIVIS,
diff --git a/tty-term.c b/tty-term.c
index ec8302a6..ad6a5567 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -61,6 +61,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_AX] = { TTYCODE_FLAG, "AX" },
[TTYC_BCE] = { TTYCODE_FLAG, "bce" },
[TTYC_BEL] = { TTYCODE_STRING, "bel" },
+ [TTYC_BIDI] = { TTYCODE_STRING, "Bidi" },
[TTYC_BLINK] = { TTYCODE_STRING, "blink" },
[TTYC_BOLD] = { TTYCODE_STRING, "bold" },
[TTYC_CIVIS] = { TTYCODE_STRING, "civis" },