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

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/

This commit is contained in:
Nicholas Marriott 2008-12-08 16:19:51 +00:00
parent f008d303e7
commit 7a82e86827
27 changed files with 690 additions and 768 deletions

46
CHANGES
View File

@ -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 02 December 2008
* Add support for including the window title in status-left or status-right * Add support for including the window title in status-left or status-right
@ -272,7 +306,7 @@
07 June 2008 07 June 2008
* Make status-interval actually changable. * Make status-interval actually changeable.
06 June 2008 06 June 2008
@ -355,7 +389,7 @@
* -s to specify session name now supports fnmatch(3) wildcards; if multiple * -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. 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 * 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. * kill-server command.
02 June 2008 02 June 2008
@ -669,7 +703,7 @@
a serious problem when it comes to things like scrolling. This change a serious problem when it comes to things like scrolling. This change
consolidates all the range checking and limiting together which should make consolidates all the range checking and limiting together which should make
it easier. 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 27 September 2007
@ -728,4 +762,8 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.169 2008-12-05 20:04:06 nicm Exp $ $Id: CHANGES,v 1.170 2008-12-08 16:19:51 nicm Exp $
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

View File

@ -1,13 +1,13 @@
# $Id: GNUmakefile,v 1.42 2008-09-26 06:45:25 nicm Exp $ # $Id: GNUmakefile,v 1.43 2008-12-08 16:19:51 nicm Exp $
.PHONY: clean .PHONY: clean
PROG= tmux PROG= tmux
VERSION= 0.5 VERSION= 0.6
DATE= $(shell date +%Y%m%d-%H%M) DATE= $(shell date +%Y%m%d-%H%M)
#DEBUG= 1 DEBUG= 1
META?= \002 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-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c \ cmd-respawn-window.c \
window-scroll.c window-more.c window-copy.c options.c paste.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 CC?= gcc
INCDIRS+= -I. -I- INCDIRS+= -I. -I-

View File

@ -1,10 +1,10 @@
# $Id: Makefile,v 1.78 2008-12-05 20:04:06 nicm Exp $ # $Id: Makefile,v 1.79 2008-12-08 16:19:51 nicm Exp $
.SUFFIXES: .c .o .y .h .SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html .PHONY: clean update-index.html upload-index.html
PROG= tmux PROG= tmux
VERSION= 0.5 VERSION= 0.6
OS!= uname OS!= uname
REL!= uname -r 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-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c \ cmd-respawn-window.c \
window-scroll.c window-more.c window-copy.c options.c paste.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 CC?= cc
INCDIRS+= -I. -I- -I/usr/local/include INCDIRS+= -I. -I- -I/usr/local/include

2
TODO
View File

@ -52,3 +52,5 @@
- vi half page scroll - vi half page scroll
- why do home/end work in emacs outside tmux but not inside? - why do home/end work in emacs outside tmux but not inside?
- document status line options, title bits - document status line options, title bits
- document mode-fg/mode-bg/message-fg/message-bg
- document window options changes

View File

@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.13 2008-09-25 23:28:12 nicm Exp $ */ /* $Id: cmd-generic.c,v 1.14 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -44,7 +44,7 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
cmd_target_init(self, 0); cmd_target_init(self, 0);
data = self->data; data = self->data;
while ((opt = getopt(argc, argv, GETOPT_PREFIX "dkt:")) != EOF) { while ((opt = getopt(argc, argv, GETOPT_PREFIX "dgkt:")) != EOF) {
switch (opt) { switch (opt) {
case 'd': case 'd':
if (self->entry->flags & CMD_DFLAG) { if (self->entry->flags & CMD_DFLAG) {
@ -52,6 +52,12 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
break; break;
} }
goto usage; goto usage;
case 'g':
if (self->entry->flags & CMD_GFLAG) {
data->flags |= CMD_GFLAG;
break;
}
goto usage;
case 'k': case 'k':
if (self->entry->flags & CMD_KFLAG) { if (self->entry->flags & CMD_KFLAG) {
data->flags |= CMD_KFLAG; data->flags |= CMD_KFLAG;
@ -137,6 +143,8 @@ cmd_target_print(struct cmd *self, char *buf, size_t len)
return; return;
if (off < len && data->flags & CMD_DFLAG) if (off < len && data->flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, " -d"); 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) if (off < len && data->flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, " -k"); off += xsnprintf(buf + off, len - off, " -k");
if (off < len && data->target != NULL) 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); cmd_srcdst_init(self, 0);
data = self->data; 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) { switch (opt) {
case 'd': case 'd':
if (self->entry->flags & CMD_DFLAG) { if (self->entry->flags & CMD_DFLAG) {
@ -174,6 +182,12 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
break; break;
} }
goto usage; goto usage;
case 'g':
if (self->entry->flags & CMD_GFLAG) {
data->flags |= CMD_GFLAG;
break;
}
goto usage;
case 'k': case 'k':
if (self->entry->flags & CMD_KFLAG) { if (self->entry->flags & CMD_KFLAG) {
data->flags |= CMD_KFLAG; data->flags |= CMD_KFLAG;
@ -267,6 +281,8 @@ cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
return; return;
if (off < len && data->flags & CMD_DFLAG) if (off < len && data->flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, " -d"); 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) if (off < len && data->flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, " -k"); off += xsnprintf(buf + off, len - off, " -k");
if (off < len && data->src != NULL) 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); cmd_buffer_init(self, 0);
data = self->data; 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) { switch (opt) {
case 'b': case 'b':
if (data->buffer == -1) { if (data->buffer == -1) {
@ -318,6 +334,12 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
break; break;
} }
goto usage; goto usage;
case 'g':
if (self->entry->flags & CMD_GFLAG) {
data->flags |= CMD_GFLAG;
break;
}
goto usage;
case 'k': case 'k':
if (self->entry->flags & CMD_KFLAG) { if (self->entry->flags & CMD_KFLAG) {
data->flags |= CMD_KFLAG; data->flags |= CMD_KFLAG;
@ -404,6 +426,8 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len)
return; return;
if (off < len && data->flags & CMD_DFLAG) if (off < len && data->flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, " -d"); 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) if (off < len && data->flags & CMD_KFLAG)
off += xsnprintf(buf + off, len - off, " -k"); off += xsnprintf(buf + off, len - off, " -k");
if (off < len && data->buffer != -1) 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) if (off < len && data->arg != NULL)
off += xsnprintf(buf + off, len - off, " %s", data->arg); 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);
}

View File

@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.45 2008-12-05 20:04:06 nicm Exp $ */ /* $Id: cmd-set-option.c,v 1.46 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -28,132 +28,61 @@
* Set an option. * 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_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 = { const struct cmd_entry cmd_set_option_entry = {
"set-option", "set", "set-option", "set",
"[-t target-session] option value", "[-t target-session] option value",
0, CMD_GFLAG,
NULL, NULL,
cmd_set_option_parse, cmd_option_parse,
cmd_set_option_exec, cmd_set_option_exec,
cmd_set_option_send, cmd_option_send,
cmd_set_option_recv, cmd_option_recv,
cmd_set_option_free, cmd_option_free,
cmd_set_option_print cmd_option_print
}; };
const char *set_option_bell_action_list[] = { const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL "none", "any", "current", NULL
}; };
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const struct set_option_entry set_option_table[NSETOPTION] = { const struct set_option_entry set_option_table[NSETOPTION] = {
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list }, { "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "default-command", SET_OPTION_STRING, 0, 0, NULL }, { "default-command", SET_OPTION_STRING, 0, 0, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL }, { "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, SHRT_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 }, { "prefix", SET_OPTION_KEY, 0, 0, NULL },
{ "remain-by-default", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL }, { "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
{ "status", SET_OPTION_FLAG, 0, 0, NULL }, { "status", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "status-left", SET_OPTION_STRING, 0, 0, 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-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 }, { "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 void
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx) 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 session *s;
struct client *c; struct client *c;
struct options *oo; struct options *oo;
const struct set_option_entry *entry; const struct set_option_entry *entry;
u_int i; u_int i;
if (data == NULL) if (data->flags & CMD_GFLAG)
return;
if (data->flag_global ||
((s = cmd_find_session(ctx, data->target))) == NULL)
oo = &global_options; oo = &global_options;
else else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return;
oo = &s->options; oo = &s->options;
}
if (*data->option == '\0') { if (*data->option == '\0') {
ctx->error(ctx, "invalid option"); ctx->error(ctx, "invalid option");
@ -211,183 +140,3 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); 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);
}

View File

@ -1,7 +1,7 @@
/* $Id: cmd-set-window-option.c,v 1.13 2008-11-16 13:28:59 nicm Exp $ */ /* $Id: cmd-set-window-option.c,v 1.14 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* 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 * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * 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_free(struct cmd *);
void cmd_set_window_option_print(struct cmd *, char *, size_t); 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 = { const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw", "set-window-option", "setw",
"[-t target-window] option value", "[-g] [-t target-window] option value",
0, CMD_GFLAG,
NULL, NULL,
cmd_set_window_option_parse, cmd_option_parse,
cmd_set_window_option_exec, cmd_set_window_option_exec,
cmd_set_window_option_send, cmd_option_send,
cmd_set_window_option_recv, cmd_option_recv,
cmd_set_window_option_free, cmd_option_free,
cmd_set_window_option_print cmd_option_print
}; };
int const char *set_option_mode_keys_list[] = {
cmd_set_window_option_parse( "emacs", "vi", NULL
struct cmd *self, int argc, char **argv, char **cause) };
{ const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
struct cmd_set_window_option_data *data; { "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
int opt; { "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
self->data = data = xmalloc(sizeof *data); { "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
data->target = NULL; { "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
data->option = NULL; { "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
data->value = NULL; { "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
while ((opt = getopt(argc, argv, GETOPT_PREFIX "t:")) != EOF) { { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
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);
}
void void
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_set_window_option_data *data = self->data; struct cmd_option_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct session *s; struct client *c;
const char *errstr; struct options *oo;
int number, flag; const struct set_option_entry *entry;
u_int i; u_int i;
if (data == NULL) if (data->flags & CMD_GFLAG)
return; oo = &global_window_options;
else {
wl = cmd_find_window(ctx, data->target, &s); if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
if (wl == NULL) return;
return; oo = &wl->window->options;
}
if (*data->option == '\0') { if (*data->option == '\0') {
ctx->error(ctx, "invalid option"); ctx->error(ctx, "invalid option");
return; return;
} }
number = -1; entry = NULL;
if (data->value != NULL) { for (i = 0; i < NSETWINDOWOPTION; i++) {
number = strtonum(data->value, 0, INT_MAX, &errstr); if (strncmp(set_window_option_table[i].name,
data->option, strlen(data->option)) != 0)
flag = -1; continue;
if (number == 1 || strcasecmp(data->value, "on") == 0 || if (entry != NULL) {
strcasecmp(data->value, "yes") == 0) ctx->error(ctx, "ambiguous option: %s", data->option);
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);
return; return;
} }
entry = &set_window_option_table[i];
if (flag == -2) /* Bail now if an exact match. */
wl->window->flags ^= WINDOW_MONITOR; if (strcmp(entry->name, data->option) == 0)
else { break;
if (flag) }
wl->window->flags |= WINDOW_MONITOR; if (entry == NULL) {
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 {
ctx->error(ctx, "unknown option: %s", data->option); ctx->error(ctx, "unknown option: %s", data->option);
return; return;
} }
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;
}
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);
}
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); 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);
}
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;
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);
}

View File

@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.7 2008-09-25 23:28:15 nicm Exp $ */ /* $Id: cmd-show-options.c,v 1.8 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -28,74 +28,25 @@
* Show options. * 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_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 = { const struct cmd_entry cmd_show_options_entry = {
"show-options", "show", "show-options", "show",
"[-t target-session]", "[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_GFLAG,
NULL, cmd_target_init,
cmd_show_options_parse, cmd_target_parse,
cmd_show_options_exec, cmd_show_options_exec,
cmd_show_options_send, cmd_target_send,
cmd_show_options_recv, cmd_target_recv,
cmd_show_options_free, cmd_target_free,
cmd_show_options_print 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 void
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx) 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 session *s;
struct options *oo; struct options *oo;
const struct set_option_entry *entry; const struct set_option_entry *entry;
@ -103,14 +54,13 @@ cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
char *vs; char *vs;
long long vn; long long vn;
if (data == NULL) if (data->flags & CMD_GFLAG)
return;
if (data->flag_global ||
((s = cmd_find_session(ctx, data->target))) == NULL)
oo = &global_options; oo = &global_options;
else else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return;
oo = &s->options; oo = &s->options;
}
for (i = 0; i < NSETOPTION; i++) { for (i = 0; i < NSETOPTION; i++) {
entry = &set_option_table[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) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); 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);
}

View File

@ -1,7 +1,7 @@
/* $Id: cmd-show-window-options.c,v 1.3 2008-11-16 13:28:59 nicm Exp $ */ /* $Id: cmd-show-window-options.c,v 1.4 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* 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 * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -20,6 +20,7 @@
#include <getopt.h> #include <getopt.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "tmux.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 = { const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw", "show-window-options", "showw",
CMD_TARGET_WINDOW_USAGE, "[-g] " CMD_TARGET_WINDOW_USAGE,
0, CMD_GFLAG,
cmd_target_init, cmd_target_init,
cmd_target_parse, cmd_target_parse,
cmd_show_window_options_exec, cmd_show_window_options_exec,
@ -45,25 +46,61 @@ const struct cmd_entry cmd_show_window_options_entry = {
void void
cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct session *s; 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) if (data->flags & CMD_GFLAG)
return; 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) for (i = 0; i < NSETWINDOWOPTION; i++) {
ctx->print(ctx, "aggressive-resize"); entry = &set_window_option_table[i];
if (wl->window->limitx != UINT_MAX)
ctx->print(ctx, "force-width %u", wl->window->limitx); if (options_find1(oo, entry->name) == NULL)
if (wl->window->limity != UINT_MAX) continue;
ctx->print(ctx, "force-height %u", wl->window->limity);
if (wl->window->flags & WINDOW_MONITOR) switch (entry->type) {
ctx->print(ctx, "monitor-activity"); case SET_OPTION_STRING:
if (wl->window->flags & WINDOW_ZOMBIFY) vs = options_get_string(oo, entry->name);
ctx->print(ctx, "remain-on-exit"); ctx->print(ctx, "%s \"%s\"", entry->name, vs);
if (wl->window->flags & WINDOW_UTF8) break;
ctx->print(ctx, "utf8"); 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) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

View File

@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.7 2008-09-26 06:45:26 nicm Exp $ */ /* $Id: cmd-string.c,v 1.8 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -131,7 +131,8 @@ cmd_string_parse(const char *s, struct cmd **cmd, char **cause)
if (argc == 0) if (argc == 0)
goto out; goto out;
*cmd = cmd_parse(argc, argv, cause); if ((*cmd = cmd_parse(argc, argv, cause)) == NULL)
goto error;
rval = 0; rval = 0;
goto out; goto out;
default: default:
@ -145,7 +146,7 @@ cmd_string_parse(const char *s, struct cmd **cmd, char **cause)
} }
error: error:
xasprintf(cause, "bad command: %s", s); xasprintf(cause, "invalid or unknown command: %s", s);
out: out:
if (buf != NULL) if (buf != NULL)

View File

@ -1,32 +1,29 @@
# Default global options. # Default global options.
set status-bg green set -g status-bg green
set default-command "exec /bin/ksh -l" set -g status-right-length 60
set bell-action none 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. # Prefix key.
set prefix ^A set -g prefix ^A
unbind ^B unbind ^B
bind ^A send-prefix bind ^A send-prefix
# Keys to switch session. # Keys to switch session.
bind q switch -t0 bind q switch -t0
bind Q switch -t0
bind w switch -t1 bind w switch -t1
bind W switch -t1
bind e switch -t2 bind e switch -t2
bind E switch -t2
# Other key bindings. # Other key bindings.
bind i list-windows bind i list-windows
bind I list-windows
bind m setw monitor-activity bind m setw monitor-activity
bind M setw monitor-activity
bind y setw force-width 81 bind y setw force-width 81
bind Y setw force-width 81
bind u setw force-width 0 bind u setw force-width 0
bind U setw force-width 0
# First session. # First session.
new -d -s0 -nirssi 'screen -DRS irssi irssi' # safe from pkill tmux ;-) 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-bg green
set -t0 status-left '[0]' set -t0 status-left '[0]'
neww -d -ntodo 'exec emacs ~/TODO' neww -d -ntodo 'exec emacs ~/TODO'
neww -d -nncmpc neww -d -nncmpc 'exec ncmpc -f ~/.ncmpc.conf'
neww -d neww -d
neww -d neww -d
neww -d neww -d

View File

@ -1,4 +1,4 @@
/* $Id: input.c,v 1.68 2008-12-05 20:04:06 nicm Exp $ */ /* $Id: input.c,v 1.69 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -512,7 +512,7 @@ input_state_utf8(u_char ch, struct input_ctx *ictx)
void void
input_handle_character(u_char ch, struct input_ctx *ictx) 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. * UTF-8 sequence.
* *

5
log.c
View File

@ -1,4 +1,4 @@
/* $Id: log.c,v 1.9 2008-10-09 05:31:04 nicm Exp $ */ /* $Id: log.c,v 1.10 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -225,9 +225,6 @@ log_vfatal(const char *msg, va_list ap)
} }
free(fmt); free(fmt);
#ifdef DEBUG
abort();
#endif
exit(1); exit(1);
} }

152
options-cmd.c Normal file
View File

@ -0,0 +1,152 @@
/* $Id: options-cmd.c,v 1.1 2008-12-08 16:19:51 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
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);
}

View File

@ -1,4 +1,4 @@
/* $Id: resize.c,v 1.16 2008-06-19 22:04:02 nicm Exp $ */ /* $Id: resize.c,v 1.17 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -48,7 +48,8 @@ recalculate_sizes(void)
struct session *s; struct session *s;
struct client *c; struct client *c;
struct window *w; 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++) { for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i); s = ARRAY_ITEM(&sessions, i);
@ -93,13 +94,14 @@ recalculate_sizes(void)
w = ARRAY_ITEM(&windows, i); w = ARRAY_ITEM(&windows, i);
if (w == NULL) if (w == NULL)
continue; continue;
flag = options_get_number(&w->options, "aggressive-resize");
ssx = ssy = UINT_MAX; ssx = ssy = UINT_MAX;
for (j = 0; j < ARRAY_LENGTH(&sessions); j++) { for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
s = ARRAY_ITEM(&sessions, j); s = ARRAY_ITEM(&sessions, j);
if (s == NULL || s->flags & SESSION_UNATTACHED) if (s == NULL || s->flags & SESSION_UNATTACHED)
continue; continue;
if (w->flags & WINDOW_AGGRESSIVE) if (flag)
has = s->curw->window == w; has = s->curw->window == w;
else else
has = session_has(s, w); has = session_has(s, w);
@ -116,10 +118,12 @@ recalculate_sizes(void)
} }
w->flags &= ~WINDOW_HIDDEN; w->flags &= ~WINDOW_HIDDEN;
if (ssx > w->limitx) limit = options_get_number(&w->options, "force-width");
ssx = w->limitx; if (limit != 0 && ssx > limit)
if (ssy > w->limity) ssx = limit;
ssy = w->limity; limit = options_get_number(&w->options, "force-height");
if (limit != 0 && ssy > limit)
ssy = limit;
if (screen_size_x(&w->base) == ssx && if (screen_size_x(&w->base) == ssx &&
screen_size_y(&w->base) == ssy) screen_size_y(&w->base) == ssy)

View File

@ -1,4 +1,4 @@
/* $Id: screen-redraw.c,v 1.13 2008-09-26 06:45:26 nicm Exp $ */ /* $Id: screen-redraw.c,v 1.14 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -124,7 +124,7 @@ void
screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py) screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
{ {
const struct grid_cell *gc; const struct grid_cell *gc;
struct grid_cell hc; struct grid_cell tc;
if (px != ctx->s->cx || py != ctx->s->cy) { if (px != ctx->s->cx || py != ctx->s->cy) {
ctx->s->cx = px; 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); gc = grid_view_peek_cell(ctx->s->grid, px, py);
if (screen_check_selection(ctx->s, px, py)) { if (screen_check_selection(ctx->s, px, py)) {
memcpy(&hc, gc, sizeof hc); memcpy(&tc, &ctx->s->sel.cell, sizeof tc);
hc.attr |= GRID_ATTR_REVERSE; tc.data = gc->data;
ctx->write(ctx->data, TTY_CELL, &hc); ctx->write(ctx->data, TTY_CELL, &tc);
} else } else
ctx->write(ctx->data, TTY_CELL, gc); ctx->write(ctx->data, TTY_CELL, gc);
ctx->s->cx++; ctx->s->cx++;

View File

@ -1,4 +1,4 @@
/* $Id: screen-write.c,v 1.16 2008-11-12 23:38:40 nicm Exp $ */ /* $Id: screen-write.c,v 1.17 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -608,8 +608,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
if (ctx->write != NULL) { if (ctx->write != NULL) {
if (screen_check_selection(ctx->s, s->cx, s->cy)) { if (screen_check_selection(ctx->s, s->cx, s->cy)) {
memcpy(&tc, gc, sizeof tc); memcpy(&tc, &ctx->s->sel.cell, sizeof tc);
tc.attr |= GRID_ATTR_REVERSE; tc.data = gc->data;
ctx->write(ctx->data, TTY_CELL, &tc); ctx->write(ctx->data, TTY_CELL, &tc);
} else } else
ctx->write(ctx->data, TTY_CELL, gc); ctx->write(ctx->data, TTY_CELL, gc);

View File

@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.76 2008-10-09 05:31:04 nicm Exp $ */ /* $Id: screen.c,v 1.77 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -183,10 +183,13 @@ screen_resize_y(struct screen *s, u_int sy)
/* Set selection. */ /* Set selection. */
void 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; struct screen_sel *sel = &s->sel;
memcpy(&sel->cell, gc, sizeof sel->cell);
sel->flag = 1; sel->flag = 1;
if (ey < sy || (sy == ey && ex < sx)) { if (ey < sy || (sy == ey && ex < sx)) {
sel->sx = ex; sel->sy = ey; sel->sx = ex; sel->sy = ey;

View File

@ -1,4 +1,4 @@
/* $Id: server.c,v 1.85 2008-12-05 20:04:06 nicm Exp $ */ /* $Id: server.c,v 1.86 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -612,7 +612,7 @@ server_handle_window(struct window *w)
update = 1; update = 1;
} }
if ((w->flags & WINDOW_MONITOR) && if (options_get_number(&w->options, "monitor-activity") &&
(w->flags & WINDOW_ACTIVITY) && (w->flags & WINDOW_ACTIVITY) &&
!session_alert_has_window(s, w, WINDOW_ACTIVITY)) { !session_alert_has_window(s, w, WINDOW_ACTIVITY)) {
session_alert_add(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); log_debug("lost window %d", w->fd);
if (w->flags & WINDOW_ZOMBIFY) { if (options_get_number(&w->options, "remain-on-exit")) {
w->fd = -1; w->fd = -1;
return; return;
} }

View File

@ -1,4 +1,4 @@
/* $Id: session.c,v 1.46 2008-11-16 13:28:59 nicm Exp $ */ /* $Id: session.c,v 1.47 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -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) if ((w = window_create(name, cmd, env, s->sx, s->sy, hlimit)) == NULL)
return (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)); return (session_attach(s, w, idx));
} }

View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.51 2008-12-05 20:04:06 nicm Exp $ */ /* $Id: status.c,v 1.52 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -369,6 +369,7 @@ void
status_message_redraw(struct client *c) status_message_redraw(struct client *c)
{ {
struct screen_redraw_ctx ctx; struct screen_redraw_ctx ctx;
struct session *s = c->session;
size_t xx, yy; size_t xx, yy;
struct grid_cell gc; struct grid_cell gc;
@ -381,7 +382,8 @@ status_message_redraw(struct client *c)
yy = c->sy - 1; yy = c->sy - 1;
memcpy(&gc, &grid_default_cell, sizeof gc); 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); screen_redraw_start_client(&ctx, c);
@ -400,6 +402,7 @@ void
status_prompt_redraw(struct client *c) status_prompt_redraw(struct client *c)
{ {
struct screen_redraw_ctx ctx; struct screen_redraw_ctx ctx;
struct session *s = c->session;
size_t i, xx, yy, left, size, offset; size_t i, xx, yy, left, size, offset;
char ch; char ch;
struct grid_cell gc; struct grid_cell gc;
@ -414,7 +417,8 @@ status_prompt_redraw(struct client *c)
yy = c->sy - 1; yy = c->sy - 1;
memcpy(&gc, &grid_default_cell, sizeof gc); 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); screen_redraw_start_client(&ctx, c);
@ -448,7 +452,8 @@ status_prompt_redraw(struct client *c)
ch = c->prompt_buffer[c->prompt_index]; ch = c->prompt_buffer[c->prompt_index];
if (ch == '\0') if (ch == '\0')
ch = ' '; 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_putc(&ctx, &gc, ch);
screen_redraw_stop(&ctx); screen_redraw_stop(&ctx);

19
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.82 2008-12-05 20:04:06 nicm Exp $ */ /* $Id: tmux.c,v 1.83 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -48,6 +48,7 @@ volatile sig_atomic_t sigterm;
char *cfg_file; char *cfg_file;
struct options global_options; struct options global_options;
struct options global_window_options;
int debug_level; int debug_level;
int be_quiet; 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, "status-interval", 15);
options_set_number(&global_options, "set-titles", 1); options_set_number(&global_options, "set-titles", 1);
options_set_number(&global_options, "buffer-limit", 9); options_set_number(&global_options, "buffer-limit", 9);
options_set_number(&global_options, "remain-by-default", 0); options_set_number(&global_options, "message-fg", 0);
options_set_number(&global_options, "mode-keys", MODEKEY_EMACS); options_set_number(&global_options, "message-bg", 3);
options_set_number(&global_options, "utf8-default", 0); 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) { if (cfg_file == NULL) {
home = getenv("HOME"); home = getenv("HOME");
@ -363,6 +373,7 @@ main(int argc, char **argv)
out: out:
options_free(&global_options); options_free(&global_options);
options_free(&global_window_options);
close(cctx.srv_fd); close(cctx.srv_fd);
buffer_destroy(cctx.srv_in); buffer_destroy(cctx.srv_in);

103
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.200 2008-12-05 20:04:06 nicm Exp $ */ /* $Id: tmux.h,v 1.201 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -450,6 +450,31 @@ struct grid_data {
struct grid_cell **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. */ /* Screen selection. */
struct screen_sel { struct screen_sel {
int flag; int flag;
@ -459,6 +484,8 @@ struct screen_sel {
u_int ex; u_int ex;
u_int ey; u_int ey;
struct grid_cell cell;
}; };
/* Virtual screen. */ /* Virtual screen. */
@ -566,17 +593,12 @@ struct window {
struct input_ctx ictx; struct input_ctx ictx;
struct options options;
int flags; int flags;
#define WINDOW_BELL 0x1 #define WINDOW_BELL 0x1
#define WINDOW_HIDDEN 0x2 #define WINDOW_HIDDEN 0x2
#define WINDOW_ACTIVITY 0x4 #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 *screen;
struct screen base; struct screen base;
@ -599,31 +621,6 @@ struct winlink {
RB_HEAD(winlinks, winlink); RB_HEAD(winlinks, winlink);
SLIST_HEAD(winlink_stack, 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. */ /* Paste buffer. */
struct paste_buffer { struct paste_buffer {
char *data; char *data;
@ -787,6 +784,7 @@ struct cmd_entry {
#define CMD_DFLAG 0x8 #define CMD_DFLAG 0x8
#define CMD_ONEARG 0x10 #define CMD_ONEARG 0x10
#define CMD_ZEROONEARG 0x20 #define CMD_ZEROONEARG 0x20
#define CMD_GFLAG 0x40
int flags; int flags;
void (*init)(struct cmd *, int); void (*init)(struct cmd *, int);
@ -819,6 +817,13 @@ struct cmd_buffer_data {
char *arg; char *arg;
}; };
struct cmd_option_data {
int flags;
char *target;
char *option;
char *value;
};
/* Key binding. */ /* Key binding. */
struct binding { struct binding {
int key; int key;
@ -844,7 +849,9 @@ struct set_option_entry {
const char **choices; const char **choices;
}; };
extern const struct set_option_entry set_option_table[]; extern const struct set_option_entry set_option_table[];
#define NSETOPTION 18 extern const struct set_option_entry set_window_option_table[];
#define NSETOPTION 17
#define NSETWINDOWOPTION 9
/* Edit keys. */ /* Edit keys. */
enum mode_key { enum mode_key {
@ -907,6 +914,7 @@ char *fgetln(FILE *, size_t *);
extern volatile sig_atomic_t sigwinch; extern volatile sig_atomic_t sigwinch;
extern volatile sig_atomic_t sigterm; extern volatile sig_atomic_t sigterm;
extern struct options global_options; extern struct options global_options;
extern struct options global_window_options;
extern char *cfg_file; extern char *cfg_file;
extern int debug_level; extern int debug_level;
extern int be_quiet; extern int be_quiet;
@ -956,6 +964,20 @@ void tty_vwrite_window(void *, int, va_list);
void tty_write_session(void *, int, ...); void tty_write_session(void *, int, ...);
void tty_vwrite_session(void *, int, va_list); 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 */ /* paste.c */
void paste_init_stack(struct paste_stack *); void paste_init_stack(struct paste_stack *);
void paste_free_stack(struct paste_stack *); void paste_free_stack(struct paste_stack *);
@ -1066,6 +1088,16 @@ void cmd_buffer_send(struct cmd *, struct buffer *);
void cmd_buffer_recv(struct cmd *, struct buffer *); void cmd_buffer_recv(struct cmd *, struct buffer *);
void cmd_buffer_free(struct cmd *); void cmd_buffer_free(struct cmd *);
void cmd_buffer_print(struct cmd *, char *, size_t); 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 */ /* client.c */
int client_init(const char *, struct client_ctx *, int, int); 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_free(struct screen *);
void screen_set_title(struct screen *, const char *); void screen_set_title(struct screen *, const char *);
void screen_resize(struct screen *, u_int, u_int); 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 *); void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int); int screen_check_selection(struct screen *, u_int, u_int);
void screen_display_copy_area(struct screen *, struct screen *, void screen_display_copy_area(struct screen *, struct screen *,

View File

@ -1,4 +1,4 @@
/* $Id: window-copy.c,v 1.33 2008-11-12 23:39:25 nicm Exp $ */ /* $Id: window-copy.c,v 1.34 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -137,7 +137,7 @@ window_copy_key(struct window *w, struct client *c, int key)
struct screen *s = &data->screen; struct screen *s = &data->screen;
int table; 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)) { switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT: case MODEKEY_QUIT:
window_reset_mode(w); 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); memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr, size = xsnprintf(hdr, sizeof hdr,
"[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base)); "[%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_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr); screen_write_puts(ctx, &gc, "%s", hdr);
gc.attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE); screen_write_puts(ctx, &gc, "%s", hdr);
} else } else
size = 0; size = 0;
@ -308,11 +309,17 @@ window_copy_update_selection(struct window *w)
{ {
struct window_copy_mode_data *data = w->modedata; struct window_copy_mode_data *data = w->modedata;
struct screen *s = &data->screen; struct screen *s = &data->screen;
struct grid_cell gc;
u_int sx, sy, tx, ty; u_int sx, sy, tx, ty;
if (!s->sel.flag) if (!s->sel.flag)
return (0); 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. */ /* Find top-left of screen. */
tx = data->ox; tx = data->ox;
ty = screen_hsize(&w->base) - data->oy; ty = screen_hsize(&w->base) - data->oy;
@ -343,7 +350,8 @@ window_copy_update_selection(struct window *w)
} }
sy = screen_hsize(s) + sy; 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); return (1);
} }

View File

@ -1,4 +1,4 @@
/* $Id: window-more.c,v 1.20 2008-09-26 06:45:28 nicm Exp $ */ /* $Id: window-more.c,v 1.21 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -123,13 +123,13 @@ window_more_resize(struct window *w, u_int sx, u_int sy)
} }
void 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 window_more_mode_data *data = w->modedata;
struct screen *s = &data->screen; struct screen *s = &data->screen;
int table; 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)) { switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT: case MODEKEY_QUIT:
window_reset_mode(w); 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, size = xsnprintf(hdr, sizeof hdr,
"[%u/%u]", data->top, ARRAY_LENGTH(&data->list)); "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
screen_write_cursormove(ctx, screen_size_x(s) - size, 0); 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); screen_write_puts(ctx, &gc, "%s", hdr);
gc.attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE); memcpy(&gc, &grid_default_cell, sizeof gc);
} else } else
size = 0; size = 0;

View File

@ -1,4 +1,4 @@
/* $Id: window-scroll.c,v 1.24 2008-09-25 20:08:57 nicm Exp $ */ /* $Id: window-scroll.c,v 1.25 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -101,13 +101,13 @@ window_scroll_resize(struct window *w, u_int sx, u_int sy)
} }
void 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 window_scroll_mode_data *data = w->modedata;
struct screen *s = &data->screen; struct screen *s = &data->screen;
int table; 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)) { switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT: case MODEKEY_QUIT:
window_reset_mode(w); window_reset_mode(w);
@ -157,10 +157,11 @@ window_scroll_write_line(
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr, size = xsnprintf(hdr, sizeof hdr,
"[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base)); "[%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_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr); screen_write_puts(ctx, &gc, "%s", hdr);
gc.attr &= ~(GRID_ATTR_BRIGHT|GRID_ATTR_REVERSE); memcpy(&gc, &grid_default_cell, sizeof gc);
} else } else
size = 0; size = 0;

View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.51 2008-11-16 10:10:26 nicm Exp $ */ /* $Id: window.c,v 1.52 2008-12-08 16:19:51 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -207,11 +207,11 @@ window_create(const char *name,
w->mode = NULL; w->mode = NULL;
w->flags = 0; w->flags = 0;
w->limitx = w->limity = UINT_MAX;
screen_init(&w->base, sx, sy, hlimit); screen_init(&w->base, sx, sy, hlimit);
w->screen = &w->base; w->screen = &w->base;
input_init(w); input_init(w);
options_init(&w->options, &global_window_options);
if (name == NULL) { if (name == NULL) {
/* XXX */ /* XXX */
@ -308,6 +308,7 @@ window_destroy(struct window *w)
input_free(w); input_free(w);
window_reset_mode(w); window_reset_mode(w);
options_free(&w->options);
screen_free(&w->base); screen_free(&w->base);
buffer_destroy(w->in); buffer_destroy(w->in);