Change so main-pane-width and height can be given as a percentage.

This commit is contained in:
nicm 2020-04-22 06:57:13 +00:00
parent 445dfa8512
commit de5163a634
5 changed files with 66 additions and 36 deletions

View File

@ -352,22 +352,29 @@ long long
args_percentage(struct args *args, u_char ch, long long minval, args_percentage(struct args *args, u_char ch, long long minval,
long long maxval, long long curval, char **cause) long long maxval, long long curval, char **cause)
{ {
const char *errstr; const char *value;
long long ll;
struct args_entry *entry; struct args_entry *entry;
struct args_value *value;
size_t valuelen;
char *copy;
if ((entry = args_find(args, ch)) == NULL) { if ((entry = args_find(args, ch)) == NULL) {
*cause = xstrdup("missing"); *cause = xstrdup("missing");
return (0); return (0);
} }
value = TAILQ_LAST(&entry->values, args_values); value = TAILQ_LAST(&entry->values, args_values)->value;
valuelen = strlen(value->value); return (args_string_percentage(value, minval, maxval, curval, cause));
}
if (value->value[valuelen - 1] == '%') { /* Convert a string to a number which may be a percentage. */
copy = xstrdup(value->value); long long
args_string_percentage(const char *value, long long minval, long long maxval,
long long curval, char **cause)
{
const char *errstr;
long long ll;
size_t valuelen = strlen(value);
char *copy;
if (value[valuelen - 1] == '%') {
copy = xstrdup(value);
copy[valuelen - 1] = '\0'; copy[valuelen - 1] = '\0';
ll = strtonum(copy, 0, 100, &errstr); ll = strtonum(copy, 0, 100, &errstr);
@ -386,7 +393,7 @@ args_percentage(struct args *args, u_char ch, long long minval,
return (0); return (0);
} }
} else { } else {
ll = strtonum(value->value, minval, maxval, &errstr); ll = strtonum(value, minval, maxval, &errstr);
if (errstr != NULL) { if (errstr != NULL) {
*cause = xstrdup(errstr); *cause = xstrdup(errstr);
return (0); return (0);

View File

@ -18,6 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "tmux.h" #include "tmux.h"
@ -186,6 +187,8 @@ layout_set_main_h(struct window *w)
struct window_pane *wp; struct window_pane *wp;
struct layout_cell *lc, *lcmain, *lcother, *lcchild; struct layout_cell *lc, *lcmain, *lcother, *lcchild;
u_int n, mainh, otherh, sx, sy; u_int n, mainh, otherh, sx, sy;
char *cause;
const char *s;
layout_print_cell(w->layout_root, __func__, 1); layout_print_cell(w->layout_root, __func__, 1);
@ -198,8 +201,15 @@ layout_set_main_h(struct window *w)
/* Find available height - take off one line for the border. */ /* Find available height - take off one line for the border. */
sy = w->sy - 1; sy = w->sy - 1;
/* Get the main pane height and work out the other pane height. */ /* Get the main pane height. */
mainh = options_get_number(w->options, "main-pane-height"); s = options_get_string(w->options, "main-pane-height");
mainh = args_string_percentage(s, 0, sy, sy, &cause);
if (cause != NULL) {
mainh = 24;
free(cause);
}
/* Work out the other pane height. */
if (mainh + PANE_MINIMUM >= sy) { if (mainh + PANE_MINIMUM >= sy) {
if (sy <= PANE_MINIMUM + PANE_MINIMUM) if (sy <= PANE_MINIMUM + PANE_MINIMUM)
mainh = PANE_MINIMUM; mainh = PANE_MINIMUM;
@ -207,10 +217,12 @@ layout_set_main_h(struct window *w)
mainh = sy - PANE_MINIMUM; mainh = sy - PANE_MINIMUM;
otherh = PANE_MINIMUM; otherh = PANE_MINIMUM;
} else { } else {
otherh = options_get_number(w->options, "other-pane-height"); s = options_get_string(w->options, "other-pane-height");
if (otherh == 0) otherh = args_string_percentage(s, 0, sy, sy, &cause);
if (cause != NULL || otherh == 0) {
otherh = sy - mainh; otherh = sy - mainh;
else if (otherh > sy || sy - otherh < mainh) free(cause);
} else if (otherh > sy || sy - otherh < mainh)
otherh = sy - mainh; otherh = sy - mainh;
else else
mainh = sy - otherh; mainh = sy - otherh;
@ -273,6 +285,8 @@ layout_set_main_v(struct window *w)
struct window_pane *wp; struct window_pane *wp;
struct layout_cell *lc, *lcmain, *lcother, *lcchild; struct layout_cell *lc, *lcmain, *lcother, *lcchild;
u_int n, mainw, otherw, sx, sy; u_int n, mainw, otherw, sx, sy;
char *cause;
const char *s;
layout_print_cell(w->layout_root, __func__, 1); layout_print_cell(w->layout_root, __func__, 1);
@ -285,8 +299,15 @@ layout_set_main_v(struct window *w)
/* Find available width - take off one line for the border. */ /* Find available width - take off one line for the border. */
sx = w->sx - 1; sx = w->sx - 1;
/* Get the main pane width and work out the other pane width. */ /* Get the main pane width. */
mainw = options_get_number(w->options, "main-pane-width"); s = options_get_string(w->options, "main-pane-width");
mainw = args_string_percentage(s, 0, sx, sx, &cause);
if (cause != NULL) {
mainw = 80;
free(cause);
}
/* Work out the other pane width. */
if (mainw + PANE_MINIMUM >= sx) { if (mainw + PANE_MINIMUM >= sx) {
if (sx <= PANE_MINIMUM + PANE_MINIMUM) if (sx <= PANE_MINIMUM + PANE_MINIMUM)
mainw = PANE_MINIMUM; mainw = PANE_MINIMUM;
@ -294,10 +315,12 @@ layout_set_main_v(struct window *w)
mainw = sx - PANE_MINIMUM; mainw = sx - PANE_MINIMUM;
otherw = PANE_MINIMUM; otherw = PANE_MINIMUM;
} else { } else {
otherw = options_get_number(w->options, "other-pane-width"); s = options_get_string(w->options, "other-pane-width");
if (otherw == 0) otherw = args_string_percentage(s, 0, sx, sx, &cause);
if (cause != NULL || otherw == 0) {
otherw = sx - mainw; otherw = sx - mainw;
else if (otherw > sx || sx - otherw < mainw) free(cause);
} else if (otherw > sx || sx - otherw < mainw)
otherw = sx - mainw; otherw = sx - mainw;
else else
mainw = sx - otherw; mainw = sx - otherw;

View File

@ -647,19 +647,15 @@ const struct options_table_entry options_table[] = {
}, },
{ .name = "main-pane-height", { .name = "main-pane-height",
.type = OPTIONS_TABLE_NUMBER, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
.minimum = 1, .default_str = "24"
.maximum = INT_MAX,
.default_num = 24
}, },
{ .name = "main-pane-width", { .name = "main-pane-width",
.type = OPTIONS_TABLE_NUMBER, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
.minimum = 1, .default_str = "80"
.maximum = INT_MAX,
.default_num = 80
}, },
{ .name = "mode-keys", { .name = "mode-keys",
@ -696,19 +692,15 @@ const struct options_table_entry options_table[] = {
}, },
{ .name = "other-pane-height", { .name = "other-pane-height",
.type = OPTIONS_TABLE_NUMBER, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
.minimum = 0, .default_str = "0"
.maximum = INT_MAX,
.default_num = 0
}, },
{ .name = "other-pane-width", { .name = "other-pane-width",
.type = OPTIONS_TABLE_NUMBER, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
.minimum = 0, .default_str = "0"
.maximum = INT_MAX,
.default_num = 0
}, },
{ .name = "pane-active-border-style", { .name = "pane-active-border-style",

6
tmux.1
View File

@ -3711,6 +3711,9 @@ Set the width or height of the main (left or top) pane in the
or or
.Ic main-vertical .Ic main-vertical
layouts. layouts.
If suffixed by
.Ql % ,
this is a percentage of the window size.
.Pp .Pp
.It Xo Ic mode-keys .It Xo Ic mode-keys
.Op Ic vi | emacs .Op Ic vi | emacs
@ -3764,6 +3767,9 @@ and
.Ic other-pane-height .Ic other-pane-height
options are set, the main pane will grow taller to make the other panes the options are set, the main pane will grow taller to make the other panes the
specified height, but will never shrink to do so. specified height, but will never shrink to do so.
If suffixed by
.Ql % ,
this is a percentage of the window size.
.Pp .Pp
.It Ic other-pane-width Ar width .It Ic other-pane-width Ar width
Like Like

2
tmux.h
View File

@ -2043,6 +2043,8 @@ long long args_strtonum(struct args *, u_char, long long, long long,
char **); 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, 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 *,