mirror of
https://github.com/tmux/tmux.git
synced 2024-11-17 18:08:51 +00:00
Expand arguments to some commands where it makes sense, GitHub issue
3204 from Anindya Mukherjee.
This commit is contained in:
parent
020c403dff
commit
c07d582e24
102
arguments.c
102
arguments.c
@ -848,6 +848,41 @@ args_strtonum(struct args *args, u_char flag, long long minval,
|
|||||||
return (ll);
|
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. */
|
/* Convert an argument to a number which may be a percentage. */
|
||||||
long long
|
long long
|
||||||
args_percentage(struct args *args, u_char flag, long long minval,
|
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;
|
*cause = NULL;
|
||||||
return (ll);
|
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);
|
||||||
|
}
|
||||||
|
@ -133,7 +133,8 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
|
|||||||
if (Sflag != NULL && strcmp(Sflag, "-") == 0)
|
if (Sflag != NULL && strcmp(Sflag, "-") == 0)
|
||||||
top = 0;
|
top = 0;
|
||||||
else {
|
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) {
|
if (cause != NULL) {
|
||||||
top = gd->hsize;
|
top = gd->hsize;
|
||||||
free(cause);
|
free(cause);
|
||||||
@ -149,7 +150,8 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
|
|||||||
if (Eflag != NULL && strcmp(Eflag, "-") == 0)
|
if (Eflag != NULL && strcmp(Eflag, "-") == 0)
|
||||||
bottom = gd->hsize + gd->sy - 1;
|
bottom = gd->hsize + gd->sy - 1;
|
||||||
else {
|
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) {
|
if (cause != NULL) {
|
||||||
bottom = gd->hsize + gd->sy - 1;
|
bottom = gd->hsize + gd->sy - 1;
|
||||||
free(cause);
|
free(cause);
|
||||||
|
@ -72,10 +72,11 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct window *src_w, *dst_w;
|
struct window *src_w, *dst_w;
|
||||||
struct window_pane *src_wp, *dst_wp;
|
struct window_pane *src_wp, *dst_wp;
|
||||||
char *cause = NULL;
|
char *cause = NULL;
|
||||||
int size, percentage, dst_idx;
|
int size, dst_idx;
|
||||||
int flags;
|
int flags;
|
||||||
enum layout_type type;
|
enum layout_type type;
|
||||||
struct layout_cell *lc;
|
struct layout_cell *lc;
|
||||||
|
u_int curval = 0;
|
||||||
|
|
||||||
dst_s = target->s;
|
dst_s = target->s;
|
||||||
dst_wl = target->wl;
|
dst_wl = target->wl;
|
||||||
@ -98,23 +99,30 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
if (args_has(args, 'h'))
|
if (args_has(args, 'h'))
|
||||||
type = LAYOUT_LEFTRIGHT;
|
type = LAYOUT_LEFTRIGHT;
|
||||||
|
|
||||||
|
/* 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 {
|
||||||
|
if (type == LAYOUT_TOPBOTTOM)
|
||||||
|
curval = dst_wp->sy;
|
||||||
|
else
|
||||||
|
curval = dst_wp->sx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size = -1;
|
size = -1;
|
||||||
if (args_has(args, 'l')) {
|
if (args_has(args, 'l')) {
|
||||||
if (type == LAYOUT_TOPBOTTOM) {
|
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
||||||
size = args_percentage(args, 'l', 0, INT_MAX,
|
item, &cause);
|
||||||
dst_wp->sy, &cause);
|
|
||||||
} else {
|
|
||||||
size = args_percentage(args, 'l', 0, INT_MAX,
|
|
||||||
dst_wp->sx, &cause);
|
|
||||||
}
|
|
||||||
} else if (args_has(args, 'p')) {
|
} else if (args_has(args, 'p')) {
|
||||||
percentage = args_strtonum(args, 'p', 0, 100, &cause);
|
size = args_strtonum_and_expand(args, 'l', 0, 100, item,
|
||||||
if (cause == NULL) {
|
&cause);
|
||||||
if (type == LAYOUT_TOPBOTTOM)
|
if (cause == NULL)
|
||||||
size = (dst_wp->sy * percentage) / 100;
|
size = curval * size / 100;
|
||||||
else
|
|
||||||
size = (dst_wp->sx * percentage) / 100;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (cause != NULL) {
|
if (cause != NULL) {
|
||||||
cmdq_error(item, "size %s", cause);
|
cmdq_error(item, "size %s", cause);
|
||||||
|
@ -151,7 +151,8 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
char *cause = NULL;
|
char *cause = NULL;
|
||||||
|
|
||||||
if (args_has(args, 'N')) {
|
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) {
|
if (cause != NULL) {
|
||||||
cmdq_error(item, "repeat count %s", cause);
|
cmdq_error(item, "repeat count %s", cause);
|
||||||
free(cause);
|
free(cause);
|
||||||
|
@ -66,67 +66,46 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
enum layout_type type;
|
enum layout_type type;
|
||||||
struct layout_cell *lc;
|
struct layout_cell *lc;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
int size, percentage, flags, input;
|
int size, flags, input;
|
||||||
const char *template, *errstr, *p;
|
const char *template;
|
||||||
char *cause, *cp, *copy;
|
char *cause = NULL, *cp;
|
||||||
size_t plen;
|
|
||||||
struct args_value *av;
|
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'))
|
if (args_has(args, 'h'))
|
||||||
type = LAYOUT_LEFTRIGHT;
|
type = LAYOUT_LEFTRIGHT;
|
||||||
else
|
|
||||||
type = LAYOUT_TOPBOTTOM;
|
/* If the 'p' flag is dropped then this bit can be moved into 'l'. */
|
||||||
if ((p = args_get(args, 'l')) != NULL) {
|
if (args_has(args, 'l') || args_has(args, 'p')) {
|
||||||
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 (args_has(args, 'f')) {
|
||||||
if (type == LAYOUT_TOPBOTTOM)
|
if (type == LAYOUT_TOPBOTTOM)
|
||||||
size = (w->sy * percentage) / 100;
|
curval = w->sy;
|
||||||
else
|
else
|
||||||
size = (w->sx * percentage) / 100;
|
curval = w->sx;
|
||||||
} else {
|
} else {
|
||||||
if (type == LAYOUT_TOPBOTTOM)
|
if (type == LAYOUT_TOPBOTTOM)
|
||||||
size = (wp->sy * percentage) / 100;
|
curval = wp->sy;
|
||||||
else
|
else
|
||||||
size = (wp->sx * percentage) / 100;
|
curval = wp->sx;
|
||||||
}
|
|
||||||
} 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 (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 = -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'));
|
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
|
||||||
input = (args_has(args, 'I') && count == 0);
|
input = (args_has(args, 'I') && count == 0);
|
||||||
|
6
tmux.h
6
tmux.h
@ -2383,10 +2383,16 @@ struct args_value *args_first_value(struct args *, u_char);
|
|||||||
struct args_value *args_next_value(struct args_value *);
|
struct args_value *args_next_value(struct args_value *);
|
||||||
long long args_strtonum(struct args *, u_char, long long, long long,
|
long long args_strtonum(struct args *, u_char, long long, long long,
|
||||||
char **);
|
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 args_percentage(struct args *, u_char, long long,
|
||||||
long long, long long, char **);
|
long long, long long, char **);
|
||||||
long long args_string_percentage(const char *, long long, long long,
|
long long args_string_percentage(const char *, long long, long long,
|
||||||
long long, char **);
|
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 */
|
/* cmd-find.c */
|
||||||
int cmd_find_target(struct cmd_find_state *, struct cmdq_item *,
|
int cmd_find_target(struct cmd_find_state *, struct cmdq_item *,
|
||||||
|
Loading…
Reference in New Issue
Block a user