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
* 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
@ -728,4 +762,8 @@
(including mutt, emacs). No status bar yet and no key remapping or other
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
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-

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
.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

2
TODO
View File

@ -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

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>
@ -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);
}

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>
@ -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);
}

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
* 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;
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 == NULL)
return;
wl = cmd_find_window(ctx, data->target, &s);
if (wl == 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 (*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;
}
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)
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>
@ -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);
}

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
* 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);

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>
@ -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)

View File

@ -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

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>
@ -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.
*

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>
@ -225,9 +225,6 @@ log_vfatal(const char *msg, va_list ap)
}
free(fmt);
#ifdef DEBUG
abort();
#endif
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>
@ -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)

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>
@ -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++;

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>
@ -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);

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>
@ -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;

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>
@ -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;
}

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>
@ -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));
}

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>
@ -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);

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>
@ -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);

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>
@ -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 *,

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>
@ -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);
}

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>
@ -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;

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>
@ -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;

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>
@ -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);