diff options
-rw-r--r-- | arguments.c | 102 | ||||
-rw-r--r-- | cmd-capture-pane.c | 6 | ||||
-rw-r--r-- | cmd-choose-tree.c | 2 | ||||
-rw-r--r-- | cmd-join-pane.c | 36 | ||||
-rw-r--r-- | cmd-load-buffer.c | 2 | ||||
-rw-r--r-- | cmd-send-keys.c | 3 | ||||
-rw-r--r-- | cmd-set-buffer.c | 16 | ||||
-rw-r--r-- | cmd-split-window.c | 79 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | input.c | 11 | ||||
-rw-r--r-- | paste.c | 8 | ||||
-rw-r--r-- | screen-write.c | 4 | ||||
-rw-r--r-- | tmux.h | 13 | ||||
-rw-r--r-- | tty-keys.c | 2 | ||||
-rw-r--r-- | tty.c | 9 | ||||
-rw-r--r-- | window-copy.c | 4 |
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) @@ -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); @@ -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); @@ -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); @@ -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; @@ -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); } |