aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arguments.c102
-rw-r--r--cmd-capture-pane.c6
-rw-r--r--cmd-choose-tree.c2
-rw-r--r--cmd-join-pane.c36
-rw-r--r--cmd-load-buffer.c2
-rw-r--r--cmd-send-keys.c3
-rw-r--r--cmd-set-buffer.c16
-rw-r--r--cmd-split-window.c79
-rw-r--r--configure.ac2
-rw-r--r--input.c11
-rw-r--r--paste.c8
-rw-r--r--screen-write.c4
-rw-r--r--tmux.h13
-rw-r--r--tty-keys.c2
-rw-r--r--tty.c9
-rw-r--r--window-copy.c4
16 files changed, 216 insertions, 83 deletions
diff --git a/arguments.c b/arguments.c
index d0dc2d4d..46777f7f 100644
--- a/arguments.c
+++ b/arguments.c
@@ -848,6 +848,41 @@ args_strtonum(struct args *args, u_char flag, long long minval,
return (ll);
}
+/* Convert an argument value to a number, and expand formats. */
+long long
+args_strtonum_and_expand(struct args *args, u_char flag, long long minval,
+ long long maxval, struct cmdq_item *item, char **cause)
+{
+ const char *errstr;
+ char *formatted;
+ long long ll;
+ struct args_entry *entry;
+ struct args_value *value;
+
+ if ((entry = args_find(args, flag)) == NULL) {
+ *cause = xstrdup("missing");
+ return (0);
+ }
+ value = TAILQ_LAST(&entry->values, args_values);
+ if (value == NULL ||
+ value->type != ARGS_STRING ||
+ value->string == NULL) {
+ *cause = xstrdup("missing");
+ return (0);
+ }
+
+ formatted = format_single_from_target(item, value->string);
+ ll = strtonum(formatted, minval, maxval, &errstr);
+ free(formatted);
+ if (errstr != NULL) {
+ *cause = xstrdup(errstr);
+ return (0);
+ }
+
+ *cause = NULL;
+ return (ll);
+}
+
/* Convert an argument to a number which may be a percentage. */
long long
args_percentage(struct args *args, u_char flag, long long minval,
@@ -904,3 +939,70 @@ args_string_percentage(const char *value, long long minval, long long maxval,
*cause = NULL;
return (ll);
}
+
+/*
+ * Convert an argument to a number which may be a percentage, and expand
+ * formats.
+ */
+long long
+args_percentage_and_expand(struct args *args, u_char flag, long long minval,
+ long long maxval, long long curval, struct cmdq_item *item, char **cause)
+{
+ const char *value;
+ struct args_entry *entry;
+
+ if ((entry = args_find(args, flag)) == NULL) {
+ *cause = xstrdup("missing");
+ return (0);
+ }
+ value = TAILQ_LAST(&entry->values, args_values)->string;
+ return (args_string_percentage_and_expand(value, minval, maxval, curval,
+ item, cause));
+}
+
+/*
+ * Convert a string to a number which may be a percentage, and expand formats.
+ */
+long long
+args_string_percentage_and_expand(const char *value, long long minval,
+ long long maxval, long long curval, struct cmdq_item *item, char **cause)
+{
+ const char *errstr;
+ long long ll;
+ size_t valuelen = strlen(value);
+ char *copy, *f;
+
+ if (value[valuelen - 1] == '%') {
+ copy = xstrdup(value);
+ copy[valuelen - 1] = '\0';
+
+ f = format_single_from_target(item, copy);
+ ll = strtonum(f, 0, 100, &errstr);
+ free(f);
+ free(copy);
+ if (errstr != NULL) {
+ *cause = xstrdup(errstr);
+ return (0);
+ }
+ ll = (curval * ll) / 100;
+ if (ll < minval) {
+ *cause = xstrdup("too small");
+ return (0);
+ }
+ if (ll > maxval) {
+ *cause = xstrdup("too large");
+ return (0);
+ }
+ } else {
+ f = format_single_from_target(item, value);
+ ll = strtonum(f, minval, maxval, &errstr);
+ free(f);
+ if (errstr != NULL) {
+ *cause = xstrdup(errstr);
+ return (0);
+ }
+ }
+
+ *cause = NULL;
+ return (ll);
+}
diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index 964f831e..a3e84c46 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -133,7 +133,8 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
if (Sflag != NULL && strcmp(Sflag, "-") == 0)
top = 0;
else {
- n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
+ n = args_strtonum_and_expand(args, 'S', INT_MIN, SHRT_MAX,
+ item, &cause);
if (cause != NULL) {
top = gd->hsize;
free(cause);
@@ -149,7 +150,8 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
if (Eflag != NULL && strcmp(Eflag, "-") == 0)
bottom = gd->hsize + gd->sy - 1;
else {
- n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause);
+ n = args_strtonum_and_expand(args, 'E', INT_MIN, SHRT_MAX,
+ item, &cause);
if (cause != NULL) {
bottom = gd->hsize + gd->sy - 1;
free(cause);
diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c
index 7aa1d217..f2f4b2e3 100644
--- a/cmd-choose-tree.c
+++ b/cmd-choose-tree.c
@@ -100,7 +100,7 @@ cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item)
const struct window_mode *mode;
if (cmd_get_entry(self) == &cmd_choose_buffer_entry) {
- if (paste_get_top(NULL) == NULL)
+ if (paste_is_empty())
return (CMD_RETURN_NORMAL);
mode = &window_buffer_mode;
} else if (cmd_get_entry(self) == &cmd_choose_client_entry) {
diff --git a/cmd-join-pane.c b/cmd-join-pane.c
index cb3fb343..e82b4cde 100644
--- a/cmd-join-pane.c
+++ b/cmd-join-pane.c
@@ -71,10 +71,11 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
struct window *src_w, *dst_w;
struct window_pane *src_wp, *dst_wp;
char *cause = NULL;
- int size, percentage, dst_idx;
+ int size, dst_idx;
int flags;
enum layout_type type;
struct layout_cell *lc;
+ u_int curval = 0;
dst_s = target->s;
dst_wl = target->wl;
@@ -97,24 +98,31 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'h'))
type = LAYOUT_LEFTRIGHT;
- size = -1;
- if (args_has(args, 'l')) {
- if (type == LAYOUT_TOPBOTTOM) {
- size = args_percentage(args, 'l', 0, INT_MAX,
- dst_wp->sy, &cause);
+ /* If the 'p' flag is dropped then this bit can be moved into 'l'. */
+ if (args_has(args, 'l') || args_has(args, 'p')) {
+ if (args_has(args, 'f')) {
+ if (type == LAYOUT_TOPBOTTOM)
+ curval = dst_w->sy;
+ else
+ curval = dst_w->sx;
} else {
- size = args_percentage(args, 'l', 0, INT_MAX,
- dst_wp->sx, &cause);
- }
- } else if (args_has(args, 'p')) {
- percentage = args_strtonum(args, 'p', 0, 100, &cause);
- if (cause == NULL) {
if (type == LAYOUT_TOPBOTTOM)
- size = (dst_wp->sy * percentage) / 100;
+ curval = dst_wp->sy;
else
- size = (dst_wp->sx * percentage) / 100;
+ curval = dst_wp->sx;
}
}
+
+ size = -1;
+ if (args_has(args, 'l')) {
+ size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
+ item, &cause);
+ } else if (args_has(args, 'p')) {
+ size = args_strtonum_and_expand(args, 'l', 0, 100, item,
+ &cause);
+ if (cause == NULL)
+ size = curval * size / 100;
+ }
if (cause != NULL) {
cmdq_error(item, "size %s", cause);
free(cause);
diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c
index 59810dea..70fd7ed9 100644
--- a/cmd-load-buffer.c
+++ b/cmd-load-buffer.c
@@ -77,7 +77,7 @@ cmd_load_buffer_done(__unused struct client *c, const char *path, int error,
} else if (tc != NULL &&
tc->session != NULL &&
(~tc->flags & CLIENT_DEAD))
- tty_set_selection(&tc->tty, copy, bsize);
+ tty_set_selection(&tc->tty, "", copy, bsize);
if (tc != NULL)
server_client_unref(tc);
}
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index d6a95434..e22d94a6 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -151,7 +151,8 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
char *cause = NULL;
if (args_has(args, 'N')) {
- np = args_strtonum(args, 'N', 1, UINT_MAX, &cause);
+ np = args_strtonum_and_expand(args, 'N', 1, UINT_MAX, item,
+ &cause);
if (cause != NULL) {
cmdq_error(item, "repeat count %s", cause);
free(cause);
diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c
index 9112683f..35e72955 100644
--- a/cmd-set-buffer.c
+++ b/cmd-set-buffer.c
@@ -69,8 +69,13 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
pb = paste_get_name(bufname);
if (cmd_get_entry(self) == &cmd_delete_buffer_entry) {
- if (pb == NULL)
+ if (pb == NULL) {
+ if (bufname != NULL) {
+ cmdq_error(item, "unknown buffer: %s", bufname);
+ return (CMD_RETURN_ERROR);
+ }
pb = paste_get_top(&bufname);
+ }
if (pb == NULL) {
cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR);
@@ -80,8 +85,13 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
}
if (args_has(args, 'n')) {
- if (pb == NULL)
+ if (pb == NULL) {
+ if (bufname != NULL) {
+ cmdq_error(item, "unknown buffer: %s", bufname);
+ return (CMD_RETURN_ERROR);
+ }
pb = paste_get_top(&bufname);
+ }
if (pb == NULL) {
cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR);
@@ -121,7 +131,7 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR);
}
if (args_has(args, 'w') && tc != NULL)
- tty_set_selection(&tc->tty, bufdata, bufsize);
+ tty_set_selection(&tc->tty, "", bufdata, bufsize);
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-split-window.c b/cmd-split-window.c
index 9947dfd3..637bad30 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -65,67 +65,46 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
enum layout_type type;
struct layout_cell *lc;
struct cmd_find_state fs;
- int size, percentage, flags, input;
- const char *template, *errstr, *p;
- char *cause, *cp, *copy;
- size_t plen;
+ int size, flags, input;
+ const char *template;
+ char *cause = NULL, *cp;
struct args_value *av;
- u_int count = args_count(args);
+ u_int count = args_count(args), curval = 0;
+ type = LAYOUT_TOPBOTTOM;
if (args_has(args, 'h'))
type = LAYOUT_LEFTRIGHT;
- else
- type = LAYOUT_TOPBOTTOM;
- if ((p = args_get(args, 'l')) != NULL) {
- plen = strlen(p);
- if (p[plen - 1] == '%') {
- copy = xstrdup(p);
- copy[plen - 1] = '\0';
- percentage = strtonum(copy, 0, INT_MAX, &errstr);
- free(copy);
- if (errstr != NULL) {
- cmdq_error(item, "percentage %s", errstr);
- return (CMD_RETURN_ERROR);
- }
- if (args_has(args, 'f')) {
- if (type == LAYOUT_TOPBOTTOM)
- size = (w->sy * percentage) / 100;
- else
- size = (w->sx * percentage) / 100;
- } else {
- if (type == LAYOUT_TOPBOTTOM)
- size = (wp->sy * percentage) / 100;
- else
- size = (wp->sx * percentage) / 100;
- }
- } else {
- size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
- if (cause != NULL) {
- cmdq_error(item, "lines %s", cause);
- free(cause);
- return (CMD_RETURN_ERROR);
- }
- }
- } else if (args_has(args, 'p')) {
- percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
- if (cause != NULL) {
- cmdq_error(item, "create pane failed: -p %s", cause);
- free(cause);
- return (CMD_RETURN_ERROR);
- }
+
+ /* If the 'p' flag is dropped then this bit can be moved into 'l'. */
+ if (args_has(args, 'l') || args_has(args, 'p')) {
if (args_has(args, 'f')) {
if (type == LAYOUT_TOPBOTTOM)
- size = (w->sy * percentage) / 100;
+ curval = w->sy;
else
- size = (w->sx * percentage) / 100;
+ curval = w->sx;
} else {
if (type == LAYOUT_TOPBOTTOM)
- size = (wp->sy * percentage) / 100;
+ curval = wp->sy;
else
- size = (wp->sx * percentage) / 100;
+ curval = wp->sx;
}
- } else
- size = -1;
+ }
+
+ size = -1;
+ if (args_has(args, 'l')) {
+ size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
+ item, &cause);
+ } else if (args_has(args, 'p')) {
+ size = args_strtonum_and_expand(args, 'l', 0, 100, item,
+ &cause);
+ if (cause == NULL)
+ size = curval * size / 100;
+ }
+ if (cause != NULL) {
+ cmdq_error(item, "size %s", cause);
+ free(cause);
+ return (CMD_RETURN_ERROR);
+ }
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
input = (args_has(args, 'I') && count == 0);
diff --git a/configure.ac b/configure.ac
index 2b8b3b11..276f71c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
# configure.ac
-AC_INIT([tmux], 3.3a)
+AC_INIT([tmux], next-3.4)
AC_PREREQ([2.60])
AC_CONFIG_AUX_DIR(etc)
diff --git a/input.c b/input.c
index 693b6f32..fa9dfcdf 100644
--- a/input.c
+++ b/input.c
@@ -2693,6 +2693,9 @@ input_osc_52(struct input_ctx *ictx, const char *p)
int outlen, state;
struct screen_write_ctx ctx;
struct paste_buffer *pb;
+ const char* allow = "cpqs01234567";
+ char flags[sizeof allow] = "";
+ u_int i, j = 0;
if (wp == NULL)
return;
@@ -2707,6 +2710,12 @@ input_osc_52(struct input_ctx *ictx, const char *p)
return;
log_debug("%s: %s", __func__, end);
+ for (i = 0; p + i != end; i++) {
+ if (strchr(allow, p[i]) != NULL && strchr(flags, p[i]) == NULL)
+ flags[j++] = p[i];
+ }
+ log_debug("%s: %.*s %s", __func__, (int)(end - p - 1), p, flags);
+
if (strcmp(end, "?") == 0) {
if ((pb = paste_get_top(NULL)) != NULL)
buf = paste_buffer_data(pb, &len);
@@ -2728,7 +2737,7 @@ input_osc_52(struct input_ctx *ictx, const char *p)
}
screen_write_start_pane(&ctx, wp, NULL);
- screen_write_setselection(&ctx, out, outlen);
+ screen_write_setselection(&ctx, flags, out, outlen);
screen_write_stop(&ctx);
notify_pane("pane-set-clipboard", wp);
diff --git a/paste.c b/paste.c
index 51ae2b1d..ad9d71e5 100644
--- a/paste.c
+++ b/paste.c
@@ -111,6 +111,12 @@ paste_walk(struct paste_buffer *pb)
return (RB_NEXT(paste_time_tree, &paste_by_time, pb));
}
+int
+paste_is_empty(void)
+{
+ return RB_ROOT(&paste_by_time) == NULL;
+}
+
/* Get the most recent automatic buffer. */
struct paste_buffer *
paste_get_top(const char **name)
@@ -118,6 +124,8 @@ paste_get_top(const char **name)
struct paste_buffer *pb;
pb = RB_MIN(paste_time_tree, &paste_by_time);
+ while (pb != NULL && !pb->automatic)
+ pb = RB_NEXT(paste_time_tree, &paste_by_time, pb);
if (pb == NULL)
return (NULL);
if (name != NULL)
diff --git a/screen-write.c b/screen-write.c
index 6b6a750e..213b533c 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -2085,12 +2085,14 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc,
/* Set external clipboard. */
void
-screen_write_setselection(struct screen_write_ctx *ctx, u_char *str, u_int len)
+screen_write_setselection(struct screen_write_ctx *ctx, const char *flags,
+ u_char *str, u_int len)
{
struct tty_ctx ttyctx;
screen_write_initctx(ctx, &ttyctx, 0);
ttyctx.ptr = str;
+ ttyctx.ptr2 = (void *)flags;
ttyctx.num = len;
tty_write(tty_cmd_setselection, &ttyctx);
diff --git a/tmux.h b/tmux.h
index 53084b8b..c8061da5 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1422,6 +1422,7 @@ struct tty_ctx {
u_int num;
void *ptr;
+ void *ptr2;
/*
* Cursor and region position before the screen was updated - this is
@@ -2058,6 +2059,7 @@ u_int paste_buffer_order(struct paste_buffer *);
time_t paste_buffer_created(struct paste_buffer *);
const char *paste_buffer_data(struct paste_buffer *, size_t *);
struct paste_buffer *paste_walk(struct paste_buffer *);
+int paste_is_empty(void);
struct paste_buffer *paste_get_top(const char **);
struct paste_buffer *paste_get_name(const char *);
void paste_free(struct paste_buffer *);
@@ -2278,7 +2280,7 @@ int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
void tty_update_features(struct tty *);
-void tty_set_selection(struct tty *, const char *, size_t);
+void tty_set_selection(struct tty *, const char *, const char *, size_t);
void tty_write(void (*)(struct tty *, const struct tty_ctx *),
struct tty_ctx *);
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
@@ -2383,10 +2385,16 @@ struct args_value *args_first_value(struct args *, u_char);
struct args_value *args_next_value(struct args_value *);
long long args_strtonum(struct args *, u_char, long long, long long,
char **);
+long long args_strtonum_and_expand(struct args *, u_char, long long,
+ long long, struct cmdq_item *, char **);
long long args_percentage(struct args *, u_char, long long,
long long, long long, char **);
long long args_string_percentage(const char *, long long, long long,
long long, char **);
+long long args_percentage_and_expand(struct args *, u_char, long long,
+ long long, long long, struct cmdq_item *, char **);
+long long args_string_percentage_and_expand(const char *, long long,
+ long long, long long, struct cmdq_item *, char **);
/* cmd-find.c */
int cmd_find_target(struct cmd_find_state *, struct cmdq_item *,
@@ -2867,7 +2875,8 @@ void screen_write_collect_end(struct screen_write_ctx *);
void screen_write_collect_add(struct screen_write_ctx *,
const struct grid_cell *);
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
-void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
+void screen_write_setselection(struct screen_write_ctx *, const char *,
+ u_char *, u_int);
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
void screen_write_alternateon(struct screen_write_ctx *,
struct grid_cell *, int);
diff --git a/tty-keys.c b/tty-keys.c
index 64dd91bb..d26dbf1e 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -798,6 +798,8 @@ partial_key:
/* Get the time period. */
delay = options_get_number(global_options, "escape-time");
+ if (delay == 0)
+ delay = 1;
tv.tv_sec = delay / 1000;
tv.tv_usec = (delay % 1000) * 1000L;
diff --git a/tty.c b/tty.c
index 49cf9795..7e0a6a3e 100644
--- a/tty.c
+++ b/tty.c
@@ -671,7 +671,7 @@ static void
tty_force_cursor_colour(struct tty *tty, int c)
{
u_char r, g, b;
- char s[13] = "";
+ char s[13];
if (c != -1)
c = colour_force_rgb(c);
@@ -2082,11 +2082,12 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_set_selection(tty, ctx->ptr, ctx->num);
+ tty_set_selection(tty, ctx->ptr2, ctx->ptr, ctx->num);
}
void
-tty_set_selection(struct tty *tty, const char *buf, size_t len)
+tty_set_selection(struct tty *tty, const char *flags, const char *buf,
+ size_t len)
{
char *encoded;
size_t size;
@@ -2101,7 +2102,7 @@ tty_set_selection(struct tty *tty, const char *buf, size_t len)
b64_ntop(buf, len, encoded, size);
tty->flags |= TTY_NOBLOCK;
- tty_putcode_ptr2(tty, TTYC_MS, "", encoded);
+ tty_putcode_ptr2(tty, TTYC_MS, flags, encoded);
free(encoded);
}
diff --git a/window-copy.c b/window-copy.c
index 03070556..09304218 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -4570,7 +4570,7 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix,
if (options_get_number(global_options, "set-clipboard") != 0) {
screen_write_start_pane(&ctx, wp, NULL);
- screen_write_setselection(&ctx, buf, len);
+ screen_write_setselection(&ctx, "", buf, len);
screen_write_stop(&ctx);
notify_pane("pane-set-clipboard", wp);
}
@@ -4644,7 +4644,7 @@ window_copy_append_selection(struct window_mode_entry *wme)
if (options_get_number(global_options, "set-clipboard") != 0) {
screen_write_start_pane(&ctx, wp, NULL);
- screen_write_setselection(&ctx, buf, len);
+ screen_write_setselection(&ctx, "", buf, len);
screen_write_stop(&ctx);
notify_pane("pane-set-clipboard", wp);
}