diff --git a/arguments.c b/arguments.c index e2d18980..e9af70ac 100644 --- a/arguments.c +++ b/arguments.c @@ -343,3 +343,53 @@ args_strtonum(struct args *args, u_char ch, long long minval, long long maxval, *cause = NULL; return (ll); } + +/* Convert an argument to a number which may be a percentage. */ +long long +args_percentage(struct args *args, u_char ch, long long minval, + long long maxval, long long curval, char **cause) +{ + const char *errstr; + long long ll; + struct args_entry *entry; + struct args_value *value; + size_t valuelen; + char *copy; + + if ((entry = args_find(args, ch)) == NULL) { + *cause = xstrdup("missing"); + return (0); + } + value = TAILQ_LAST(&entry->values, args_values); + valuelen = strlen(value->value); + + if (value->value[valuelen - 1] == '%') { + copy = xstrdup(value->value); + copy[valuelen - 1] = '\0'; + + ll = strtonum(copy, 0, 100, &errstr); + free(copy); + if (errstr != NULL) { + *cause = xstrdup(errstr); + return (0); + } + ll = (curval * ll) / 100; + if (ll < minval) { + *cause = xstrdup("too large"); + return (0); + } + if (ll > maxval) { + *cause = xstrdup("too small"); + return (0); + } + } else { + ll = strtonum(value->value, minval, maxval, &errstr); + if (errstr != NULL) { + *cause = xstrdup(errstr); + return (0); + } + } + + *cause = NULL; + return (ll); +} diff --git a/cmd-join-pane.c b/cmd-join-pane.c index 4b767e3e..788f003a 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -50,7 +50,7 @@ const struct cmd_entry cmd_move_pane_entry = { .alias = "movep", .args = { "bdhvp:l:s:t:", 0, 0 }, - .usage = "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE, + .usage = "[-bdhv] [-l size] " CMD_SRCDST_PANE_USAGE, .source = { 's', CMD_FIND_PANE, CMD_FIND_DEFAULT_MARKED }, .target = { 't', CMD_FIND_PANE, 0 }, @@ -68,9 +68,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) struct winlink *src_wl, *dst_wl; struct window *src_w, *dst_w; struct window_pane *src_wp, *dst_wp; - char *cause, *copy; - const char *errstr, *p; - size_t plen; + char *cause = NULL; int size, percentage, dst_idx, not_same_window; int flags; enum layout_type type; @@ -107,40 +105,27 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) type = LAYOUT_LEFTRIGHT; size = -1; - 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, 'l')) { + if (type == LAYOUT_TOPBOTTOM) { + size = args_percentage(args, 'l', 0, INT_MAX, + dst_wp->sy, &cause); + } 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; else size = (dst_wp->sx * percentage) / 100; - } else { - size = args_strtonum(args, 'l', 0, INT_MAX, &cause); - if (cause != NULL) { - cmdq_error(item, "size %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } } - } else if (args_has(args, 'p')) { - percentage = args_strtonum(args, 'p', 0, 100, &cause); - if (cause != NULL) { - cmdq_error(item, "percentage %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } - if (type == LAYOUT_TOPBOTTOM) - size = (dst_wp->sy * percentage) / 100; - else - size = (dst_wp->sx * percentage) / 100; + } + if (cause != NULL) { + cmdq_error(item, "size %s", cause); + free(cause); + return (CMD_RETURN_ERROR); } flags = 0; diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index 3962546d..b0aa2756 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -56,11 +56,10 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) struct window *w = wl->window; struct client *c = item->client; struct session *s = item->target.s; - const char *errstr, *p; - char *cause, *copy; + const char *errstr; + char *cause; u_int adjust; - int x, y, percentage; - size_t plen; + int x, y; if (args_has(args, 'M')) { if (cmd_mouse_window(&shared->mouse, &s) == NULL) @@ -93,58 +92,21 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) } } - if ((p = args_get(args, 'x')) != 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, "width %s", errstr); - return (CMD_RETURN_ERROR); - } - x = (w->sx * percentage) / 100; - if (x < PANE_MINIMUM) - x = PANE_MINIMUM; - if (x > INT_MAX) - x = INT_MAX; - } else { - x = args_strtonum(args, 'x', PANE_MINIMUM, INT_MAX, - &cause); - if (cause != NULL) { - cmdq_error(item, "width %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } + if (args_has(args, 'x')) { + x = args_percentage(args, 'x', 0, INT_MAX, w->sx, &cause); + if (cause != NULL) { + cmdq_error(item, "width %s", cause); + free(cause); + return (CMD_RETURN_ERROR); } layout_resize_pane_to(wp, LAYOUT_LEFTRIGHT, x); } - if ((p = args_get(args, 'y')) != 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, "height %s", errstr); - return (CMD_RETURN_ERROR); - } - y = (w->sy * percentage) / 100; - if (y < PANE_MINIMUM) - y = PANE_MINIMUM; - if (y > INT_MAX) - y = INT_MAX; - } - else { - y = args_strtonum(args, 'y', PANE_MINIMUM, INT_MAX, - &cause); - if (cause != NULL) { - cmdq_error(item, "height %s", cause); - free(cause); - return (CMD_RETURN_ERROR); - } + if (args_has(args, 'y')) { + y = args_percentage(args, 'y', 0, INT_MAX, w->sy, &cause); + if (cause != NULL) { + cmdq_error(item, "width %s", cause); + free(cause); + return (CMD_RETURN_ERROR); } layout_resize_pane_to(wp, LAYOUT_TOPBOTTOM, y); } diff --git a/cmd-run-shell.c b/cmd-run-shell.c index 1cf97d51..a57beb83 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -160,6 +160,7 @@ cmd_run_shell_callback(struct job *job) { struct cmd_run_shell_data *cdata = job_get_data(job); struct bufferevent *event = job_get_event(job); + struct cmdq_item *item = cdata->item; char *cmd = cdata->cmd, *msg = NULL, *line; size_t size; int retcode, status; @@ -189,13 +190,17 @@ cmd_run_shell_callback(struct job *job) } else if (WIFSIGNALED(status)) { retcode = WTERMSIG(status); xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); + retcode += 128; } if (msg != NULL) cmd_run_shell_print(job, msg); free(msg); - if (cdata->item != NULL) - cmdq_continue(cdata->item); + if (item != NULL) { + if (item->client != NULL && item->client->session == NULL) + item->client->retval = retcode; + cmdq_continue(item); + } } static void diff --git a/tmux.h b/tmux.h index b9817c24..a522c709 100644 --- a/tmux.h +++ b/tmux.h @@ -2062,6 +2062,8 @@ const char *args_first_value(struct args *, u_char, struct args_value **); const char *args_next_value(struct args_value **); long long args_strtonum(struct args *, u_char, long long, long long, char **); +long long args_percentage(struct args *, u_char, long long, + long long, long long, char **); /* cmd-find.c */ int cmd_find_target(struct cmd_find_state *, struct cmdq_item *, diff --git a/window-copy.c b/window-copy.c index 53faa5a8..eeed210d 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1566,12 +1566,12 @@ window_copy_cmd_select_line(struct window_copy_cmd_state *cs) window_copy_cursor_start_of_line(wme); data->selrx = data->cx; data->selry = screen_hsize(data->backing) + data->cy - data->oy; + data->endselrx = window_copy_find_length(wme, data->selry); + data->endselry = data->selry; window_copy_start_selection(wme); for (; np > 1; np--) window_copy_cursor_down(wme, 0); window_copy_cursor_end_of_line(wme); - data->endselrx = data->cx; - data->endselry = screen_hsize(data->backing) + data->cy - data->oy; return (WINDOW_COPY_CMD_REDRAW); }