1
0
mirror of https://github.com/tmate-io/tmate-ssh-server.git synced 2020-11-18 19:53:51 -08:00

Sync OpenBSD patchset 580:

Eliminate duplicate code and ease the passage for server-wide options by adding
a -w flag to set-option and show-options and making setw and showw aliases to
set -w and show -w.

Note: setw and showw are still there, but now aliases for set -w and show -w.
This commit is contained in:
Tiago Cunha 2009-12-04 22:11:23 +00:00
parent ddb5bb80fa
commit 1caa73afb4
8 changed files with 408 additions and 513 deletions

View File

@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.87 2009-11-19 22:20:04 tcunha Exp $ */ /* $Id: cmd-set-option.c,v 1.88 2009-12-04 22:11:23 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -29,10 +29,27 @@
int cmd_set_option_exec(struct cmd *, struct cmd_ctx *); int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const char *cmd_set_option_print(
const struct set_option_entry *, struct options_entry *);
void cmd_set_option_string(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *, int);
void cmd_set_option_number(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_keys(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_colour(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_attributes(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_flag(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_choice(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
const struct cmd_entry cmd_set_option_entry = { const struct cmd_entry cmd_set_option_entry = {
"set-option", "set", "set-option", "set",
"[-agu] " CMD_TARGET_SESSION_USAGE " option [value]", "[-aguw] [-t target-session|target-window] option [value]",
CMD_ARG12, "agu", CMD_ARG12, "aguw",
NULL, NULL,
cmd_target_parse, cmd_target_parse,
cmd_set_option_exec, cmd_set_option_exec,
@ -40,6 +57,12 @@ const struct cmd_entry cmd_set_option_entry = {
cmd_target_print cmd_target_print
}; };
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const char *set_option_status_keys_list[] = { const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL "emacs", "vi", NULL
}; };
@ -49,7 +72,8 @@ const char *set_option_status_justify_list[] = {
const char *set_option_bell_action_list[] = { const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL "none", "any", "current", NULL
}; };
const struct set_option_entry set_option_table[] = {
const struct set_option_entry set_session_option_table[] = {
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list }, { "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
@ -101,11 +125,45 @@ const struct set_option_entry set_option_table[] = {
{ NULL, 0, 0, 0, NULL } { NULL, 0, 0, 0, NULL }
}; };
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s; struct session *s;
struct winlink *wl;
struct client *c; struct client *c;
struct options *oo; struct options *oo;
const struct set_option_entry *entry, *opt; const struct set_option_entry *entry, *opt;
@ -114,12 +172,26 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
u_int i; u_int i;
int try_again; int try_again;
if (cmd_check_flag(data->chflags, 'g')) if (cmd_check_flag(data->chflags, 'w')) {
oo = &global_s_options; table = set_window_option_table;
else { if (cmd_check_flag(data->chflags, 'g'))
if ((s = cmd_find_session(ctx, data->target)) == NULL) oo = &global_w_options;
return (-1); else {
oo = &s->options; wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
} }
if (*data->arg == '\0') { if (*data->arg == '\0') {
@ -128,7 +200,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
entry = NULL; entry = NULL;
for (opt = set_option_table; opt->name != NULL; opt++) { for (opt = table; opt->name != NULL; opt++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0) if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
continue; continue;
if (entry != NULL) { if (entry != NULL) {
@ -163,31 +235,36 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else { } else {
switch (entry->type) { switch (entry->type) {
case SET_OPTION_STRING: case SET_OPTION_STRING:
set_option_string(ctx, oo, entry, cmd_set_option_string(ctx, oo, entry,
data->arg2, cmd_check_flag(data->chflags, 'a')); data->arg2, cmd_check_flag(data->chflags, 'a'));
break; break;
case SET_OPTION_NUMBER: case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2); cmd_set_option_number(ctx, oo, entry, data->arg2);
break; break;
case SET_OPTION_KEYS: case SET_OPTION_KEYS:
set_option_keys(ctx, oo, entry, data->arg2); cmd_set_option_keys(ctx, oo, entry, data->arg2);
break; break;
case SET_OPTION_COLOUR: case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2); cmd_set_option_colour(ctx, oo, entry, data->arg2);
break; break;
case SET_OPTION_ATTRIBUTES: case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2); cmd_set_option_attributes(ctx, oo, entry, data->arg2);
break; break;
case SET_OPTION_FLAG: case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2); cmd_set_option_flag(ctx, oo, entry, data->arg2);
break; break;
case SET_OPTION_CHOICE: case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2); cmd_set_option_choice(ctx, oo, entry, data->arg2);
break; break;
} }
} }
recalculate_sizes(); recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
server_redraw_client(c);
}
/* /*
* Special-case: kill all persistent jobs if status-left, status-right * Special-case: kill all persistent jobs if status-left, status-right
@ -196,7 +273,8 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
*/ */
if (strcmp(entry->name, "status-left") == 0 || if (strcmp(entry->name, "status-left") == 0 ||
strcmp(entry->name, "status-right") == 0 || strcmp(entry->name, "status-right") == 0 ||
strcmp(entry->name, "set-titles-string") == 0) { strcmp(entry->name, "set-titles-string") == 0 ||
strcmp(entry->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL) if (c == NULL || c->session == NULL)
@ -222,3 +300,243 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0); return (0);
} }
const char *
cmd_set_option_print(
const struct set_option_entry *entry, struct options_entry *o)
{
static char out[BUFSIZ];
const char *s;
struct keylist *keylist;
u_int i;
*out = '\0';
switch (entry->type) {
case SET_OPTION_STRING:
xsnprintf(out, sizeof out, "\"%s\"", o->str);
break;
case SET_OPTION_NUMBER:
xsnprintf(out, sizeof out, "%lld", o->num);
break;
case SET_OPTION_KEYS:
keylist = o->data;
for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
strlcat(out, key_string_lookup_key(
ARRAY_ITEM(keylist, i)), sizeof out);
if (i != ARRAY_LENGTH(keylist) - 1)
strlcat(out, ",", sizeof out);
}
break;
case SET_OPTION_COLOUR:
s = colour_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_ATTRIBUTES:
s = attributes_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_FLAG:
if (o->num)
strlcpy(out, "on", sizeof out);
else
strlcpy(out, "off", sizeof out);
break;
case SET_OPTION_CHOICE:
s = entry->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
}
return (out);
}
void
cmd_set_option_string(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value, int append)
{
struct options_entry *o;
char *oldvalue, *newvalue;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if (append) {
oldvalue = options_get_string(oo, entry->name);
xasprintf(&newvalue, "%s%s", oldvalue, value);
} else
newvalue = value;
o = options_set_string(oo, entry->name, "%s", newvalue);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
if (newvalue != value)
xfree(newvalue);
}
void
cmd_set_option_number(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
long long number;
const char *errstr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
number = strtonum(value, entry->minimum, entry->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
return;
}
o = options_set_number(oo, entry->name, number);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
struct keylist *keylist;
char *copyvalue, *ptr, *str;
int key;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ptr = copyvalue = xstrdup(value);
while ((str = strsep(&ptr, ",")) != NULL) {
if ((key = key_string_lookup_string(str)) == KEYC_NONE) {
xfree(keylist);
ctx->error(ctx, "unknown key: %s", str);
xfree(copyvalue);
return;
}
ARRAY_ADD(keylist, key);
}
xfree(copyvalue);
o = options_set_data(oo, entry->name, keylist, xfree);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_colour(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int colour;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
return;
}
o = options_set_number(oo, entry->name, colour);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int attr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
return;
}
o = options_set_number(oo, entry->name, attr);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int flag;
if (value == NULL || *value == '\0')
flag = !options_get_number(oo, entry->name);
else {
if ((value[0] == '1' && value[1] == '\0') ||
strcasecmp(value, "on") == 0 ||
strcasecmp(value, "yes") == 0)
flag = 1;
else if ((value[0] == '0' && value[1] == '\0') ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
return;
}
}
o = options_set_number(oo, entry->name, flag);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_choice(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
const char **choicep;
int n, choice = -1;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
n = 0;
for (choicep = entry->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (choice != -1) {
ctx->error(ctx, "ambiguous option value: %s", value);
return;
}
choice = n - 1;
}
if (choice == -1) {
ctx->error(ctx, "unknown option value: %s", value);
return;
}
o = options_set_number(oo, entry->name, choice);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}

View File

@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.42 2009-11-19 22:35:10 tcunha Exp $ */ /* $Id: cmd-set-window-option.c,v 1.43 2009-12-04 22:11:23 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -18,13 +18,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
/* /*
* Set a window option. * Set a window option. This is just an alias for set-option -w.
*/ */
int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *); int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
@ -40,165 +37,11 @@ const struct cmd_entry cmd_set_window_option_entry = {
cmd_target_print cmd_target_print
}; };
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry, *opt;
struct jobs *jobs;
struct job *job, *nextjob;
u_int i;
int try_again;
if (cmd_check_flag(data->chflags, 'g')) cmd_set_flag(&data->chflags, 'w');
oo = &global_w_options; return (cmd_set_option_entry.exec(self, ctx));
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
if (*data->arg == '\0') {
ctx->error(ctx, "invalid option");
return (-1);
}
entry = NULL;
for (opt = set_window_option_table; opt->name != NULL; opt++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
continue;
if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg);
return (-1);
}
entry = opt;
/* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0)
break;
}
if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg);
return (-1);
}
if (cmd_check_flag(data->chflags, 'u')) {
if (cmd_check_flag(data->chflags, 'g')) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
return (-1);
}
if (data->arg2 != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
}
options_remove(oo, entry->name);
ctx->info(ctx, "unset option: %s", entry->name);
} else {
switch (entry->type) {
case SET_OPTION_STRING:
set_option_string(ctx, oo, entry,
data->arg2, cmd_check_flag(data->chflags, 'a'));
break;
case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEYS:
set_option_keys(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2);
break;
}
}
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
server_redraw_client(c);
}
/*
* Special-case: kill all persistent jobs if window-status-format has
* changed. Persistent jobs are only used by the status line at the
* moment so this works XXX.
*/
if (strcmp(entry->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
jobs = &c->status_jobs;
do {
try_again = 0;
job = RB_ROOT(jobs);
while (job != NULL) {
nextjob = RB_NEXT(jobs, jobs, job);
if (job->flags & JOB_PERSIST) {
job_remove(jobs, job);
try_again = 1;
break;
}
job = nextjob;
}
} while (try_again);
server_redraw_client(c);
}
}
return (0);
} }

View File

@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.18 2009-11-14 17:56:39 tcunha Exp $ */ /* $Id: cmd-show-options.c,v 1.19 2009-12-04 22:11:23 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -31,8 +31,8 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_options_entry = { const struct cmd_entry cmd_show_options_entry = {
"show-options", "show", "show-options", "show",
"[-g] " CMD_TARGET_SESSION_USAGE, "[-gw] [-t target-session|target-window]",
0, "g", 0, "gw",
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_show_options_exec, cmd_show_options_exec,
@ -43,25 +43,41 @@ const struct cmd_entry cmd_show_options_entry = {
int int
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s; struct session *s;
struct winlink *wl;
struct options *oo; struct options *oo;
struct options_entry *o; struct options_entry *o;
const struct set_option_entry *entry; const struct set_option_entry *entry;
const char *optval; const char *optval;
if (cmd_check_flag(data->chflags, 'g')) if (cmd_check_flag(data->chflags, 'w')) {
oo = &global_s_options; table = set_window_option_table;
else { if (cmd_check_flag(data->chflags, 'g'))
if ((s = cmd_find_session(ctx, data->target)) == NULL) oo = &global_w_options;
return (-1); else {
oo = &s->options; wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
} }
for (entry = set_option_table; entry->name != NULL; entry++) { for (entry = table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL) if ((o = options_find1(oo, entry->name)) == NULL)
continue; continue;
optval = set_option_print(entry, o); optval = cmd_set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval); ctx->print(ctx, "%s %s", entry->name, optval);
} }

View File

@ -1,4 +1,4 @@
/* $Id: cmd-show-window-options.c,v 1.14 2009-11-14 17:56:39 tcunha Exp $ */ /* $Id: cmd-show-window-options.c,v 1.15 2009-12-04 22:11:23 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -24,7 +24,7 @@
#include "tmux.h" #include "tmux.h"
/* /*
* Show window options. * Show window options. This is an alias for show-options -w.
*/ */
int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *); int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
@ -44,26 +44,7 @@ int
cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
const char *optval;
if (cmd_check_flag(data->chflags, 'g')) cmd_set_flag(&data->chflags, 'w');
oo = &global_w_options; return (cmd_show_options_entry.exec(self, ctx));
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
for (entry = set_window_option_table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
continue;
optval = set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
}
return (0);
} }

View File

@ -1,263 +0,0 @@
/* $Id: options-cmd.c,v 1.8 2009-09-22 14:22:20 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
const char *
set_option_print(const struct set_option_entry *entry, struct options_entry *o)
{
static char out[BUFSIZ];
const char *s;
struct keylist *keylist;
u_int i;
*out = '\0';
switch (entry->type) {
case SET_OPTION_STRING:
xsnprintf(out, sizeof out, "\"%s\"", o->str);
break;
case SET_OPTION_NUMBER:
xsnprintf(out, sizeof out, "%lld", o->num);
break;
case SET_OPTION_KEYS:
keylist = o->data;
for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
strlcat(out, key_string_lookup_key(
ARRAY_ITEM(keylist, i)), sizeof out);
if (i != ARRAY_LENGTH(keylist) - 1)
strlcat(out, ",", sizeof out);
}
break;
case SET_OPTION_COLOUR:
s = colour_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_ATTRIBUTES:
s = attributes_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_FLAG:
if (o->num)
strlcpy(out, "on", sizeof out);
else
strlcpy(out, "off", sizeof out);
break;
case SET_OPTION_CHOICE:
s = entry->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
}
return (out);
}
void
set_option_string(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value, int append)
{
struct options_entry *o;
char *oldvalue, *newvalue;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if (append) {
oldvalue = options_get_string(oo, entry->name);
xasprintf(&newvalue, "%s%s", oldvalue, value);
} else
newvalue = value;
o = options_set_string(oo, entry->name, "%s", newvalue);
ctx->info(
ctx, "set option: %s -> %s", o->name, set_option_print(entry, o));
if (newvalue != value)
xfree(newvalue);
}
void
set_option_number(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
long long number;
const char *errstr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
number = strtonum(value, entry->minimum, entry->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
return;
}
o = options_set_number(oo, entry->name, number);
ctx->info(
ctx, "set option: %s -> %s", o->name, set_option_print(entry, o));
}
void
set_option_keys(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
struct keylist *keylist;
char *copyvalue, *ptr, *str;
int key;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ptr = copyvalue = xstrdup(value);
while ((str = strsep(&ptr, ",")) != NULL) {
if ((key = key_string_lookup_string(str)) == KEYC_NONE) {
xfree(keylist);
ctx->error(ctx, "unknown key: %s", str);
xfree(copyvalue);
return;
}
ARRAY_ADD(keylist, key);
}
xfree(copyvalue);
o = options_set_data(oo, entry->name, keylist, xfree);
ctx->info(
ctx, "set option: %s -> %s", o->name, set_option_print(entry, o));
}
void
set_option_colour(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int colour;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
return;
}
o = options_set_number(oo, entry->name, colour);
ctx->info(
ctx, "set option: %s -> %s", o->name, set_option_print(entry, o));
}
void
set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int attr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
return;
}
o = options_set_number(oo, entry->name, attr);
ctx->info(
ctx, "set option: %s -> %s", o->name, set_option_print(entry, o));
}
void
set_option_flag(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int flag;
if (value == NULL || *value == '\0')
flag = !options_get_number(oo, entry->name);
else {
if ((value[0] == '1' && value[1] == '\0') ||
strcasecmp(value, "on") == 0 ||
strcasecmp(value, "yes") == 0)
flag = 1;
else if ((value[0] == '0' && value[1] == '\0') ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
return;
}
}
o = options_set_number(oo, entry->name, flag);
ctx->info(
ctx, "set option: %s -> %s", o->name, set_option_print(entry, o));
}
void
set_option_choice(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
const char **choicep;
int n, choice = -1;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
n = 0;
for (choicep = entry->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (choice != -1) {
ctx->error(ctx, "ambiguous option: %s", value);
return;
}
choice = n - 1;
}
if (choice == -1) {
ctx->error(ctx, "unknown option: %s", value);
return;
}
o = options_set_number(oo, entry->name, choice);
ctx->info(
ctx, "set option: %s -> %s", o->name, set_option_print(entry, o));
}

View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.138 2009-11-28 14:54:12 tcunha Exp $ */ /* $Id: status.c,v 1.139 2009-12-04 22:11:23 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1115,7 +1115,7 @@ char *
status_prompt_complete(const char *s) status_prompt_complete(const char *s)
{ {
const struct cmd_entry **cmdent; const struct cmd_entry **cmdent;
const struct set_option_entry *optent; const struct set_option_entry *entry;
ARRAY_DECL(, const char *) list; ARRAY_DECL(, const char *) list;
char *prefix, *s2; char *prefix, *s2;
u_int i; u_int i;
@ -1130,13 +1130,13 @@ status_prompt_complete(const char *s)
if (strncmp((*cmdent)->name, s, strlen(s)) == 0) if (strncmp((*cmdent)->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, (*cmdent)->name); ARRAY_ADD(&list, (*cmdent)->name);
} }
for (optent = set_option_table; optent->name != NULL; optent++) { for (entry = set_session_option_table; entry->name != NULL; entry++) {
if (strncmp(optent->name, s, strlen(s)) == 0) if (strncmp(entry->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, optent->name); ARRAY_ADD(&list, entry->name);
} }
for (optent = set_window_option_table; optent->name != NULL; optent++) { for (entry = set_window_option_table; entry->name != NULL; entry++) {
if (strncmp(optent->name, s, strlen(s)) == 0) if (strncmp(entry->name, s, strlen(s)) == 0)
ARRAY_ADD(&list, optent->name); ARRAY_ADD(&list, entry->name);
} }
/* If none, bail now. */ /* If none, bail now. */

26
tmux.1
View File

@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.210 2009-12-02 15:10:44 tcunha Exp $ .\" $Id: tmux.1,v 1.211 2009-12-04 22:11:23 tcunha Exp $
.\" .\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\" .\"
@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: December 1 2009 $ .Dd $Mdocdate: December 3 2009 $
.Dt TMUX 1 .Dt TMUX 1
.Os .Os
.Sh NAME .Sh NAME
@ -1230,8 +1230,8 @@ command.
Commands which set options are as follows: Commands which set options are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo Ic set-option .It Xo Ic set-option
.Op Fl agu .Op Fl aguw
.Op Fl t Ar target-session .Op Fl t Ar target-session | Ar target-window
.Ar option Ar value .Ar option Ar value
.Xc .Xc
.D1 (alias: Ic set ) .D1 (alias: Ic set )
@ -1249,6 +1249,13 @@ The
flag unsets an option, so a session inherits the option from the global flag unsets an option, so a session inherits the option from the global
options - it is not possible to unset a global option. options - it is not possible to unset a global option.
.Pp .Pp
With
.Fl w ,
this command is equivalent to
.Ic set-window-option
with
.Ar target-window .
.Pp
Available session options are: Available session options are:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Ic base-index Ar index .It Ic base-index Ar index
@ -1831,14 +1838,21 @@ as Shift, Alt or Ctrl.
The default is off. The default is off.
.El .El
.It Xo Ic show-options .It Xo Ic show-options
.Op Fl g .Op Fl gw
.Op Fl t Ar target-session .Op Fl t Ar target-session | Ar target-window
.Xc .Xc
.D1 (alias: Ic show ) .D1 (alias: Ic show )
Show the session options for Show the session options for
.Ar target session , .Ar target session ,
or the global session options with or the global session options with
.Fl g . .Fl g .
.Pp
If
.Fl w
is used, this command is equivalent to
.Ic show-window-options
with
.Ar target-window .
.It Xo Ic show-window-options .It Xo Ic show-window-options
.Op Fl g .Op Fl g
.Op Fl t Ar target-window .Op Fl t Ar target-window

28
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.528 2009-12-02 15:10:44 tcunha Exp $ */ /* $Id: tmux.h,v 1.529 2009-12-04 22:11:23 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -1232,8 +1232,6 @@ struct set_option_entry {
const char **choices; const char **choices;
}; };
extern const struct set_option_entry set_option_table[];
extern const struct set_option_entry set_window_option_table[];
/* tmux.c */ /* tmux.c */
extern struct options global_s_options; extern struct options global_s_options;
@ -1376,24 +1374,6 @@ void tty_keys_init(struct tty *);
void tty_keys_free(struct tty *); void tty_keys_free(struct tty *);
int tty_keys_next(struct tty *); int tty_keys_next(struct tty *);
/* options-cmd.c */
const char *set_option_print(
const struct set_option_entry *, struct options_entry *);
void set_option_string(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *, int);
void set_option_number(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void set_option_keys(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void set_option_colour(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void set_option_attributes(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void set_option_flag(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void set_option_choice(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
/* paste.c */ /* paste.c */
void paste_init_stack(struct paste_stack *); void paste_init_stack(struct paste_stack *);
void paste_free_stack(struct paste_stack *); void paste_free_stack(struct paste_stack *);
@ -1409,6 +1389,12 @@ int paste_replace(struct paste_stack *, u_int, char *, size_t);
extern const char clock_table[14][5][5]; extern const char clock_table[14][5][5];
void clock_draw(struct screen_write_ctx *, int, int); void clock_draw(struct screen_write_ctx *, int, int);
/* cmd-set-option.c */
extern const struct set_option_entry set_session_option_table[];
extern const struct set_option_entry set_window_option_table[];
const char *cmd_set_option_print(
const struct set_option_entry *, struct options_entry *);
/* cmd.c */ /* cmd.c */
int cmd_pack_argv(int, char **, char *, size_t); int cmd_pack_argv(int, char **, char *, size_t);
int cmd_unpack_argv(char *, size_t, int, char ***); int cmd_unpack_argv(char *, size_t, int, char ***);