From 1caa73afb4da381425160cbff68284a4dab1470b Mon Sep 17 00:00:00 2001 From: Tiago Cunha Date: Fri, 4 Dec 2009 22:11:23 +0000 Subject: [PATCH] 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. --- cmd-set-option.c | 356 ++++++++++++++++++++++++++++++++++++-- cmd-set-window-option.c | 165 +----------------- cmd-show-options.c | 40 +++-- cmd-show-window-options.c | 27 +-- options-cmd.c | 263 ---------------------------- status.c | 16 +- tmux.1 | 26 ++- tmux.h | 28 +-- 8 files changed, 408 insertions(+), 513 deletions(-) delete mode 100644 options-cmd.c diff --git a/cmd-set-option.c b/cmd-set-option.c index 4bcdd26a..2e0074b6 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -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 @@ -29,10 +29,27 @@ 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 = { "set-option", "set", - "[-agu] " CMD_TARGET_SESSION_USAGE " option [value]", - CMD_ARG12, "agu", + "[-aguw] [-t target-session|target-window] option [value]", + CMD_ARG12, "aguw", NULL, cmd_target_parse, cmd_set_option_exec, @@ -40,6 +57,12 @@ const struct cmd_entry cmd_set_option_entry = { 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[] = { "emacs", "vi", NULL }; @@ -49,7 +72,8 @@ const char *set_option_status_justify_list[] = { const char *set_option_bell_action_list[] = { "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 }, { "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list }, { "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 } }; +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 cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; + const struct set_option_entry *table; struct session *s; + struct winlink *wl; struct client *c; struct options *oo; 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; int try_again; - if (cmd_check_flag(data->chflags, 'g')) - oo = &global_s_options; - else { - if ((s = cmd_find_session(ctx, data->target)) == NULL) - return (-1); - oo = &s->options; + if (cmd_check_flag(data->chflags, 'w')) { + table = set_window_option_table; + if (cmd_check_flag(data->chflags, 'g')) + oo = &global_w_options; + else { + 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') { @@ -128,7 +200,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) } 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) continue; if (entry != NULL) { @@ -163,31 +235,36 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) } else { switch (entry->type) { 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')); break; case SET_OPTION_NUMBER: - set_option_number(ctx, oo, entry, data->arg2); + cmd_set_option_number(ctx, oo, entry, data->arg2); break; case SET_OPTION_KEYS: - set_option_keys(ctx, oo, entry, data->arg2); + cmd_set_option_keys(ctx, oo, entry, data->arg2); break; case SET_OPTION_COLOUR: - set_option_colour(ctx, oo, entry, data->arg2); + cmd_set_option_colour(ctx, oo, entry, data->arg2); break; case SET_OPTION_ATTRIBUTES: - set_option_attributes(ctx, oo, entry, data->arg2); + cmd_set_option_attributes(ctx, oo, entry, data->arg2); break; case SET_OPTION_FLAG: - set_option_flag(ctx, oo, entry, data->arg2); + cmd_set_option_flag(ctx, oo, entry, data->arg2); break; case SET_OPTION_CHOICE: - set_option_choice(ctx, oo, entry, data->arg2); + cmd_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 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 || 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++) { c = ARRAY_ITEM(&clients, i); if (c == NULL || c->session == NULL) @@ -222,3 +300,243 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) 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)); +} diff --git a/cmd-set-window-option.c b/cmd-set-window-option.c index a66ff5dd..fc6b0ebb 100644 --- a/cmd-set-window-option.c +++ b/cmd-set-window-option.c @@ -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 @@ -18,13 +18,10 @@ #include -#include -#include - #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 *); @@ -40,165 +37,11 @@ const struct cmd_entry cmd_set_window_option_entry = { 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 cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx) { 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')) - oo = &global_w_options; - 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); + cmd_set_flag(&data->chflags, 'w'); + return (cmd_set_option_entry.exec(self, ctx)); } diff --git a/cmd-show-options.c b/cmd-show-options.c index 860fc45a..94095676 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -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 @@ -31,8 +31,8 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_show_options_entry = { "show-options", "show", - "[-g] " CMD_TARGET_SESSION_USAGE, - 0, "g", + "[-gw] [-t target-session|target-window]", + 0, "gw", cmd_target_init, cmd_target_parse, cmd_show_options_exec, @@ -43,25 +43,41 @@ const struct cmd_entry cmd_show_options_entry = { int 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 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')) - oo = &global_s_options; - else { - if ((s = cmd_find_session(ctx, data->target)) == NULL) - return (-1); - oo = &s->options; + if (cmd_check_flag(data->chflags, 'w')) { + table = set_window_option_table; + if (cmd_check_flag(data->chflags, 'g')) + oo = &global_w_options; + else { + 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) continue; - optval = set_option_print(entry, o); + optval = cmd_set_option_print(entry, o); ctx->print(ctx, "%s %s", entry->name, optval); } diff --git a/cmd-show-window-options.c b/cmd-show-window-options.c index 04fe1523..a33694f0 100644 --- a/cmd-show-window-options.c +++ b/cmd-show-window-options.c @@ -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 @@ -24,7 +24,7 @@ #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 *); @@ -44,26 +44,7 @@ int cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx) { 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')) - oo = &global_w_options; - 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); + cmd_set_flag(&data->chflags, 'w'); + return (cmd_show_options_entry.exec(self, ctx)); } diff --git a/options-cmd.c b/options-cmd.c deleted file mode 100644 index 815c2e63..00000000 --- a/options-cmd.c +++ /dev/null @@ -1,263 +0,0 @@ -/* $Id: options-cmd.c,v 1.8 2009-09-22 14:22:20 tcunha Exp $ */ - -/* - * Copyright (c) 2008 Nicholas Marriott - * - * 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 - -#include -#include - -#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)); -} diff --git a/status.c b/status.c index 92df2f18..6cabc7c2 100644 --- a/status.c +++ b/status.c @@ -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 @@ -1115,7 +1115,7 @@ char * status_prompt_complete(const char *s) { const struct cmd_entry **cmdent; - const struct set_option_entry *optent; + const struct set_option_entry *entry; ARRAY_DECL(, const char *) list; char *prefix, *s2; u_int i; @@ -1130,13 +1130,13 @@ status_prompt_complete(const char *s) if (strncmp((*cmdent)->name, s, strlen(s)) == 0) ARRAY_ADD(&list, (*cmdent)->name); } - for (optent = set_option_table; optent->name != NULL; optent++) { - if (strncmp(optent->name, s, strlen(s)) == 0) - ARRAY_ADD(&list, optent->name); + for (entry = set_session_option_table; entry->name != NULL; entry++) { + if (strncmp(entry->name, s, strlen(s)) == 0) + ARRAY_ADD(&list, entry->name); } - for (optent = set_window_option_table; optent->name != NULL; optent++) { - if (strncmp(optent->name, s, strlen(s)) == 0) - ARRAY_ADD(&list, optent->name); + for (entry = set_window_option_table; entry->name != NULL; entry++) { + if (strncmp(entry->name, s, strlen(s)) == 0) + ARRAY_ADD(&list, entry->name); } /* If none, bail now. */ diff --git a/tmux.1 b/tmux.1 index 5386dfd3..7e210776 100644 --- a/tmux.1 +++ b/tmux.1 @@ -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 .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" 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 .Os .Sh NAME @@ -1230,8 +1230,8 @@ command. Commands which set options are as follows: .Bl -tag -width Ds .It Xo Ic set-option -.Op Fl agu -.Op Fl t Ar target-session +.Op Fl aguw +.Op Fl t Ar target-session | Ar target-window .Ar option Ar value .Xc .D1 (alias: Ic set ) @@ -1249,6 +1249,13 @@ The flag unsets an option, so a session inherits the option from the global options - it is not possible to unset a global option. .Pp +With +.Fl w , +this command is equivalent to +.Ic set-window-option +with +.Ar target-window . +.Pp Available session options are: .Bl -tag -width Ds .It Ic base-index Ar index @@ -1831,14 +1838,21 @@ as Shift, Alt or Ctrl. The default is off. .El .It Xo Ic show-options -.Op Fl g -.Op Fl t Ar target-session +.Op Fl gw +.Op Fl t Ar target-session | Ar target-window .Xc .D1 (alias: Ic show ) Show the session options for .Ar target session , or the global session options with .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 .Op Fl g .Op Fl t Ar target-window diff --git a/tmux.h b/tmux.h index 9202b16b..e2d44f86 100644 --- a/tmux.h +++ b/tmux.h @@ -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 @@ -1232,8 +1232,6 @@ struct set_option_entry { const char **choices; }; -extern const struct set_option_entry set_option_table[]; -extern const struct set_option_entry set_window_option_table[]; /* tmux.c */ extern struct options global_s_options; @@ -1376,24 +1374,6 @@ void tty_keys_init(struct tty *); void tty_keys_free(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 */ void paste_init_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]; 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 */ int cmd_pack_argv(int, char **, char *, size_t); int cmd_unpack_argv(char *, size_t, int, char ***);