summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2008-12-08 16:19:51 +0000
committernicm <nicm>2008-12-08 16:19:51 +0000
commit8256adb023f35b3474ddac0c447c27df20995a23 (patch)
treec63a0e9b6996fef3b71a4332334478c541d7b99f
parentff0412de8c8aa2233ff87c6b8e1e4bc61dbbfe11 (diff)
downloadtmux-old-8256adb023f35b3474ddac0c447c27df20995a23.tar.gz
tmux-old-8256adb023f35b3474ddac0c447c27df20995a23.tar.bz2
tmux-old-8256adb023f35b3474ddac0c447c27df20995a23.zip
Make window options work the same was as session options, add mode-fg/mode-bg options, force -g for global on set/show/setw/showw/
-rw-r--r--CHANGES44
-rw-r--r--GNUmakefile6
-rw-r--r--Makefile4
-rw-r--r--TODO2
-rw-r--r--cmd-generic.c159
-rw-r--r--cmd-set-option.c281
-rw-r--r--cmd-set-window-option.c335
-rw-r--r--cmd-show-options.c113
-rw-r--r--cmd-show-window-options.c77
-rw-r--r--cmd-string.c5
-rw-r--r--examples/n-marriott.conf21
-rw-r--r--input.c2
-rw-r--r--log.c3
-rw-r--r--options-cmd.c152
-rw-r--r--resize.c16
-rw-r--r--screen-redraw.c8
-rw-r--r--screen-write.c4
-rw-r--r--screen.c5
-rw-r--r--server.c4
-rw-r--r--session.c5
-rw-r--r--status.c11
-rw-r--r--tmux.c17
-rw-r--r--tmux.h101
-rw-r--r--window-copy.c16
-rw-r--r--window-more.c9
-rw-r--r--window-scroll.c9
-rw-r--r--window.c3
27 files changed, 667 insertions, 745 deletions
diff --git a/CHANGES b/CHANGES
index 55cf901f..3f761b72 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,37 @@
+06 December 2008
+
+* Bring set/setw/show/showw into line with other commands. This means that by
+ default they now affect the current window (if any); the new -g flag must be
+ passed to set the global options. This changes the behaviour of set/show and
+ WILL BREAK CURRENT CONFIGURATIONS.
+
+ In summary, whether in the configuration file, the command prompt, or a key
+ binding, use -g to set a global option, use -t to specify a particular window
+ or session, or omit both to try and use the current window or session.
+
+ This makes set/show a bit of a pain but is the correct behaviour for
+ setw/showw and is the same as every other command, so we can put up with a
+ bit of pain for consistency.
+* Redo window options. They now work in the same way to session options with a
+ global options set. showw/setw commands now have similar syntax to show/set
+ (including the ability to use abbreviations).
+
+ PLEASE NOTE this includes the following configuration-breaking changes:
+
+ - remain-by-default is now GONE, use "setw -g remain-on-exit" to apply the
+ global window option instead;
+ - mode-keys is now a window option rather than session - use "setw [-g]
+ mode-keys" instead of set.
+
+ There are also some additions:
+
+ - message-fg and message-bg session options to control status line message
+ colours;
+ - mode-fg and mode-bg window options to set colours in window modes such as
+ copy mode.
+
+ The options code still a mess and now there is twice as much of it :-(.
+
02 December 2008
* Add support for including the window title in status-left or status-right
@@ -272,7 +306,7 @@
07 June 2008
-* Make status-interval actually changable.
+* Make status-interval actually changeable.
06 June 2008
@@ -355,7 +389,7 @@
* -s to specify session name now supports fnmatch(3) wildcards; if multiple
sessions are found, or if no -s is specified, the most newly created is used.
* If no command is specified, assume new-session. As a byproduct, clean up
- command default values into seperate init functions.
+ command default values into separate init functions.
* kill-server command.
02 June 2008
@@ -669,7 +703,7 @@
a serious problem when it comes to things like scrolling. This change
consolidates all the range checking and limiting together which should make
it easier.
-* (mxey) Added window remaming, like "tmux rename [-s session] [-i index] name"
+* (mxey) Added window renaming, like "tmux rename [-s session] [-i index] name"
27 September 2007
@@ -729,3 +763,7 @@
customisation.
$Id$
+
+ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
+ LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB
+ LocalWords: dstidx srcname srcidx winlink lsw nabc sabc Exp
diff --git a/GNUmakefile b/GNUmakefile
index 210d1ec5..5ac0c676 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -3,11 +3,11 @@
.PHONY: clean
PROG= tmux
-VERSION= 0.5
+VERSION= 0.6
DATE= $(shell date +%Y%m%d-%H%M)
-#DEBUG= 1
+DEBUG= 1
META?= \002
@@ -33,7 +33,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c \
window-scroll.c window-more.c window-copy.c options.c paste.c \
- tty.c tty-keys.c tty-write.c colour.c utf8.c
+ tty.c tty-keys.c tty-write.c colour.c utf8.c options-cmd.c
CC?= gcc
INCDIRS+= -I. -I-
diff --git a/Makefile b/Makefile
index 3726594a..584cb8d0 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
.PHONY: clean update-index.html upload-index.html
PROG= tmux
-VERSION= 0.5
+VERSION= 0.6
OS!= uname
REL!= uname -r
@@ -37,7 +37,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c \
window-scroll.c window-more.c window-copy.c options.c paste.c \
- tty.c tty-keys.c tty-write.c colour.c utf8.c
+ tty.c tty-keys.c tty-write.c colour.c utf8.c options-cmd.c
CC?= cc
INCDIRS+= -I. -I- -I/usr/local/include
diff --git a/TODO b/TODO
index 34dd15c4..be612baf 100644
--- a/TODO
+++ b/TODO
@@ -52,3 +52,5 @@
- vi half page scroll
- why do home/end work in emacs outside tmux but not inside?
- document status line options, title bits
+- document mode-fg/mode-bg/message-fg/message-bg
+- document window options changes
diff --git a/cmd-generic.c b/cmd-generic.c
index cfa7d435..6586959d 100644
--- a/cmd-generic.c
+++ b/cmd-generic.c
@@ -44,7 +44,7 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
cmd_target_init(self, 0);
data = self->data;
- while ((opt = getopt(argc, argv, GETOPT_PREFIX "dkt:")) != EOF) {
+ while ((opt = getopt(argc, argv, GETOPT_PREFIX "dgkt:")) != EOF) {
switch (opt) {
case 'd':
if (self->entry->flags & CMD_DFLAG) {
@@ -52,6 +52,12 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
break;
}
goto usage;
+ case 'g':
+ if (self->entry->flags & CMD_GFLAG) {
+ data->flags |= CMD_GFLAG;
+ break;
+ }
+ goto usage;
case 'k':
if (self->entry->flags & CMD_KFLAG) {
data->flags |= CMD_KFLAG;
@@ -137,6 +143,8 @@ cmd_target_print(struct cmd *self, char *buf, size_t len)
return;
if (off < len && data->flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, " -d");
+ if (off < len && data->flags & CMD_GFLAG)
+ off += xsnprintf(buf + off, len - off, " -g");
if (off < len && data->flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, " -k");
if (off < len && data->target != NULL)
@@ -166,7 +174,7 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
cmd_srcdst_init(self, 0);
data = self->data;
- while ((opt = getopt(argc, argv, GETOPT_PREFIX "dks:t:")) != EOF) {
+ while ((opt = getopt(argc, argv, GETOPT_PREFIX "dgks:t:")) != EOF) {
switch (opt) {
case 'd':
if (self->entry->flags & CMD_DFLAG) {
@@ -174,6 +182,12 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
break;
}
goto usage;
+ case 'g':
+ if (self->entry->flags & CMD_GFLAG) {
+ data->flags |= CMD_GFLAG;
+ break;
+ }
+ goto usage;
case 'k':
if (self->entry->flags & CMD_KFLAG) {
data->flags |= CMD_KFLAG;
@@ -267,6 +281,8 @@ cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
return;
if (off < len && data->flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, " -d");
+ if (off < len && data->flags & CMD_GFLAG)
+ off += xsnprintf(buf + off, len - off, " -g");
if (off < len && data->flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, " -k");
if (off < len && data->src != NULL)
@@ -299,7 +315,7 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
cmd_buffer_init(self, 0);
data = self->data;
- while ((opt = getopt(argc, argv, GETOPT_PREFIX "b:dkt:")) != EOF) {
+ while ((opt = getopt(argc, argv, GETOPT_PREFIX "b:dgkt:")) != EOF) {
switch (opt) {
case 'b':
if (data->buffer == -1) {
@@ -318,6 +334,12 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
break;
}
goto usage;
+ case 'g':
+ if (self->entry->flags & CMD_GFLAG) {
+ data->flags |= CMD_GFLAG;
+ break;
+ }
+ goto usage;
case 'k':
if (self->entry->flags & CMD_KFLAG) {
data->flags |= CMD_KFLAG;
@@ -404,6 +426,8 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len)
return;
if (off < len && data->flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, " -d");
+ if (off < len && data->flags & CMD_GFLAG)
+ off += xsnprintf(buf + off, len - off, " -g");
if (off < len && data->flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, " -k");
if (off < len && data->buffer != -1)
@@ -413,3 +437,132 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len)
if (off < len && data->arg != NULL)
off += xsnprintf(buf + off, len - off, " %s", data->arg);
}
+
+void
+cmd_option_init(struct cmd *self, unused int key)
+{
+ struct cmd_option_data *data;
+
+ self->data = data = xmalloc(sizeof *data);
+ data->flags = 0;
+ data->target = NULL;
+ data->option = NULL;
+ data->value = NULL;
+}
+
+int
+cmd_option_parse(struct cmd *self, int argc, char **argv, char **cause)
+{
+ struct cmd_option_data *data;
+ int opt;
+
+ /* Don't use the entry version since it may be dependent on key. */
+ cmd_option_init(self, 0);
+ data = self->data;
+
+ while ((opt = getopt(argc, argv, GETOPT_PREFIX "dgkt:")) != EOF) {
+ switch (opt) {
+ case 'd':
+ if (self->entry->flags & CMD_DFLAG) {
+ data->flags |= CMD_DFLAG;
+ break;
+ }
+ goto usage;
+ case 'g':
+ if (self->entry->flags & CMD_GFLAG) {
+ data->flags |= CMD_GFLAG;
+ break;
+ }
+ goto usage;
+ case 'k':
+ if (self->entry->flags & CMD_KFLAG) {
+ data->flags |= CMD_KFLAG;
+ break;
+ }
+ goto usage;
+ case 't':
+ if (data->target == NULL)
+ data->target = xstrdup(optarg);
+ break;
+ default:
+ goto usage;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 2) {
+ data->option = xstrdup(argv[0]);
+ data->value = xstrdup(argv[1]);
+ } else if (argc == 1)
+ data->option = xstrdup(argv[0]);
+ else
+ goto usage;
+ return (0);
+
+usage:
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
+
+ self->entry->free(self);
+ return (-1);
+}
+
+void
+cmd_option_send(struct cmd *self, struct buffer *b)
+{
+ struct cmd_option_data *data = self->data;
+
+ buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->target);
+ cmd_send_string(b, data->option);
+ cmd_send_string(b, data->value);
+}
+
+void
+cmd_option_recv(struct cmd *self, struct buffer *b)
+{
+ struct cmd_option_data *data;
+
+ self->data = data = xmalloc(sizeof *data);
+ buffer_read(b, data, sizeof *data);
+ data->target = cmd_recv_string(b);
+ data->option = cmd_recv_string(b);
+ data->value = cmd_recv_string(b);
+}
+
+void
+cmd_option_free(struct cmd *self)
+{
+ struct cmd_option_data *data = self->data;
+
+ if (data->target != NULL)
+ xfree(data->target);
+ if (data->option != NULL)
+ xfree(data->option);
+ if (data->value != NULL)
+ xfree(data->value);
+ xfree(data);
+}
+
+void
+cmd_option_print(struct cmd *self, char *buf, size_t len)
+{
+ struct cmd_option_data *data = self->data;
+ size_t off = 0;
+
+ off += xsnprintf(buf, len, "%s", self->entry->name);
+ if (data == NULL)
+ return;
+ if (off < len && data->flags & CMD_DFLAG)
+ off += xsnprintf(buf + off, len - off, " -d");
+ if (off < len && data->flags & CMD_GFLAG)
+ off += xsnprintf(buf + off, len - off, " -g");
+ if (off < len && data->flags & CMD_KFLAG)
+ off += xsnprintf(buf + off, len - off, " -k");
+ if (off < len && data->target != NULL)
+ off += xsnprintf(buf + off, len - off, " -t %s", data->target);
+ if (off < len && data->option != NULL)
+ off += xsnprintf(buf + off, len - off, " %s", data->option);
+ if (off < len && data->value != NULL)
+ off += xsnprintf(buf + off, len - off, " %s", data->value);
+}
diff --git a/cmd-set-option.c b/cmd-set-option.c
index a2ba99a5..e58b35e1 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -28,132 +28,61 @@
* Set an option.
*/
-int cmd_set_option_parse(struct cmd *, int, char **, char **);
void cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
-void cmd_set_option_send(struct cmd *, struct buffer *);
-void cmd_set_option_recv(struct cmd *, struct buffer *);
-void cmd_set_option_free(struct cmd *);
-void cmd_set_option_print(struct cmd *, char *, size_t);
-
-struct cmd_set_option_data {
- char *target;
- int flag_global;
- char *option;
- char *value;
-};
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
"[-t target-session] option value",
- 0,
+ CMD_GFLAG,
NULL,
- cmd_set_option_parse,
+ cmd_option_parse,
cmd_set_option_exec,
- cmd_set_option_send,
- cmd_set_option_recv,
- cmd_set_option_free,
- cmd_set_option_print
+ cmd_option_send,
+ cmd_option_recv,
+ cmd_option_free,
+ cmd_option_print
};
const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL
};
-const char *set_option_mode_keys_list[] = {
- "emacs", "vi", NULL
-};
const struct set_option_entry set_option_table[NSETOPTION] = {
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "default-command", SET_OPTION_STRING, 0, 0, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
- { "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
+ { "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
+ { "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "prefix", SET_OPTION_KEY, 0, 0, NULL },
- { "remain-by-default", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
{ "status", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "status-left", SET_OPTION_STRING, 0, 0, NULL },
- { "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
+ { "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
- { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
};
-void set_option_string(struct cmd_ctx *,
- struct options *, const struct set_option_entry *, char *);
-void set_option_number(struct cmd_ctx *,
- struct options *, const struct set_option_entry *, char *);
-void set_option_key(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_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 *);
-
-int
-cmd_set_option_parse(struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_set_option_data *data;
- int opt;
-
- self->data = data = xmalloc(sizeof *data);
- data->target = NULL;
- data->flag_global = 1;
- data->option = NULL;
- data->value = NULL;
-
- while ((opt = getopt(argc, argv, GETOPT_PREFIX "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 != 1 && argc != 2)
- goto usage;
-
- data->option = xstrdup(argv[0]);
- if (argc == 2)
- data->value = xstrdup(argv[1]);
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
-}
-
void
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_set_option_data *data = self->data;
+ struct cmd_option_data *data = self->data;
struct session *s;
struct client *c;
struct options *oo;
const struct set_option_entry *entry;
u_int i;
- if (data == NULL)
- return;
-
- if (data->flag_global ||
- ((s = cmd_find_session(ctx, data->target))) == NULL)
+ if (data->flags & CMD_GFLAG)
oo = &global_options;
- else
+ else {
+ if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ return;
oo = &s->options;
+ }
if (*data->option == '\0') {
ctx->error(ctx, "invalid option");
@@ -211,183 +140,3 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
-
-void
-set_option_string(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
-{
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
-
- options_set_string(oo, entry->name, "%s", value);
-}
-
-void
-set_option_number(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
-{
- 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;
- }
- options_set_number(oo, entry->name, number);
-}
-
-void
-set_option_key(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
-{
- int key;
-
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
-
- if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
- ctx->error(ctx, "unknown key: %s", value);
- return;
- }
- options_set_number(oo, entry->name, key);
-
-}
-
-void
-set_option_colour(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
-{
- u_char colour;
-
- if (value == NULL) {
- ctx->error(ctx, "empty value");
- return;
- }
-
- if ((colour = colour_fromstring(value)) > 8) {
- ctx->error(ctx, "bad colour: %s", value);
- return;
- }
-
- options_set_number(oo, entry->name, colour);
-}
-
-void
-set_option_flag(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
-{
- 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;
- }
- }
-
- options_set_number(oo, entry->name, flag);
-}
-
-void
-set_option_choice(struct cmd_ctx *ctx, struct options *oo,
- const struct set_option_entry *entry, char *value)
-{
- 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;
- }
-
- options_set_number(oo, entry->name, choice);
-}
-
-void
-cmd_set_option_send(struct cmd *self, struct buffer *b)
-{
- struct cmd_set_option_data *data = self->data;
-
- buffer_write(b, data, sizeof *data);
- cmd_send_string(b, data->target);
- cmd_send_string(b, data->option);
- cmd_send_string(b, data->value);
-}
-
-void
-cmd_set_option_recv(struct cmd *self, struct buffer *b)
-{
- struct cmd_set_option_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- buffer_read(b, data, sizeof *data);
- data->target = cmd_recv_string(b);
- data->option = cmd_recv_string(b);
- data->value = cmd_recv_string(b);
-}
-
-void
-cmd_set_option_free(struct cmd *self)
-{
- struct cmd_set_option_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- if (data->option != NULL)
- xfree(data->option);
- if (data->value != NULL)
- xfree(data->value);
- xfree(data);
-}
-
-void
-cmd_set_option_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_set_option_data *data = self->data;
- size_t off = 0;
-
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return;
- if (off < len && data->option != NULL)
- off += xsnprintf(buf + off, len - off, " %s", data->option);
- if (off < len && data->value != NULL)
- off += xsnprintf(buf + off, len - off, " %s", data->value);
-}
diff --git a/cmd-set-window-option.c b/cmd-set-window-option.c
index ff155d76..789d345d 100644
--- a/cmd-set-window-option.c
+++ b/cmd-set-window-option.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
- * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
+ * 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
@@ -35,286 +35,105 @@ void cmd_set_window_option_recv(struct cmd *, struct buffer *);
void cmd_set_window_option_free(struct cmd *);
void cmd_set_window_option_print(struct cmd *, char *, size_t);
-struct cmd_set_window_option_data {
- char *target;
- char *option;
- char *value;
-};
-
const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw",
- "[-t target-window] option value",
- 0,
+ "[-g] [-t target-window] option value",
+ CMD_GFLAG,
NULL,
- cmd_set_window_option_parse,
+ cmd_option_parse,
cmd_set_window_option_exec,
- cmd_set_window_option_send,
- cmd_set_window_option_recv,
- cmd_set_window_option_free,
- cmd_set_window_option_print
+ cmd_option_send,
+ cmd_option_recv,
+ cmd_option_free,
+ cmd_option_print
};
-int
-cmd_set_window_option_parse(
- struct cmd *self, int argc, char **argv, char **cause)
-{
- struct cmd_set_window_option_data *data;
- int opt;
-
- self->data = data = xmalloc(sizeof *data);
- data->target = NULL;
- data->option = NULL;
- data->value = NULL;
-
- while ((opt = getopt(argc, argv, GETOPT_PREFIX "t:")) != EOF) {
- switch (opt) {
- case 't':
- if (data->target == NULL)
- data->target = xstrdup(optarg);
- break;
- default:
- goto usage;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc != 1 && argc != 2)
- goto usage;
-
- data->option = xstrdup(argv[0]);
- if (argc == 2)
- data->value = xstrdup(argv[1]);
-
- return (0);
-
-usage:
- xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
-
- self->entry->free(self);
- return (-1);
-}
+const char *set_option_mode_keys_list[] = {
+ "emacs", "vi", NULL
+};
+const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
+ { "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
+ { "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
+ { "force-width", SET_OPTION_NUMBER, 0, INT_MAX, 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 },
+ { "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
+ { "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
+ { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
+};
void
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_set_window_option_data *data = self->data;
- struct winlink *wl;
- struct session *s;
- const char *errstr;
- int number, flag;
- u_int i;
-
- if (data == NULL)
- return;
-
- wl = cmd_find_window(ctx, data->target, &s);
- if (wl == NULL)
- return;
+ struct cmd_option_data *data = self->data;
+ struct winlink *wl;
+ struct client *c;
+ struct options *oo;
+ const struct set_option_entry *entry;
+ u_int i;
+
+ if (data->flags & CMD_GFLAG)
+ oo = &global_window_options;
+ else {
+ if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ return;
+ oo = &wl->window->options;
+ }
if (*data->option == '\0') {
ctx->error(ctx, "invalid option");
return;
}
- number = -1;
- if (data->value != NULL) {
- number = strtonum(data->value, 0, INT_MAX, &errstr);
-
- flag = -1;
- if (number == 1 || strcasecmp(data->value, "on") == 0 ||
- strcasecmp(data->value, "yes") == 0)
- flag = 1;
- else if (number == 0 || strcasecmp(data->value, "off") == 0 ||
- strcasecmp(data->value, "no") == 0)
- flag = 0;
- } else
- flag = -2;
-
- if (strcmp(data->option, "monitor-activity") == 0) {
- if (flag == -1) {
- ctx->error(ctx, "bad value: %s", data->value);
+ entry = NULL;
+ for (i = 0; i < NSETWINDOWOPTION; i++) {
+ if (strncmp(set_window_option_table[i].name,
+ data->option, strlen(data->option)) != 0)
+ continue;
+ if (entry != NULL) {
+ ctx->error(ctx, "ambiguous option: %s", data->option);
return;
}
+ entry = &set_window_option_table[i];
- if (flag == -2)
- wl->window->flags ^= WINDOW_MONITOR;
- else {
- if (flag)
- wl->window->flags |= WINDOW_MONITOR;
- else
- wl->window->flags &= ~WINDOW_MONITOR;
- }
-
- if (wl->window->flags & WINDOW_MONITOR) {
- ctx->info(ctx, "window %s:%d: set %s",
- s->name, wl->idx, data->option);
- } else {
- ctx->info(ctx, "window %s:%d: cleared %s",
- s->name, wl->idx, data->option);
- }
-
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s != NULL)
- session_alert_cancel(s, wl);
- }
- } else if (strcmp(data->option, "aggressive-resize") == 0) {
- if (flag == -1) {
- ctx->error(ctx, "bad value: %s", data->value);
- return;
- }
-
- if (flag == -2)
- wl->window->flags ^= WINDOW_AGGRESSIVE;
- else {
- if (flag)
- wl->window->flags |= WINDOW_AGGRESSIVE;
- else
- wl->window->flags &= ~WINDOW_AGGRESSIVE;
- }
-
- if (wl->window->flags & WINDOW_AGGRESSIVE) {
- ctx->info(ctx, "window %s:%d: set %s",
- s->name, wl->idx, data->option);
- } else {
- ctx->info(ctx, "window %s:%d: cleared %s",
- s->name, wl->idx, data->option);
- }
-
- recalculate_sizes();
- } else if (strcmp(data->option, "utf8") == 0) {
- if (flag == -1) {
- ctx->error(ctx, "bad value: %s", data->value);
- return;
- }
-
- if (flag == -2)
- wl->window->flags ^= WINDOW_UTF8;
- else {
- if (flag)
- wl->window->flags |= WINDOW_UTF8;
- else
- wl->window->flags &= ~WINDOW_UTF8;
- }
-
- if (wl->window->flags & WINDOW_UTF8) {
- ctx->info(ctx, "window %s:%d: set %s",
- s->name, wl->idx, data->option);
- } else {
- ctx->info(ctx, "window %s:%d: cleared %s",
- s->name, wl->idx, data->option);
- }
-
- recalculate_sizes();
- } else if (strcmp(data->option, "force-width") == 0) {
- if (data->value == NULL || number == -1) {
- ctx->error(ctx, "invalid value");
- return;
- }
- if (errstr != NULL) {
- ctx->error(ctx, "force-width %s", errstr);
- return;
- }
- if (number == 0)
- wl->window->limitx = UINT_MAX;
- else
- wl->window->limitx = number;
-
- ctx->info(ctx, "window %s:%d: set force-width %u",
- s->name, wl->idx, number);
-
- recalculate_sizes();
- } else if (strcmp(data->option, "force-height") == 0) {
- if (data->value == NULL || number == -1) {
- ctx->error(ctx, "invalid value");
- return;
- }
- if (errstr != NULL) {
- ctx->error(ctx, "force-height %s", errstr);
- return;
- }
- if (number == 0)
- wl->window->limity = UINT_MAX;
- else
- wl->window->limity = number;
-
- ctx->info(ctx, "window %s:%d: set force-height %u",
- s->name, wl->idx, number);
-
- recalculate_sizes();
- } else if (strcmp(data->option, "remain-on-exit") == 0) {
- if (flag == -1) {
- ctx->error(ctx, "bad value: %s", data->value);
- return;
- }
-
- if (flag == -2)
- wl->window->flags ^= WINDOW_ZOMBIFY;
- else {
- if (flag)
- wl->window->flags |= WINDOW_ZOMBIFY;
- else
- wl->window->flags &= ~WINDOW_ZOMBIFY;
- }
- } else {
+ /* Bail now if an exact match. */
+ if (strcmp(entry->name, data->option) == 0)
+ break;
+ }
+ if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->option);
return;
}
- if (ctx->cmdclient != NULL)
- server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
-}
-
-void
-cmd_set_window_option_send(struct cmd *self, struct buffer *b)
-{
- struct cmd_set_window_option_data *data = self->data;
-
- buffer_write(b, data, sizeof *data);
- cmd_send_string(b, data->target);
- cmd_send_string(b, data->option);
- cmd_send_string(b, data->value);
-}
-
-void
-cmd_set_window_option_recv(struct cmd *self, struct buffer *b)
-{
- struct cmd_set_window_option_data *data;
-
- self->data = data = xmalloc(sizeof *data);
- buffer_read(b, data, sizeof *data);
- data->target = cmd_recv_string(b);
- data->option = cmd_recv_string(b);
- data->value = cmd_recv_string(b);
-}
-
-void
-cmd_set_window_option_free(struct cmd *self)
-{
- struct cmd_set_window_option_data *data = self->data;
-
- if (data->target != NULL)
- xfree(data->target);
- if (data->option != NULL)
- xfree(data->option);
- if (data->value != NULL)
- xfree(data->value);
- xfree(data);
-}
+ switch (entry->type) {
+ case SET_OPTION_STRING:
+ set_option_string(ctx, oo, entry, data->value);
+ break;
+ case SET_OPTION_NUMBER:
+ set_option_number(ctx, oo, entry, data->value);
+ break;
+ case SET_OPTION_KEY:
+ set_option_key(ctx, oo, entry, data->value);
+ break;
+ case SET_OPTION_COLOUR:
+ set_option_colour(ctx, oo, entry, data->value);
+ break;
+ case SET_OPTION_FLAG:
+ set_option_flag(ctx, oo, entry, data->value);
+ break;
+ case SET_OPTION_CHOICE:
+ set_option_choice(ctx, oo, entry, data->value);
+ break;
+ }
-void
-cmd_set_window_option_print(struct cmd *self, char *buf, size_t len)
-{
- struct cmd_set_window_option_data *data = self->data;
- size_t off = 0;
+ 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);
+ }
- off += xsnprintf(buf, len, "%s", self->entry->name);
- if (data == NULL)
- return;
- if (off < len && data->target != NULL)
- off += xsnprintf(buf + off, len - off, " -t %s", data->target);
- if (off < len && data->option != NULL)
- off += xsnprintf(buf + off, len - off, " %s", data->option);
- if (off < len && data->value != NULL)
- off += xsnprintf(buf + off, len - off, " %s", data->value);
+ if (ctx->cmdclient != NULL)
+ server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-show-options.c b/cmd-show-options.c
index 961990ba..d55002cb 100644
--- a/cmd-show-options.c
+++ b/cmd-show-options.c
@@ -28,74 +28,25 @@
* 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-session]",
- 0,
- NULL,
- cmd_show_options_parse,
+ "[-g] " CMD_TARGET_SESSION_USAGE,
+ CMD_GFLAG,
+ cmd_target_init,
+ cmd_target_parse,
cmd_show_options_exec,
- cmd_show_options_send,
- cmd_show_options_recv,
- cmd_show_options_free,
- cmd_show_options_print
+ cmd_target_send,
+ cmd_target_recv,
+ cmd_target_free,
+ cmd_target_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, GETOPT_PREFIX "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 cmd_target_data *data = self->data;
struct session *s;
struct options *oo;
const struct set_option_entry *entry;
@@ -103,14 +54,13 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
char *vs;
long long vn;
- if (data == NULL)
- return;
-
- if (data->flag_global ||
- ((s = cmd_find_session(ctx, data->target))) == NULL)
+ if (data->flags & CMD_GFLAG)
oo = &global_options;
- else
+ else {
+ if ((s = cmd_find_session(ctx, data->target)) == NULL)
+ return;
oo = &s->options;
+ }
for (i = 0; i < NSETOPTION; i++) {
entry = &set_option_table[i];
@@ -155,38 +105,3 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
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-show-window-options.c b/cmd-show-window-options.c
index 949954f8..1d426f12 100644
--- a/cmd-show-window-options.c
+++ b/cmd-show-window-options.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
- * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
+ * 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
@@ -20,6 +20,7 @@
#include <getopt.h>
#include <stdlib.h>
+#include <string.h>
#include "tmux.h"
@@ -31,8 +32,8 @@ void cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw",
- CMD_TARGET_WINDOW_USAGE,
- 0,
+ "[-g] " CMD_TARGET_WINDOW_USAGE,
+ CMD_GFLAG,
cmd_target_init,
cmd_target_parse,
cmd_show_window_options_exec,
@@ -45,25 +46,61 @@ const struct cmd_entry cmd_show_window_options_entry = {
void
cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
- struct cmd_target_data *data = self->data;
- struct winlink *wl;
- struct session *s;
+ struct cmd_target_data *data = self->data;
+ struct winlink *wl;
+ struct options *oo;
+ const struct set_option_entry *entry;
+ u_int i;
+ char *vs;
+ long long vn;
- if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
- return;
+ if (data->flags & CMD_GFLAG)
+ oo = &global_window_options;
+ else {
+ if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ return;
+ oo = &wl->window->options;
+ }
- if (wl->window->flags & WINDOW_AGGRESSIVE)
- ctx->print(ctx, "aggressive-resize");
- if (wl->window->limitx != UINT_MAX)
- ctx->print(ctx, "force-width %u", wl->window->limitx);
- if (wl->window->limity != UINT_MAX)
- ctx->print(ctx, "force-height %u", wl->window->limity);
- if (wl->window->flags & WINDOW_MONITOR)
- ctx->print(ctx, "monitor-activity");
- if (wl->window->flags & WINDOW_ZOMBIFY)
- ctx->print(ctx, "remain-on-exit");
- if (wl->window->flags & WINDOW_UTF8)
- ctx->print(ctx, "utf8");
+ for (i = 0; i < NSETWINDOWOPTION; i++) {
+ entry = &set_window_option_table[i];
+
+ if (options_find1(oo, entry->name) == NULL)
+ continue;
+
+ switch (entry->type) {
+ case SET_OPTION_STRING:
+ vs = options_get_string(oo, entry->name);
+ ctx->print(ctx, "%s \"%s\"", entry->name, vs);
+ break;
+ case SET_OPTION_NUMBER:
+ vn = options_get_number(oo, entry->name);
+ ctx->print(ctx, "%s %lld", entry->name, vn);
+ break;
+ case SET_OPTION_KEY:
+ vn = options_get_number(oo, entry->name);
+ ctx->print(ctx, "%s %s",
+ entry->name, key_string_lookup_key(vn));
+ break;
+ case SET_OPTION_COLOUR:
+ vn = options_get_number(oo, entry->name);
+ ctx->print(ctx, "%s %s",
+ entry->name, colour_tostring(vn));
+ break;
+ case SET_OPTION_FLAG:
+ vn = options_get_number(oo, entry->name);
+ if (vn)
+ ctx->print(ctx, "%s on", entry->name);
+ else
+ ctx->print(ctx, "%s off", entry->name);
+ break;
+ case SET_OPTION_CHOICE:
+ vn = options_get_number(oo, entry->name);
+ ctx->print(ctx, "%s %s",
+ entry->name, entry->choices[vn]);
+ break;
+ }
+ }
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-string.c b/cmd-string.c
index e1e7e81f..111c5990 100644
--- a/cmd-string.c
+++ b/cmd-string.c
@@ -131,7 +131,8 @@ cmd_string_parse(const char *s, struct cmd **cmd, char **cause)
if (argc == 0)
goto out;
- *cmd = cmd_parse(argc, argv, cause);
+ if ((*cmd = cmd_parse(argc, argv, cause)) == NULL)
+ goto error;
rval = 0;
goto out;
default:
@@ -145,7 +146,7 @@ cmd_string_parse(const char *s, struct cmd **cmd, char **cause)
}
error:
- xasprintf(cause, "bad command: %s", s);
+ xasprintf(cause, "invalid or unknown command: %s", s);
out:
if (buf != NULL)
diff --git a/examples/n-marriott.conf b/examples/n-marriott.conf
index 5650f004..c3695fbc 100644
--- a/examples/n-marriott.conf
+++ b/examples/n-marriott.conf
@@ -1,32 +1,29 @@
# Default global options.
-set status-bg green
-set default-command "exec /bin/ksh -l"
-set bell-action none
+set -g status-bg green
+set -g status-right-length 60
+set -g default-command "exec /bin/ksh -l"
+set -g bell-action none
+
+# Default global window options.
+setw -g remain-on-exit on
# Prefix key.
-set prefix ^A
+set -g prefix ^A
unbind ^B
bind ^A send-prefix
# Keys to switch session.
bind q switch -t0
-bind Q switch -t0
bind w switch -t1
-bind W switch -t1
bind e switch -t2
-bind E switch -t2
# Other key bindings.
bind i list-windows
-bind I list-windows
bind m setw monitor-activity
-bind M setw monitor-activity
bind y setw force-width 81
-bind Y setw force-width 81
bind u setw force-width 0
-bind U setw force-width 0
# First session.
new -d -s0 -nirssi 'screen -DRS irssi irssi' # safe from pkill tmux ;-)
@@ -35,7 +32,7 @@ setw -t0:0 aggressive-resize on
set -t0 status-bg green
set -t0 status-left '[0]'
neww -d -ntodo 'exec emacs ~/TODO'
-neww -d -nncmpc
+neww -d -nncmpc 'exec ncmpc -f ~/.ncmpc.conf'
neww -d
neww -d
neww -d
diff --git a/input.c b/input.c
index 1d75bac6..82b9dd3f 100644
--- a/input.c
+++ b/input.c
@@ -512,7 +512,7 @@ input_state_utf8(u_char ch, struct input_ctx *ictx)
void
input_handle_character(u_char ch, struct input_ctx *ictx)
{
- if (ictx->w->flags & WINDOW_UTF8 && ch > 0x7f) {
+ if (ch > 0x7f && options_get_number(&ictx->w->options, "utf8")) {
/*
* UTF-8 sequence.
*
diff --git a/log.c b/log.c
index 8ca1e7bc..0a3a83b2 100644
--- a/log.c
+++ b/log.c
@@ -225,9 +225,6 @@ log_vfatal(const char *msg, va_list ap)
}
free(fmt);
-#ifdef DEBUG
- abort();
-#endif
exit(1);
}
diff --git a/options-cmd.c b/options-cmd.c
new file mode 100644
index 00000000..643eb28f
--- /dev/null
+++ b/options-cmd.c
@@ -0,0 +1,152 @@
+/* $Id$ */
+
+/*
+ * 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"
+
+void
+set_option_string(struct cmd_ctx *ctx, struct options *oo,
+ const struct set_option_entry *entry, char *value)
+{
+ if (value == NULL) {
+ ctx->error(ctx, "empty value");
+ return;
+ }
+
+ options_set_string(oo, entry->name, "%s", value);
+}
+
+void
+set_option_number(struct cmd_ctx *ctx, struct options *oo,
+ const struct set_option_entry *entry, char *value)
+{
+ 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;
+ }
+ options_set_number(oo, entry->name, number);
+}
+
+void
+set_option_key(struct cmd_ctx *ctx, struct options *oo,
+ const struct set_option_entry *entry, char *value)
+{
+ int key;
+
+ if (value == NULL) {
+ ctx->error(ctx, "empty value");
+ return;
+ }
+
+ if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
+ ctx->error(ctx, "unknown key: %s", value);
+ return;
+ }
+ options_set_number(oo, entry->name, key);
+
+}
+
+void
+set_option_colour(struct cmd_ctx *ctx, struct options *oo,
+ const struct set_option_entry *entry, char *value)
+{
+ u_char colour;
+
+ if (value == NULL) {
+ ctx->error(ctx, "empty value");
+ return;
+ }
+
+ if ((colour = colour_fromstring(value)) > 8) {
+ ctx->error(ctx, "bad colour: %s", value);
+ return;
+ }
+
+ options_set_number(oo, entry->name, colour);
+}
+
+void
+set_option_flag(struct cmd_ctx *ctx, struct options *oo,
+ const struct set_option_entry *entry, char *value)
+{
+ 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;
+ }
+ }
+
+ options_set_number(oo, entry->name, flag);
+}
+
+void
+set_option_choice(struct cmd_ctx *ctx, struct options *oo,
+ const struct set_option_entry *entry, char *value)
+{
+ 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;
+ }
+
+ options_set_number(oo, entry->name, choice);
+}
diff --git a/resize.c b/resize.c
index 1b642a58..54ee9e4e 100644
--- a/resize.c
+++ b/resize.c
@@ -48,7 +48,8 @@ recalculate_sizes(void)
struct session *s;
struct client *c;
struct window *w;
- u_int i, j, ssx, ssy, has;
+ u_int i, j, ssx, ssy, has, limit;
+ int flag;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
@@ -93,13 +94,14 @@ recalculate_sizes(void)
w = ARRAY_ITEM(&windows, i);
if (w == NULL)
continue;
+ flag = options_get_number(&w->options, "aggressive-resize");
ssx = ssy = UINT_MAX;
for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
s = ARRAY_ITEM(&sessions, j);
if (s == NULL || s->flags & SESSION_UNATTACHED)
continue;
- if (w->flags & WINDOW_AGGRESSIVE)
+ if (flag)
has = s->curw->window == w;
else
has = session_has(s, w);
@@ -116,10 +118,12 @@ recalculate_sizes(void)
}
w->flags &= ~WINDOW_HIDDEN;
- if (ssx > w->limitx)
- ssx = w->limitx;
- if (ssy > w->limity)
- ssy = w->limity;
+ limit = options_get_number(&w->options, "force-width");
+ if (limit != 0 && ssx > limit)
+ ssx = limit;
+ limit = options_get_number(&w->options, "force-height");
+ if (limit != 0 && ssy > limit)
+ ssy = limit;
if (screen_size_x(&w->base) == ssx &&
screen_size_y(&w->base) == ssy)
diff --git a/screen-redraw.c b/screen-redraw.c
index 734aa3f8..deadc42a 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -124,7 +124,7 @@ void
screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
{
const struct grid_cell *gc;
- struct grid_cell hc;
+ struct grid_cell tc;
if (px != ctx->s->cx || py != ctx->s->cy) {
ctx->s->cx = px;
@@ -134,9 +134,9 @@ screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
gc = grid_view_peek_cell(ctx->s->grid, px, py);
if (screen_check_selection(ctx->s, px, py)) {
- memcpy(&hc, gc, sizeof hc);
- hc.attr |= GRID_ATTR_REVERSE;
- ctx->write(ctx->data, TTY_CELL, &hc);
+ memcpy(&tc, &ctx->s->sel.cell, sizeof tc);
+ tc.data = gc->data;
+ ctx->write(ctx->data, TTY_CELL, &tc);
} else
ctx->write(ctx->data, TTY_CELL, gc);
ctx->s->cx++;
diff --git a/screen-write.c b/screen-write.c
index af17cc69..f678fd1a 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -608,8 +608,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
if (ctx->write != NULL) {
if (screen_check_selection(ctx->s, s->cx, s->cy)) {
- memcpy(&tc, gc, sizeof tc);
- tc.attr |= GRID_ATTR_REVERSE;
+ memcpy(&tc, &ctx->s->sel.cell, sizeof tc);
+ tc.data = gc->data;
ctx->write(ctx->data, TTY_CELL, &tc);
} else
ctx->write(ctx->data, TTY_CELL, gc);
diff --git a/screen.c b/screen.c
index b55fc912..84498b56 100644
--- a/screen.c
+++ b/screen.c
@@ -183,10 +183,13 @@ screen_resize_y(struct screen *s, u_int sy)
/* Set selection. */
void
-screen_set_selection(struct screen *s, u_int sx, u_int sy, u_int ex, u_int ey)
+screen_set_selection(struct screen *s,
+ u_int sx, u_int sy, u_int ex, u_int ey, struct grid_cell *gc)
{
struct screen_sel *sel = &s->sel;
+ memcpy(&sel->cell, gc, sizeof sel->cell);
+
sel->flag = 1;
if (ey < sy || (sy == ey && ex < sx)) {
sel->sx = ex; sel->sy = ey;
diff --git a/server.c b/server.c
index dd2061e1..9bac6330 100644
--- a/server.c
+++ b/server.c
@@ -612,7 +612,7 @@ server_handle_window(struct window *w)
update = 1;
}
- if ((w->flags & WINDOW_MONITOR) &&
+ if (options_get_number(&w->options, "monitor-activity") &&
(w->flags & WINDOW_ACTIVITY) &&
!session_alert_has_window(s, w, WINDOW_ACTIVITY)) {
session_alert_add(s, w, WINDOW_ACTIVITY);
@@ -637,7 +637,7 @@ server_lost_window(struct window *w)
log_debug("lost window %d", w->fd);
- if (w->flags & WINDOW_ZOMBIFY) {
+ if (options_get_number(&w->options, "remain-on-exit")) {
w->fd = -1;
return;
}
diff --git a/session.c b/session.c
index 58bfb465..017c6018 100644
--- a/session.c
+++ b/session.c
@@ -207,11 +207,6 @@ session_new(struct session *s, const char *name, const char *cmd, int idx)
if ((w = window_create(name, cmd, env, s->sx, s->sy, hlimit)) == NULL)
return (NULL);
- if (options_get_number(&s->options, "remain-by-default"))
- w->flags |= WINDOW_ZOMBIFY;
- if (options_get_number(&s->options, "utf8-default"))
- w->flags |= WINDOW_UTF8;
-
return (session_attach(s, w, idx));
}
diff --git a/status.c b/status.c
index 48c0415c..8f75af8a 100644
--- a/status.c
+++ b/status.c
@@ -369,6 +369,7 @@ void
status_message_redraw(struct client *c)
{
struct screen_redraw_ctx ctx;
+ struct session *s = c->session;
size_t xx, yy;
struct grid_cell gc;
@@ -381,7 +382,8 @@ status_message_redraw(struct client *c)
yy = c->sy - 1;
memcpy(&gc, &grid_default_cell, sizeof gc);
- gc.attr |= GRID_ATTR_REVERSE;
+ gc.fg = options_get_number(&s->options, "message-fg");
+ gc.bg = options_get_number(&s->options, "message-bg");
screen_redraw_start_client(&ctx, c);
@@ -400,6 +402,7 @@ void
status_prompt_redraw(struct client *c)
{
struct screen_redraw_ctx ctx;
+ struct session *s = c->session;
size_t i, xx, yy, left, size, offset;
char ch;
struct grid_cell gc;
@@ -414,7 +417,8 @@ status_prompt_redraw(struct client *c)
yy = c->sy - 1;
memcpy(&gc, &grid_default_cell, sizeof gc);
- gc.attr |= GRID_ATTR_REVERSE;
+ gc.fg = options_get_number(&s->options, "message-fg");
+ gc.bg = options_get_number(&s->options, "message-bg");
screen_redraw_start_client(&ctx, c);
@@ -448,7 +452,8 @@ status_prompt_redraw(struct client *c)
ch = c->prompt_buffer[c->prompt_index];
if (ch == '\0')
ch = ' ';
- gc.attr &= ~GRID_ATTR_REVERSE;
+ gc.bg = gc.fg;
+ gc.fg = options_get_number(&s->options, "message-bg");
screen_redraw_putc(&ctx, &gc, ch);
screen_redraw_stop(&ctx);
diff --git a/tmux.c b/tmux.c
index 7ea7013e..7beb9a94 100644
--- a/tmux.c
+++ b/tmux.c
@@ -48,6 +48,7 @@ volatile sig_atomic_t sigterm;
char *cfg_file;
struct options global_options;
+struct options global_window_options;
int debug_level;
int be_quiet;
@@ -232,9 +233,18 @@ main(int argc, char **argv)
options_set_number(&global_options, "status-interval", 15);
options_set_number(&global_options, "set-titles", 1);
options_set_number(&global_options, "buffer-limit", 9);
- options_set_number(&global_options, "remain-by-default", 0);
- options_set_number(&global_options, "mode-keys", MODEKEY_EMACS);
- options_set_number(&global_options, "utf8-default", 0);
+ options_set_number(&global_options, "message-fg", 0);
+ options_set_number(&global_options, "message-bg", 3);
+ options_init(&global_window_options, NULL);
+ options_set_number(&global_window_options, "monitor-activity", 0);
+ options_set_number(&global_window_options, "aggressive-resize", 0);
+ options_set_number(&global_window_options, "remain-on-exit", 0);
+ options_set_number(&global_window_options, "utf8", 0);
+ options_set_number(&global_window_options, "mode-fg", 0);
+ options_set_number(&global_window_options, "mode-bg", 3);
+ options_set_number(&global_window_options, "mode-keys", MODEKEY_EMACS);
+ options_set_number(&global_window_options, "force-width", 0);
+ options_set_number(&global_window_options, "force-height", 0);
if (cfg_file == NULL) {
home = getenv("HOME");
@@ -363,6 +373,7 @@ main(int argc, char **argv)
out:
options_free(&global_options);
+ options_free(&global_window_options);
close(cctx.srv_fd);
buffer_destroy(cctx.srv_in);
diff --git a/tmux.h b/tmux.h
index ec7f6aa9..90b98ce9 100644
--- a/tmux.h
+++ b/tmux.h
@@ -450,6 +450,31 @@ struct grid_data {
struct grid_cell **data;
};
+/* Option data structures. */
+struct options_entry {
+ char *name;
+
+ enum {
+ OPTIONS_STRING,
+ OPTIONS_NUMBER,
+ OPTIONS_KEY,
+ OPTIONS_COLOURS
+ } type;
+ union {
+ char *string;
+ long long number;
+ int key;
+ u_char colours;
+ } value;
+
+ SPLAY_ENTRY(options_entry) entry;
+};
+
+struct options {
+ SPLAY_HEAD(options_tree, options_entry) tree;
+ struct options *parent;
+};
+
/* Screen selection. */
struct screen_sel {
int flag;
@@ -459,6 +484,8 @@ struct screen_sel {
u_int ex;
u_int ey;
+
+ struct grid_cell cell;
};
/* Virtual screen. */
@@ -566,17 +593,12 @@ struct window {
struct input_ctx ictx;
+ struct options options;
+
int flags;
#define WINDOW_BELL 0x1
#define WINDOW_HIDDEN 0x2
#define WINDOW_ACTIVITY 0x4
-#define WINDOW_MONITOR 0x8
-#define WINDOW_AGGRESSIVE 0x10
-#define WINDOW_ZOMBIFY 0x20
-#define WINDOW_UTF8 0x40
-
- u_int limitx;
- u_int limity;
struct screen *screen;
struct screen base;
@@ -599,31 +621,6 @@ struct winlink {
RB_HEAD(winlinks, winlink);
SLIST_HEAD(winlink_stack, winlink);
-/* Option data structures. */
-struct options_entry {
- char *name;
-
- enum {
- OPTIONS_STRING,
- OPTIONS_NUMBER,
- OPTIONS_KEY,
- OPTIONS_COLOURS
- } type;
- union {
- char *string;
- long long number;
- int key;
- u_char colours;
- } value;
-
- SPLAY_ENTRY(options_entry) entry;
-};
-
-struct options {
- SPLAY_HEAD(options_tree, options_entry) tree;
- struct options *parent;
-};
-
/* Paste buffer. */
struct paste_buffer {
char *data;
@@ -787,6 +784,7 @@ struct cmd_entry {
#define CMD_DFLAG 0x8
#define CMD_ONEARG 0x10
#define CMD_ZEROONEARG 0x20
+#define CMD_GFLAG 0x40
int flags;
void (*init)(struct cmd *, int);
@@ -819,6 +817,13 @@ struct cmd_buffer_data {
char *arg;
};
+struct cmd_option_data {
+ int flags;
+ char *target;
+ char *option;
+ char *value;
+};
+
/* Key binding. */
struct binding {
int key;
@@ -844,7 +849,9 @@ struct set_option_entry {
const char **choices;
};
extern const struct set_option_entry set_option_table[];
-#define NSETOPTION 18
+extern const struct set_option_entry set_window_option_table[];
+#define NSETOPTION 17
+#define NSETWINDOWOPTION 9
/* Edit keys. */
enum mode_key {
@@ -907,6 +914,7 @@ char *fgetln(FILE *, size_t *);
extern volatile sig_atomic_t sigwinch;
extern volatile sig_atomic_t sigterm;
extern struct options global_options;
+extern struct options global_window_options;
extern char *cfg_file;
extern int debug_level;
extern int be_quiet;
@@ -956,6 +964,20 @@ void tty_vwrite_window(void *, int, va_list);
void tty_write_session(void *, int, ...);
void tty_vwrite_session(void *, int, va_list);
+/* options-cmd.c */
+void set_option_string(struct cmd_ctx *,
+ struct options *, const struct set_option_entry *, char *);
+void set_option_number(struct cmd_ctx *,
+ struct options *, const struct set_option_entry *, char *);
+void set_option_key(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_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 *);
@@ -1066,6 +1088,16 @@ void cmd_buffer_send(struct cmd *, struct buffer *);
void cmd_buffer_recv(struct cmd *, struct buffer *);
void cmd_buffer_free(struct cmd *);
void cmd_buffer_print(struct cmd *, char *, size_t);
+#define CMD_OPTION_WINDOW_USAGE "[-t target-window] option value"
+#define CMD_OPTION_SESSION_USAGE "[-t target-session] option value"
+#define CMD_OPTION_CLIENT_USAGE "[-t target-client] option value"
+void cmd_option_init(struct cmd *, int);
+int cmd_option_parse(struct cmd *, int, char **, char **);
+void cmd_option_exec(struct cmd *, struct cmd_ctx *);
+void cmd_option_send(struct cmd *, struct buffer *);
+void cmd_option_recv(struct cmd *, struct buffer *);
+void cmd_option_free(struct cmd *);
+void cmd_option_print(struct cmd *, char *, size_t);
/* client.c */
int client_init(const char *, struct client_ctx *, int, int);
@@ -1248,7 +1280,8 @@ void screen_reinit(struct screen *);
void screen_free(struct screen *);
void screen_set_title(struct screen *, const char *);
void screen_resize(struct screen *, u_int, u_int);
-void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int);
+void screen_set_selection(
+ struct screen *, u_int, u_int, u_int, u_int, struct grid_cell *);
void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);
void screen_display_copy_area(struct screen *, struct screen *,
diff --git a/window-copy.c b/window-copy.c
index 22e2f951..a729b034 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -137,7 +137,7 @@ window_copy_key(struct window *w, struct client *c, int key)
struct screen *s = &data->screen;
int table;
- table = options_get_number(&c->session->options, "mode-keys");
+ table = options_get_number(&w->options, "mode-keys");
switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT:
window_reset_mode(w);
@@ -213,10 +213,11 @@ window_copy_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr,
"[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base));
- gc.attr |= GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE;
+ gc.fg = options_get_number(&w->options, "mode-fg");
+ gc.bg = options_get_number(&w->options, "mode-bg");
screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr);
- gc.attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE);
+ screen_write_puts(ctx, &gc, "%s", hdr);
} else
size = 0;
@@ -308,11 +309,17 @@ window_copy_update_selection(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
struct screen *s = &data->screen;
+ struct grid_cell gc;
u_int sx, sy, tx, ty;
if (!s->sel.flag)
return (0);
+ /* Set colours. */
+ memcpy(&gc, &grid_default_cell, sizeof gc);
+ gc.fg = options_get_number(&w->options, "mode-fg");
+ gc.bg = options_get_number(&w->options, "mode-bg");
+
/* Find top-left of screen. */
tx = data->ox;
ty = screen_hsize(&w->base) - data->oy;
@@ -343,7 +350,8 @@ window_copy_update_selection(struct window *w)
}
sy = screen_hsize(s) + sy;
- screen_set_selection(s, sx, sy, data->cx, screen_hsize(s) + data->cy);
+ screen_set_selection(
+ s, sx, sy, data->cx, screen_hsize(s) + data->cy, &gc);
return (1);
}
diff --git a/window-more.c b/window-more.c
index 61152ce2..07e9cbb4 100644
--- a/window-more.c
+++ b/window-more.c
@@ -123,13 +123,13 @@ window_more_resize(struct window *w, u_int sx, u_int sy)
}
void
-window_more_key(struct window *w, struct client *c, int key)
+window_more_key(struct window *w, unused struct client *c, int key)
{
struct window_more_mode_data *data = w->modedata;
struct screen *s = &data->screen;
int table;
- table = options_get_number(&c->session->options, "mode-keys");
+ table = options_get_number(&w->options, "mode-keys");
switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT:
window_reset_mode(w);
@@ -174,9 +174,10 @@ window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
size = xsnprintf(hdr, sizeof hdr,
"[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
- gc.attr |= GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE;
+ gc.fg = options_get_number(&w->options, "mode-fg");
+ gc.bg = options_get_number(&w->options, "mode-bg");
screen_write_puts(ctx, &gc, "%s", hdr);
- gc.attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE);
+ memcpy(&gc, &grid_default_cell, sizeof gc);
} else
size = 0;
diff --git a/window-scroll.c b/window-scroll.c
index a7f2a422..48391b11 100644
--- a/window-scroll.c
+++ b/window-scroll.c
@@ -101,13 +101,13 @@ window_scroll_resize(struct window *w, u_int sx, u_int sy)
}
void
-window_scroll_key(struct window *w, struct client *c, int key)
+window_scroll_key(struct window *w, unused struct client *c, int key)
{
struct window_scroll_mode_data *data = w->modedata;
struct screen *s = &data->screen;
int table;
- table = options_get_number(&c->session->options, "mode-keys");
+ table = options_get_number(&w->options, "mode-keys");
switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT:
window_reset_mode(w);
@@ -157,10 +157,11 @@ window_scroll_write_line(
memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr,
"[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base));
- gc.attr |= GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE;
+ gc.fg = options_get_number(&w->options, "mode-fg");
+ gc.bg = options_get_number(&w->options, "mode-bg");
screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr);
- gc.attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE);
+ memcpy(&gc, &grid_default_cell, sizeof gc);
} else
size = 0;
diff --git a/window.c b/window.c
index b1fc9d1c..bfe7e418 100644
--- a/window.c
+++ b/window.c
@@ -207,11 +207,11 @@ window_create(const char *name,
w->mode = NULL;
w->flags = 0;
- w->limitx = w->limity = UINT_MAX;
screen_init(&w->base, sx, sy, hlimit);
w->screen = &w->base;
input_init(w);
+ options_init(&w->options, &global_window_options);
if (name == NULL) {
/* XXX */
@@ -308,6 +308,7 @@ window_destroy(struct window *w)
input_free(w);
window_reset_mode(w);
+ options_free(&w->options);
screen_free(&w->base);
buffer_destroy(w->in);