From 557b6b86b0b153b98f06897756d2ebd5ca53b78a Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 15 Jun 2008 08:01:54 +0000 Subject: [PATCH] Add a couple of extra option types, and implement show-options command. --- CHANGES | 6 +- GNUmakefile | 4 +- Makefile | 4 +- TODO | 3 +- cmd-send-prefix.c | 4 +- cmd-set-option.c | 12 ++-- cmd-show-options.c | 170 +++++++++++++++++++++++++++++++++++++++++++++ cmd.c | 5 +- options.c | 126 +++++++++++++++++++++++++-------- server.c | 4 +- status.c | 4 +- tmux.1 | 6 +- tmux.c | 6 +- tmux.h | 15 +++- 14 files changed, 310 insertions(+), 59 deletions(-) create mode 100644 cmd-show-options.c diff --git a/CHANGES b/CHANGES index 27386400..d69986f9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +15 June 2008 + +* show-options command to show one or all options. + 14 June 2008 * New window options: force-width and force-height. This will force a window @@ -472,4 +476,4 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.119 2008-06-14 16:47:20 nicm Exp $ +$Id: CHANGES,v 1.120 2008-06-15 08:01:54 nicm Exp $ diff --git a/GNUmakefile b/GNUmakefile index 4cad2d5a..1373e7db 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,4 @@ -# $Id: GNUmakefile,v 1.17 2008-06-06 17:20:15 nicm Exp $ +# $Id: GNUmakefile,v 1.18 2008-06-15 08:01:54 nicm Exp $ .PHONY: clean @@ -24,7 +24,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \ cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \ cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \ - cmd-kill-server.c cmd-set-window-option.c \ + cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \ window-scroll.c window-more.c window-copy.c options.c \ tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c diff --git a/Makefile b/Makefile index 24cd3e7b..a8c7eec7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.59 2008-06-05 21:25:00 nicm Exp $ +# $Id: Makefile,v 1.60 2008-06-15 08:01:54 nicm Exp $ .SUFFIXES: .c .o .y .h .PHONY: clean update-index.html upload-index.html @@ -28,7 +28,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \ cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \ cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \ - cmd-kill-server.c cmd-set-window-option.c \ + cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \ window-scroll.c window-more.c window-copy.c options.c \ tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c diff --git a/TODO b/TODO index fd2e4863..cfa96c56 100644 --- a/TODO +++ b/TODO @@ -70,12 +70,13 @@ -- For 0.3 -------------------------------------------------------------------- - clear EOL etc CANNOT rely on term using the current colour/attr and probably should not emulate it doing so -- show-options - key binding bug: random changes? - test and fix wsvt25 - activity/bell should be per-window not per-link? what if it is cur win in session not being watched? +- show-window-options - man page: + show-options set-window-option explanation of -t format config file diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c index b9c236a6..8e010b04 100644 --- a/cmd-send-prefix.c +++ b/cmd-send-prefix.c @@ -1,4 +1,4 @@ -/* $Id: cmd-send-prefix.c,v 1.14 2008-06-05 21:25:00 nicm Exp $ */ +/* $Id: cmd-send-prefix.c,v 1.15 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -49,7 +49,7 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return; - window_key(wl->window, options_get_number(&s->options, "prefix-key")); + window_key(wl->window, options_get_key(&s->options, "prefix-key")); if (ctx->cmdclient != NULL) server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); diff --git a/cmd-set-option.c b/cmd-set-option.c index f6752223..8b6da0d4 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -1,4 +1,4 @@ -/* $Id: cmd-set-option.c,v 1.26 2008-06-07 06:13:21 nicm Exp $ */ +/* $Id: cmd-set-option.c,v 1.27 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -148,7 +148,7 @@ cmd_set_option_exec(struct cmd *self, unused struct cmd_ctx *ctx) ctx->error(ctx, "unknown key: %s", data->value); return; } - options_set_number(oo, "prefix-key", key); + options_set_key(oo, "prefix-key", key); } else if (strcmp(data->option, "status") == 0) { if (bool == -1) { ctx->error(ctx, "bad value: %s", data->value); @@ -169,10 +169,10 @@ cmd_set_option_exec(struct cmd *self, unused struct cmd_ctx *ctx) return; } - colour = options_get_number(oo, "status-colour"); + colour = options_get_colours(oo, "status-colour"); colour &= 0x0f; colour |= number << 4; - options_set_number(oo, "status-colour", colour); + options_set_colours(oo, "status-colour", colour); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); @@ -190,10 +190,10 @@ cmd_set_option_exec(struct cmd *self, unused struct cmd_ctx *ctx) return; } - colour = options_get_number(oo, "status-colour"); + colour = options_get_colours(oo, "status-colour"); colour &= 0xf0; colour |= number; - options_set_number(oo, "status-colour", colour); + options_set_colours(oo, "status-colour", colour); for (i = 0; i < ARRAY_LENGTH(&clients); i++) { c = ARRAY_ITEM(&clients, i); diff --git a/cmd-show-options.c b/cmd-show-options.c new file mode 100644 index 00000000..9e94e690 --- /dev/null +++ b/cmd-show-options.c @@ -0,0 +1,170 @@ +/* $Id: cmd-show-options.c,v 1.1 2008-06-15 08:01:54 nicm Exp $ */ + +/* + * Copyright (c) 2007 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 + +#include "tmux.h" + +/* + * Show options. + */ + +int cmd_show_options_parse(struct cmd *, int, char **, char **); +void cmd_show_options_exec(struct cmd *, struct cmd_ctx *); +void cmd_show_options_send(struct cmd *, struct buffer *); +void cmd_show_options_recv(struct cmd *, struct buffer *); +void cmd_show_options_free(struct cmd *); +void cmd_show_options_print(struct cmd *, char *, size_t); + +struct cmd_show_options_data { + char *target; + int flag_global; +}; + +/* + * XXX Can't use cmd_target because we want -t not to use current if missing + * (this could be a flag??). + */ +const struct cmd_entry cmd_show_options_entry = { + "show-options", "show", + "[-t target-window]", + 0, + NULL, + cmd_show_options_parse, + cmd_show_options_exec, + cmd_show_options_send, + cmd_show_options_recv, + cmd_show_options_free, + cmd_show_options_print +}; + +int +cmd_show_options_parse(struct cmd *self, int argc, char **argv, char **cause) +{ + struct cmd_show_options_data *data; + int opt; + + self->data = data = xmalloc(sizeof *data); + data->target = NULL; + data->flag_global = 1; + + while ((opt = getopt(argc, argv, "t:s:")) != EOF) { + switch (opt) { + case 't': + if (data->target == NULL) + data->target = xstrdup(optarg); + data->flag_global = 0; + break; + default: + goto usage; + } + } + argc -= optind; + argv += optind; + if (argc != 0) + goto usage; + + return (0); + +usage: + xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); + + self->entry->free(self); + return (-1); +} + +void +cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx) +{ + struct cmd_show_options_data *data = self->data; + struct session *s; + struct options *oo; + struct options_entry *o; + + if (data == NULL) + return; + + if (data->flag_global || + ((s = cmd_find_session(ctx, data->target))) == NULL) + oo = &global_options; + else + oo = &s->options; + + SPLAY_FOREACH(o, options_tree, &oo->tree) { + switch (o->type) { + case OPTIONS_STRING: + ctx->print( + ctx, "%s \"%s\"", o->name, o->value.string); + break; + case OPTIONS_NUMBER: + ctx->print(ctx, "%s %lld", o->name, o->value.number); + break; + case OPTIONS_KEY: + ctx->print(ctx, "%s %s", o->name, + key_string_lookup_key(o->value.key)); + break; + case OPTIONS_COLOURS: + ctx->print(ctx, "%s fg=%s, bg=%s", o->name, + screen_colourstring(o->value.colours >> 4), + screen_colourstring(o->value.colours & 0x0f)); + break; + } + } + + if (ctx->cmdclient != NULL) + server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); +} + +void +cmd_show_options_send(struct cmd *self, struct buffer *b) +{ + struct cmd_show_options_data *data = self->data; + + buffer_write(b, data, sizeof *data); + cmd_send_string(b, data->target); +} + +void +cmd_show_options_recv(struct cmd *self, struct buffer *b) +{ + struct cmd_show_options_data *data; + + self->data = data = xmalloc(sizeof *data); + buffer_read(b, data, sizeof *data); + data->target = cmd_recv_string(b); +} + +void +cmd_show_options_free(struct cmd *self) +{ + struct cmd_show_options_data *data = self->data; + + if (data->target != NULL) + xfree(data->target); + xfree(data); +} + +void +cmd_show_options_print(struct cmd *self, char *buf, size_t len) +{ + xsnprintf(buf, len, "%s", self->entry->name); +} diff --git a/cmd.c b/cmd.c index 6685ef0a..73772719 100644 --- a/cmd.c +++ b/cmd.c @@ -1,4 +1,4 @@ -/* $Id: cmd.c,v 1.44 2008-06-05 22:59:38 nicm Exp $ */ +/* $Id: cmd.c,v 1.45 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -51,10 +51,11 @@ const struct cmd_entry *cmd_table[] = { &cmd_rename_window_entry, &cmd_scroll_mode_entry, &cmd_select_window_entry, - &cmd_set_window_option_entry, &cmd_send_keys_entry, &cmd_send_prefix_entry, &cmd_set_option_entry, + &cmd_set_window_option_entry, + &cmd_show_options_entry, &cmd_start_server_entry, &cmd_swap_window_entry, &cmd_switch_client_entry, diff --git a/options.c b/options.c index 69ad750c..24b3f759 100644 --- a/options.c +++ b/options.c @@ -1,4 +1,4 @@ -/* $Id: options.c,v 1.1 2008-06-03 21:42:37 nicm Exp $ */ +/* $Id: options.c,v 1.2 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -30,6 +30,9 @@ SPLAY_GENERATE(options_tree, options_entry, entry, options_cmp); +struct options_entry *options_find1(struct options *, const char *); +struct options_entry *options_find(struct options *, const char *); + int options_cmp(struct options_entry *o1, struct options_entry *o2) { @@ -58,15 +61,38 @@ options_free(struct options *oo) } } -void printflike3 -options_set_string(struct options *oo, const char *name, const char *fmt, ...) +struct options_entry * +options_find1(struct options *oo, const char *name) +{ + struct options_entry p; + + p.name = name; + return (SPLAY_FIND(options_tree, &oo->tree, &p)); +} + +struct options_entry * +options_find(struct options *oo, const char *name) { struct options_entry *o, p; - va_list ap; p.name = name; o = SPLAY_FIND(options_tree, &oo->tree, &p); - if (o == NULL) { + while (o == NULL) { + oo = oo->parent; + if (oo == NULL) + break; + o = SPLAY_FIND(options_tree, &oo->tree, &p); + } + return (o); +} + +void printflike3 +options_set_string(struct options *oo, const char *name, const char *fmt, ...) +{ + struct options_entry *o; + va_list ap; + + if ((o = options_find1(oo, name)) == NULL) { o = xmalloc(sizeof *o); o->name = xstrdup(name); SPLAY_INSERT(options_tree, &oo->tree, o); @@ -82,17 +108,9 @@ options_set_string(struct options *oo, const char *name, const char *fmt, ...) char * options_get_string(struct options *oo, const char *name) { - struct options_entry *o, p; + struct options_entry *o; - p.name = name; - o = SPLAY_FIND(options_tree, &oo->tree, &p); - while (o == NULL) { - oo = oo->parent; - o = SPLAY_FIND(options_tree, &oo->tree, &p); - if (o != NULL) - break; - } - if (o == NULL) + if ((o = options_find(oo, name)) == NULL) fatalx("missing option"); if (o->type != OPTIONS_STRING) fatalx("option not a string"); @@ -102,11 +120,9 @@ options_get_string(struct options *oo, const char *name) void options_set_number(struct options *oo, const char *name, long long value) { - struct options_entry *o, p; + struct options_entry *o; - p.name = name; - o = SPLAY_FIND(options_tree, &oo->tree, &p); - if (o == NULL) { + if ((o = options_find1(oo, name)) == NULL) { o = xmalloc(sizeof *o); o->name = xstrdup(name); SPLAY_INSERT(options_tree, &oo->tree, o); @@ -118,22 +134,72 @@ options_set_number(struct options *oo, const char *name, long long value) } -int +long long options_get_number(struct options *oo, const char *name) { - struct options_entry *o, p; + struct options_entry *o; - p.name = name; - o = SPLAY_FIND(options_tree, &oo->tree, &p); - while (o == NULL) { - oo = oo->parent; - o = SPLAY_FIND(options_tree, &oo->tree, &p); - if (o != NULL) - break; - } - if (o == NULL) + if ((o = options_find(oo, name)) == NULL) fatalx("missing option"); if (o->type != OPTIONS_NUMBER) fatalx("option not a number"); return (o->value.number); } + +void +options_set_key(struct options *oo, const char *name, int value) +{ + struct options_entry *o; + + if ((o = options_find1(oo, name)) == NULL) { + o = xmalloc(sizeof *o); + o->name = xstrdup(name); + SPLAY_INSERT(options_tree, &oo->tree, o); + } else if (o->type == OPTIONS_STRING) + xfree(o->value.string); + + o->type = OPTIONS_KEY; + o->value.key = value; + +} + +int +options_get_key(struct options *oo, const char *name) +{ + struct options_entry *o; + + if ((o = options_find(oo, name)) == NULL) + fatalx("missing option"); + if (o->type != OPTIONS_KEY) + fatalx("option not a key"); + return (o->value.key); +} + +void +options_set_colours(struct options *oo, const char *name, u_char value) +{ + struct options_entry *o; + + if ((o = options_find1(oo, name)) == NULL) { + o = xmalloc(sizeof *o); + o->name = xstrdup(name); + SPLAY_INSERT(options_tree, &oo->tree, o); + } else if (o->type == OPTIONS_STRING) + xfree(o->value.string); + + o->type = OPTIONS_COLOURS; + o->value.colours = value; + +} + +u_char +options_get_colours(struct options *oo, const char *name) +{ + struct options_entry *o; + + if ((o = options_find(oo, name)) == NULL) + fatalx("missing option"); + if (o->type != OPTIONS_COLOURS) + fatalx("option not a colours"); + return (o->value.colours); +} diff --git a/server.c b/server.c index ae97e1d5..53053415 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.63 2008-06-14 16:47:20 nicm Exp $ */ +/* $Id: server.c,v 1.64 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -485,7 +485,7 @@ server_handle_client(struct client *c) struct window *w = c->session->curw->window; int key, prefix; - prefix = options_get_number(&c->session->options, "prefix-key"); + prefix = options_get_key(&c->session->options, "prefix-key"); while (tty_keys_next(&c->tty, &key) == 0) { if (c->flags & CLIENT_PREFIX) { key_bindings_dispatch(key, c); diff --git a/status.c b/status.c index a207be04..23fe4659 100644 --- a/status.c +++ b/status.c @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.25 2008-06-14 16:47:20 nicm Exp $ */ +/* $Id: status.c,v 1.26 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -36,7 +36,7 @@ status_redraw(struct client *c) u_char scolour; u_int slines; - scolour = options_get_number(&c->session->options, "status-colour"); + scolour = options_get_colours(&c->session->options, "status-colour"); slines = options_get_number(&c->session->options, "status-lines"); if (slines == 0 || c->sy <= slines) return; diff --git a/tmux.1 b/tmux.1 index 19ea939c..55474806 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.32 2008-06-11 06:19:56 nicm Exp $ +.\" $Id: tmux.1,v 1.33 2008-06-15 08:01:54 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -136,7 +136,7 @@ to exit from it. .Sh KEY BINDINGS .Nm may be controlled from an attached client by using a key combination of a -prefix, +prefix key, .Ql ^B (ctrl-B) by default, followed by a command key. .Pp @@ -505,7 +505,7 @@ The default is Set the maximum number of lines held in window history. This setting applies only to new windows - existing window histories are not resized and retain the limit at the point they were created. -.It Ic prefix Ar key +.It Ic prefix-key Ar key Set the current prefix key. .It Xo Ic status .Op Ic on | Ic off diff --git a/tmux.c b/tmux.c index be11763a..fe6bf773 100644 --- a/tmux.c +++ b/tmux.c @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.54 2008-06-06 17:20:30 nicm Exp $ */ +/* $Id: tmux.c,v 1.55 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -200,10 +200,10 @@ main(int argc, char **argv) options_init(&global_options, NULL); options_set_number(&global_options, "status-lines", 1); - options_set_number(&global_options, "status-colour", 0x02); + options_set_colours(&global_options, "status-colour", 0x02); options_set_number(&global_options, "bell-action", BELL_ANY); options_set_number(&global_options, "history-limit", 2000); - options_set_number(&global_options, "prefix-key", META); + options_set_key(&global_options, "prefix-key", META); options_set_string(&global_options, "status-left", ""); options_set_string( &global_options, "status-right", "%%H:%%M %%d-%%b-%%y"); diff --git a/tmux.h b/tmux.h index fadd9329..69479a05 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.141 2008-06-14 16:47:20 nicm Exp $ */ +/* $Id: tmux.h,v 1.142 2008-06-15 08:01:54 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -557,11 +557,15 @@ struct options_entry { enum { OPTIONS_STRING, - OPTIONS_NUMBER + OPTIONS_NUMBER, + OPTIONS_KEY, + OPTIONS_COLOURS } type; union { char *string; long long number; + int key; + u_char colours; } value; SPLAY_ENTRY(options_entry) entry; @@ -772,7 +776,11 @@ void printflike3 options_set_string( struct options *, const char *, const char *, ...); char *options_get_string(struct options *, const char *); void options_set_number(struct options *, const char *, long long); -int options_get_number(struct options *, const char *); +long long options_get_number(struct options *, const char *); +void options_set_key(struct options *, const char *, int); +int options_get_key(struct options *, const char *); +void options_set_colours(struct options *, const char *, u_char); +u_char options_get_colours(struct options *, const char *); /* tty.c */ void tty_init(struct tty *, char *, char *); @@ -842,6 +850,7 @@ extern const struct cmd_entry cmd_send_keys_entry; extern const struct cmd_entry cmd_send_prefix_entry; extern const struct cmd_entry cmd_set_option_entry; extern const struct cmd_entry cmd_set_window_option_entry; +extern const struct cmd_entry cmd_show_options_entry; extern const struct cmd_entry cmd_start_server_entry; extern const struct cmd_entry cmd_swap_window_entry; extern const struct cmd_entry cmd_switch_client_entry;