Merge branch 'obsd-master'

Conflicts:
	Makefile
	cmd-server-info.c
	cmd-start-server.c
pull/1/head
Thomas Adam 2014-01-31 21:39:56 +00:00
commit d50e47fc4a
35 changed files with 1414 additions and 699 deletions

138
Makefile Normal file
View File

@ -0,0 +1,138 @@
# $OpenBSD$
PROG= tmux
SRCS= arguments.c \
attributes.c \
cfg.c \
client.c \
clock.c \
cmd-attach-session.c \
cmd-bind-key.c \
cmd-break-pane.c \
cmd-capture-pane.c \
cmd-choose-buffer.c \
cmd-choose-client.c \
cmd-choose-list.c \
cmd-choose-tree.c \
cmd-clear-history.c \
cmd-clock-mode.c \
cmd-command-prompt.c \
cmd-confirm-before.c \
cmd-copy-mode.c \
cmd-delete-buffer.c \
cmd-detach-client.c \
cmd-display-message.c \
cmd-display-panes.c \
cmd-find-window.c \
cmd-has-session.c \
cmd-if-shell.c \
cmd-join-pane.c \
cmd-kill-pane.c \
cmd-kill-server.c \
cmd-kill-session.c \
cmd-kill-window.c \
cmd-link-window.c \
cmd-list-buffers.c \
cmd-list-clients.c \
cmd-list-commands.c \
cmd-list-keys.c \
cmd-list-panes.c \
cmd-list-sessions.c \
cmd-list-windows.c \
cmd-list.c \
cmd-load-buffer.c \
cmd-lock-server.c \
cmd-move-window.c \
cmd-new-session.c \
cmd-new-window.c \
cmd-paste-buffer.c \
cmd-pipe-pane.c \
cmd-refresh-client.c \
cmd-rename-session.c \
cmd-rename-window.c \
cmd-resize-pane.c \
cmd-respawn-pane.c \
cmd-respawn-window.c \
cmd-rotate-window.c \
cmd-run-shell.c \
cmd-save-buffer.c \
cmd-select-layout.c \
cmd-select-pane.c \
cmd-select-window.c \
cmd-send-keys.c \
cmd-set-buffer.c \
cmd-set-environment.c \
cmd-set-option.c \
cmd-show-environment.c \
cmd-show-messages.c \
cmd-show-options.c \
cmd-source-file.c \
cmd-split-window.c \
cmd-string.c \
cmd-suspend-client.c \
cmd-swap-pane.c \
cmd-swap-window.c \
cmd-switch-client.c \
cmd-unbind-key.c \
cmd-unlink-window.c \
cmd-wait-for.c \
cmd.c \
cmd-queue.c \
colour.c \
control.c \
control-notify.c \
environ.c \
format.c \
grid-cell.c \
grid-view.c \
grid.c \
input-keys.c \
input.c \
job.c \
key-bindings.c \
key-string.c \
layout-custom.c \
layout-set.c \
layout.c \
log.c \
mode-key.c \
names.c \
notify.c \
options-table.c \
options.c \
paste.c \
procname.c \
resize.c \
screen-redraw.c \
screen-write.c \
screen.c \
server-client.c \
server-fn.c \
server-window.c \
server.c \
session.c \
signal.c \
status.c \
style.c \
tmux.c \
tty-acs.c \
tty-keys.c \
tty-term.c \
tty.c \
utf8.c \
window-choose.c \
window-clock.c \
window-copy.c \
window.c \
xmalloc.c \
xterm-keys.c
CDIAGFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CDIAGFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CDIAGFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
CDIAGFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
LDADD= -lutil -lcurses -levent
DPADD= ${LIBUTIL} ${LIBCURSES} ${LIBEVENT}
.include <bsd.prog.mk>

View File

@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
@ -77,7 +78,6 @@ struct args *
args_parse(const char *template, int argc, char **argv)
{
struct args *args;
char *ptr;
int opt;
args = xcalloc(1, sizeof *args);
@ -88,7 +88,7 @@ args_parse(const char *template, int argc, char **argv)
while ((opt = getopt(argc, argv, template)) != -1) {
if (opt < 0)
continue;
if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
if (opt == '?' || strchr(template, opt) == NULL) {
args_free(args);
return (NULL);
}
@ -204,19 +204,15 @@ args_set(struct args *args, u_char ch, const char *value)
/* Replace existing argument. */
if ((entry = args_find(args, ch)) != NULL) {
free(entry->value);
if (value != NULL)
entry->value = xstrdup(value);
else
entry->value = NULL;
return;
entry->value = NULL;
} else {
entry = xcalloc(1, sizeof *entry);
entry->flag = ch;
RB_INSERT(args_tree, &args->tree, entry);
}
entry = xcalloc(1, sizeof *entry);
entry->flag = ch;
if (value != NULL)
entry->value = xstrdup(value);
RB_INSERT(args_tree, &args->tree, entry);
}
/* Get argument value. Will be NULL if it isn't present. */

View File

@ -118,10 +118,15 @@ retry:
close(fd);
xasprintf(&lockfile, "%s.lock", path);
if ((lockfd = client_get_lock(lockfile)) == -1)
if ((lockfd = client_get_lock(lockfile)) == -1) {
free(lockfile);
goto retry;
if (unlink(path) != 0 && errno != ENOENT)
}
if (unlink(path) != 0 && errno != ENOENT) {
free(lockfile);
close(lockfd);
return (-1);
}
fd = server_start(lockfd, lockfile);
free(lockfile);
close(lockfd);
@ -232,7 +237,8 @@ client_main(int argc, char **argv, int flags)
/* Initialise the client socket and start the server. */
fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
if (fd == -1) {
fprintf(stderr, "failed to connect to server\n");
fprintf(stderr, "failed to connect to server: %s\n",
strerror(errno));
return (1);
}

View File

@ -47,6 +47,9 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
{
struct session *s;
struct client *c;
struct winlink *wl = NULL;
struct window *w = NULL;
struct window_pane *wp = NULL;
const char *update;
char *cause;
u_int i;
@ -59,12 +62,31 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
return (CMD_RETURN_ERROR);
}
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
if (tflag == NULL) {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
} else {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
w = cmd_lookup_windowid(tflag);
if (w == NULL && (wp = cmd_lookup_paneid(tflag)) != NULL)
w = wp->window;
if (w != NULL)
wl = winlink_find_by_window(&s->windows, w);
}
if (cmdq->client == NULL)
return (CMD_RETURN_NORMAL);
if (wl != NULL) {
if (wp != NULL)
window_set_active_pane(wp->window, wp);
session_set_current(s, wl);
}
if (cmdq->client->session != NULL) {
if (dflag) {
/*

View File

@ -38,10 +38,20 @@ const struct cmd_entry cmd_kill_server_entry = {
cmd_kill_server_exec
};
const struct cmd_entry cmd_start_server_entry = {
"start-server", "start",
"", 0, 0,
"",
CMD_STARTSERVER,
NULL,
cmd_kill_server_exec
};
enum cmd_retval
cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_q *cmdq)
cmd_kill_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
{
kill(getpid(), SIGTERM);
if (self->entry == &cmd_kill_server_entry)
kill(getpid(), SIGTERM);
return (CMD_RETURN_NORMAL);
}

View File

@ -107,13 +107,16 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
if (cp != NULL && *cp != '\0') {
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
} else if (cp != NULL)
free(cp);
cwd = fd;
} else if (c != NULL && c->session == NULL)
cwd = c->cwd;

View File

@ -82,6 +82,37 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
detached = args_has(args, 'd');
if (args->argc == 0)
cmd = options_get_string(&s->options, "default-command");
else
cmd = args->argv[0];
if (args_has(args, 'c')) {
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, s->curw);
format_window_pane(ft, s->curw->window->active);
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
if (cp != NULL && *cp != '\0') {
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
} else if (cp != NULL)
free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else
cwd = s->cwd;
wl = NULL;
if (idx != -1)
wl = winlink_find_by_index(&s->windows, idx);
@ -102,34 +133,6 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
if (args->argc == 0)
cmd = options_get_string(&s->options, "default-command");
else
cmd = args->argv[0];
if (args_has(args, 'c')) {
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
format_client(ft, c);
format_session(ft, s);
format_winlink(ft, s, s->curw);
format_window_pane(ft, s->curw->window->active);
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;
else
cwd = s->cwd;
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause);

View File

@ -69,9 +69,7 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
va_start(ap, fmt);
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
va_end(ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
@ -104,9 +102,7 @@ cmdq_info(struct cmd_q *cmdq, const char *fmt, ...)
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
va_start(ap, fmt);
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
va_end(ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);

View File

@ -60,6 +60,9 @@ struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_q *,
struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *,
const char *);
struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *,
const struct options_table_entry *, struct options *,
const char *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
@ -304,9 +307,11 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
break;
case OPTIONS_TABLE_COLOUR:
o = cmd_set_option_colour(self, cmdq, oe, oo, value);
style_update_new(oo, o->name, oe->style);
break;
case OPTIONS_TABLE_ATTRIBUTES:
o = cmd_set_option_attributes(self, cmdq, oe, oo, value);
style_update_new(oo, o->name, oe->style);
break;
case OPTIONS_TABLE_FLAG:
o = cmd_set_option_flag(self, cmdq, oe, oo, value);
@ -314,6 +319,9 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
case OPTIONS_TABLE_CHOICE:
o = cmd_set_option_choice(self, cmdq, oe, oo, value);
break;
case OPTIONS_TABLE_STYLE:
o = cmd_set_option_style(self, cmdq, oe, oo, value);
break;
}
if (o == NULL)
return (-1);
@ -462,3 +470,23 @@ cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
return (options_set_number(oo, oe->name, choice));
}
/* Set a style option. */
struct options_entry *
cmd_set_option_style(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
struct args *args = self->args;
struct options_entry *o;
int append;
append = args_has(args, 'a');
if ((o = options_set_style(oo, oe->name, value, append)) == NULL) {
cmdq_error(cmdq, "bad style: %s", value);
return (NULL);
}
style_update_old(oo, oe->name, &o->style);
return (o);
}

View File

@ -20,6 +20,8 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <vis.h>
#include "tmux.h"
@ -31,13 +33,98 @@ enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
"t:", 0, 0,
CMD_TARGET_CLIENT_USAGE,
"IJTt:", 0, 0,
"[-IJT] " CMD_TARGET_CLIENT_USAGE,
0,
NULL,
cmd_show_messages_exec
};
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
"", 0, 0,
"",
0,
NULL,
cmd_show_messages_exec
};
void cmd_show_messages_server (struct cmd_q *);
void cmd_show_messages_terminals (struct cmd_q *);
void cmd_show_messages_jobs (struct cmd_q *);
void
cmd_show_messages_server (struct cmd_q *cmdq)
{
char *tim;
tim = ctime(&start_time);
*strchr(tim, '\n') = '\0';
cmdq_print(cmdq, "started %s", tim);
cmdq_print(cmdq, "socket path %s", socket_path);
cmdq_print(cmdq, "debug level %d", debug_level);
cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
}
void
cmd_show_messages_terminals (struct cmd_q *cmdq)
{
struct tty_term *term;
const struct tty_term_code_entry *ent;
struct tty_code *code;
u_int i, n;
char out[80];
n = 0;
LIST_FOREACH(term, &tty_terms, entry) {
cmdq_print(cmdq,
"Terminal %u: %s [references=%u, flags=0x%x]:",
n, term->name, term->references, term->flags);
n++;
for (i = 0; i < NTTYCODE; i++) {
ent = &tty_term_codes[i];
code = &term->codes[ent->code];
switch (code->type) {
case TTYCODE_NONE:
cmdq_print(cmdq, "%4u: %s: [missing]",
ent->code, ent->name);
break;
case TTYCODE_STRING:
strnvis(out, code->value.string, sizeof out,
VIS_OCTAL|VIS_TAB|VIS_NL);
cmdq_print(cmdq, "%4u: %s: (string) %s",
ent->code, ent->name, out);
break;
case TTYCODE_NUMBER:
cmdq_print(cmdq, "%4u: %s: (number) %d",
ent->code, ent->name, code->value.number);
break;
case TTYCODE_FLAG:
cmdq_print(cmdq, "%4u: %s: (flag) %s",
ent->code, ent->name,
code->value.flag ? "true" : "false");
break;
}
}
}
}
void
cmd_show_messages_jobs (struct cmd_q *cmdq)
{
struct job *job;
u_int n;
n = 0;
LIST_FOREACH(job, &all_jobs, lentry) {
cmdq_print(cmdq,
"Job %u: %s [fd=%d, pid=%d, status=%d]",
n, job->cmd, job->fd, job->pid, job->status);
n++;
}
}
enum cmd_retval
cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
{
@ -46,6 +133,27 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
struct message_entry *msg;
char *tim;
u_int i;
int done;
done = 0;
if (args_has (args, 'I') || self->entry == &cmd_server_info_entry) {
cmd_show_messages_server (cmdq);
done = 1;
}
if (args_has (args, 'T') || self->entry == &cmd_server_info_entry) {
if (done)
cmdq_print (cmdq, "%s", "");
cmd_show_messages_terminals (cmdq);
done = 1;
}
if (args_has (args, 'J') || self->entry == &cmd_server_info_entry) {
if (done)
cmdq_print (cmdq, "%s", "");
cmd_show_messages_jobs (cmdq);
done = 1;
}
if (done)
return (CMD_RETURN_NORMAL);
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);

View File

@ -94,13 +94,16 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
cp = format_expand(ft, args_get(args, 'c'));
format_free(ft);
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
if (cp != NULL && *cp != '\0') {
fd = open(cp, O_RDONLY|O_DIRECTORY);
free(cp);
if (fd == -1) {
cmdq_error(cmdq, "bad working directory: %s",
strerror(errno));
return (CMD_RETURN_ERROR);
}
} else if (cp != NULL)
free(cp);
cwd = fd;
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
cwd = cmdq->client->cwd;

View File

@ -1,42 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2007 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 "tmux.h"
/*
* Start the server and do nothing else.
*/
enum cmd_retval cmd_start_server_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_start_server_entry = {
"start-server", "start",
"", 0, 0,
"",
CMD_STARTSERVER,
NULL,
cmd_start_server_exec
};
enum cmd_retval
cmd_start_server_exec(unused struct cmd *self, unused struct cmd_q *cmdq)
{
return (CMD_RETURN_NORMAL);
}

View File

@ -59,9 +59,13 @@ cmd_switch_client_key_binding(struct cmd *self, int key)
enum cmd_retval
cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct session *s;
struct args *args = self->args;
struct client *c;
struct session *s;
struct winlink *wl = NULL;
struct window *w = NULL;
struct window_pane *wp = NULL;
const char *tflag;
if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
return (CMD_RETURN_ERROR);
@ -76,7 +80,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
}
}
s = NULL;
tflag = args_get(args, 't');
if (args_has(args, 'n')) {
if ((s = session_next_session(c->session)) == NULL) {
cmdq_error(cmdq, "can't find next session");
@ -94,10 +98,33 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
cmdq_error(cmdq, "can't find last session");
return (CMD_RETURN_ERROR);
}
} else
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
if (s == NULL)
return (CMD_RETURN_ERROR);
} else {
if (tflag == NULL) {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
} else {
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
return (CMD_RETURN_ERROR);
w = cmd_lookup_windowid(tflag);
if (w == NULL &&
(wp = cmd_lookup_paneid(tflag)) != NULL)
w = wp->window;
if (w != NULL)
wl = winlink_find_by_window(&s->windows, w);
}
if (cmdq->client == NULL)
return (CMD_RETURN_NORMAL);
if (wl != NULL) {
if (wp != NULL)
window_set_active_pane(wp->window, wp);
session_set_current(s, wl);
}
}
if (c->session != NULL)
c->last_session = c->session;

2
cmd.c
View File

@ -125,9 +125,7 @@ struct session *cmd_lookup_session(const char *, int *);
struct session *cmd_lookup_session_id(const char *);
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
int cmd_lookup_index(struct session *, const char *, int *);
struct window_pane *cmd_lookup_paneid(const char *);
struct winlink *cmd_lookup_winlink_windowid(struct session *, const char *);
struct window *cmd_lookup_windowid(const char *);
struct session *cmd_window_session(struct cmd_q *, struct window *,
struct winlink **);
struct winlink *cmd_find_window_offset(const char *, struct session *, int *);

View File

@ -321,6 +321,13 @@ format_expand(struct format_tree *ft, const char *fmt)
break;
fmt += n + 1;
continue;
case '#':
while (len - off < 2) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
buf[off++] = '#';
continue;
default:
s = NULL;
if (ch >= 'A' && ch <= 'Z')

5
grid.c
View File

@ -37,7 +37,6 @@
/* Default grid cell data. */
const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " };
const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, (1 << 4) | 1, "_" };
#define grid_put_cell(gd, px, py, gc) do { \
memcpy(&gd->linedata[py].celldata[px], \
@ -124,7 +123,7 @@ grid_compare(struct grid *ga, struct grid *gb)
struct grid_cell *gca, *gcb;
u_int xx, yy;
if (ga->sx != gb->sx || ga->sy != ga->sy)
if (ga->sx != gb->sx || ga->sy != gb->sy)
return (1);
for (yy = 0; yy < ga->sy; yy++) {
@ -644,7 +643,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
if (trim) {
while (off > 0 && buf[off - 1] == ' ')
off--;
}
}
buf[off] = '\0';
return (buf);

57
input.c
View File

@ -74,6 +74,7 @@ void input_csi_dispatch_rm(struct input_ctx *);
void input_csi_dispatch_rm_private(struct input_ctx *);
void input_csi_dispatch_sm(struct input_ctx *);
void input_csi_dispatch_sm_private(struct input_ctx *);
void input_csi_dispatch_winops(struct input_ctx *);
void input_csi_dispatch_sgr(struct input_ctx *);
int input_dcs_dispatch(struct input_ctx *);
int input_utf8_open(struct input_ctx *);
@ -154,6 +155,7 @@ enum input_csi_type {
INPUT_CSI_SM_PRIVATE,
INPUT_CSI_TBC,
INPUT_CSI_VPA,
INPUT_CSI_WINOPS,
};
/* Control (CSI) command table. */
@ -188,6 +190,7 @@ const struct input_table_entry input_csi_table[] = {
{ 'q', " ", INPUT_CSI_DECSCUSR },
{ 'r', "", INPUT_CSI_DECSTBM },
{ 's', "", INPUT_CSI_SCP },
{ 't', "", INPUT_CSI_WINOPS },
{ 'u', "", INPUT_CSI_RCP },
};
@ -1077,7 +1080,7 @@ input_csi_dispatch(struct input_ctx *ictx)
struct screen_write_ctx *sctx = &ictx->ctx;
struct screen *s = sctx->s;
struct input_table_entry *entry;
int n, m;
int n, m;
if (ictx->flags & INPUT_DISCARD)
return (0);
@ -1117,6 +1120,9 @@ input_csi_dispatch(struct input_ctx *ictx)
m = input_get(ictx, 1, 1, 1);
screen_write_cursormove(sctx, m - 1, n - 1);
break;
case INPUT_CSI_WINOPS:
input_csi_dispatch_winops(ictx);
break;
case INPUT_CSI_CUU:
screen_write_cursorup(sctx, input_get(ictx, 0, 1, 1));
break;
@ -1430,6 +1436,55 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
}
}
/* Handle CSI window operations. */
void
input_csi_dispatch_winops(struct input_ctx *ictx)
{
struct window_pane *wp = ictx->wp;
int n, m;
m = 0;
while ((n = input_get(ictx, m, 0, -1)) != -1) {
switch (n) {
case 1:
case 2:
case 5:
case 6:
case 7:
case 11:
case 13:
case 14:
case 19:
case 20:
case 21:
case 24:
break;
case 3:
case 4:
case 8:
m++;
if (input_get(ictx, m, 0, -1) == -1)
return;
/* FALLTHROUGH */
case 9:
case 10:
case 22:
case 23:
m++;
if (input_get(ictx, m, 0, -1) == -1)
return;
break;
case 18:
input_reply(ictx, "\033[8;%u;%u", wp->sy, wp->sx);
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
break;
}
m++;
}
}
/* Handle CSI SGR. */
void
input_csi_dispatch_sgr(struct input_ctx *ictx)

View File

@ -195,32 +195,43 @@ const struct options_table_entry session_options_table[] = {
{ .name = "message-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "message-style"
},
{ .name = "message-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 3
.default_num = 3,
.style = "message-style"
},
{ .name = "message-command-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "message-command-style"
},
{ .name = "message-command-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 0
.default_num = 0,
.style = "message-command-style"
},
{ .name = "message-command-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 3
.default_num = 3,
.style = "message-command-style"
},
{ .name = "message-command-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "bg=black,fg=yellow"
},
{ .name = "message-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 0
.default_num = 0,
.style = "message-style"
},
{ .name = "message-limit",
@ -230,6 +241,11 @@ const struct options_table_entry session_options_table[] = {
.default_num = 20
},
{ .name = "message-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "bg=yellow,fg=black"
},
{ .name = "mouse-resize-pane",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
@ -252,22 +268,36 @@ const struct options_table_entry session_options_table[] = {
{ .name = "pane-active-border-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "pane-active-border-style"
},
{ .name = "pane-active-border-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 2
.default_num = 2,
.style = "pane-active-border-style"
},
{ .name = "pane-active-border-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "fg=green"
},
{ .name = "pane-border-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "pane-border-style"
},
{ .name = "pane-border-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "pane-border-style"
},
{ .name = "pane-border-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "default"
},
{ .name = "prefix",
@ -314,17 +344,20 @@ const struct options_table_entry session_options_table[] = {
{ .name = "status-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "status-style"
},
{ .name = "status-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 2
.default_num = 2,
.style = "status-style"
},
{ .name = "status-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 0
.default_num = 0,
.style = "status-style"
},
{ .name = "status-interval",
@ -353,17 +386,20 @@ const struct options_table_entry session_options_table[] = {
{ .name = "status-left-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "status-left-style"
},
{ .name = "status-left-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "status-left-style"
},
{ .name = "status-left-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "status-left-style"
},
{ .name = "status-left-length",
@ -373,6 +409,11 @@ const struct options_table_entry session_options_table[] = {
.default_num = 10
},
{ .name = "status-left-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "default"
},
{ .name = "status-position",
.type = OPTIONS_TABLE_CHOICE,
.choices = options_table_status_position_list,
@ -386,17 +427,20 @@ const struct options_table_entry session_options_table[] = {
{ .name = "status-right-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "status-right-style"
},
{ .name = "status-right-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "status-right-style"
},
{ .name = "status-right-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "status-right-style"
},
{ .name = "status-right-length",
@ -406,6 +450,16 @@ const struct options_table_entry session_options_table[] = {
.default_num = 40
},
{ .name = "status-right-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "default"
},
{ .name = "status-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "bg=green,fg=black"
},
{ .name = "status-utf8",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0 /* overridden in main() */
@ -536,17 +590,20 @@ const struct options_table_entry window_options_table[] = {
{ .name = "mode-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "mode-style"
},
{ .name = "mode-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 3
.default_num = 3,
.style = "mode-style"
},
{ .name = "mode-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 0
.default_num = 0,
.style = "mode-style"
},
{ .name = "mode-keys",
@ -561,6 +618,11 @@ const struct options_table_entry window_options_table[] = {
.default_num = 0
},
{ .name = "mode-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "bg=yellow,fg=black"
},
{ .name = "monitor-activity",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
@ -616,72 +678,101 @@ const struct options_table_entry window_options_table[] = {
{ .name = "window-status-activity-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE
.default_num = GRID_ATTR_REVERSE,
.style = "window-status-activity-style"
},
{ .name = "window-status-activity-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "window-status-activity-style"
},
{ .name = "window-status-activity-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "window-status-activity-style"
},
{ .name = "window-status-bell-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE
},
{ .name = "window-status-bell-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-bell-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-content-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE
},
{ .name = "window-status-content-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-content-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
{ .name = "window-status-activity-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "reverse"
},
{ .name = "window-status-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "window-status-style"
},
{ .name = "window-status-bell-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
.style = "window-status-bell-style"
},
{ .name = "window-status-bell-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8,
.style = "window-status-bell-style"
},
{ .name = "window-status-bell-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8,
.style = "window-status-bell-style"
},
{ .name = "window-status-bell-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "reverse"
},
{ .name = "window-status-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "window-status-style"
},
{ .name = "window-status-content-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
.style = "window-status-content-style"
},
{ .name = "window-status-content-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8,
.style = "window-status-content-style"
},
{ .name = "window-status-content-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8,
.style = "window-status-content-style"
},
{ .name = "window-status-content-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "reverse"
},
{ .name = "window-status-current-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
.default_num = 0,
.style = "window-status-current-style"
},
{ .name = "window-status-current-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "window-status-current-style"
},
{ .name = "window-status-current-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "window-status-current-style"
},
{ .name = "window-status-current-format",
@ -689,24 +780,15 @@ const struct options_table_entry window_options_table[] = {
.default_str = "#I:#W#F"
},
{ .name = "window-status-last-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0
},
{ .name = "window-status-last-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
},
{ .name = "window-status-last-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
{ .name = "window-status-current-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "default"
},
{ .name = "window-status-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8
.default_num = 8,
.style = "window-status-style"
},
{ .name = "window-status-format",
@ -714,11 +796,39 @@ const struct options_table_entry window_options_table[] = {
.default_str = "#I:#W#F"
},
{ .name = "window-status-last-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = 0,
.style = "window-status-last-style"
},
{ .name = "window-status-last-bg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8,
.style = "window-status-last-style"
},
{ .name = "window-status-last-fg",
.type = OPTIONS_TABLE_COLOUR,
.default_num = 8,
.style = "window-status-last-style"
},
{ .name = "window-status-last-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "default"
},
{ .name = "window-status-separator",
.type = OPTIONS_TABLE_STRING,
.default_str = " "
},
{ .name = "window-status-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "default"
},
{ .name = "wrap-search",
.type = OPTIONS_TABLE_FLAG,
.default_num = 1
@ -740,10 +850,17 @@ options_table_populate_tree(
const struct options_table_entry *oe;
for (oe = table; oe->name != NULL; oe++) {
if (oe->default_str != NULL)
switch (oe->type) {
case OPTIONS_TABLE_STRING:
options_set_string(oo, oe->name, "%s", oe->default_str);
else
break;
case OPTIONS_TABLE_STYLE:
options_set_style(oo, oe->name, oe->default_str, 0);
break;
default:
options_set_number(oo, oe->name, oe->default_num);
break;
}
}
}
@ -788,6 +905,10 @@ options_table_print_entry(const struct options_table_entry *oe,
s = oe->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
case OPTIONS_TABLE_STYLE:
s = style_tostring(&o->style);
xsnprintf(out, sizeof out, "%s", s);
break;
}
return (out);
}

View File

@ -26,7 +26,7 @@
/*
* Option handling; each option has a name, type and value and is stored in
* a splay tree.
* a red-black tree.
*/
RB_GENERATE(options_tree, options_entry, entry, options_cmp);
@ -109,6 +109,7 @@ options_set_string(struct options *oo, const char *name, const char *fmt, ...)
o = xmalloc(sizeof *o);
o->name = xstrdup(name);
RB_INSERT(options_tree, &oo->tree, o);
memcpy(&o->style, &grid_default_cell, sizeof o->style);
} else if (o->type == OPTIONS_STRING)
free(o->str);
@ -140,6 +141,7 @@ options_set_number(struct options *oo, const char *name, long long value)
o = xmalloc(sizeof *o);
o->name = xstrdup(name);
RB_INSERT(options_tree, &oo->tree, o);
memcpy(&o->style, &grid_default_cell, sizeof o->style);
} else if (o->type == OPTIONS_STRING)
free(o->str);
@ -159,3 +161,37 @@ options_get_number(struct options *oo, const char *name)
fatalx("option not a number");
return (o->num);
}
struct options_entry *
options_set_style(struct options *oo, const char *name, const char *value,
int append)
{
struct options_entry *o;
if ((o = options_find1(oo, name)) == NULL) {
o = xmalloc(sizeof *o);
o->name = xstrdup(name);
RB_INSERT(options_tree, &oo->tree, o);
} else if (o->type == OPTIONS_STRING)
free(o->str);
if (!append)
memcpy(&o->style, &grid_default_cell, sizeof o->style);
o->type = OPTIONS_STYLE;
if (style_parse(&grid_default_cell, &o->style, value) == -1)
return (NULL);
return (o);
}
struct grid_cell *
options_get_style(struct options *oo, const char *name)
{
struct options_entry *o;
if ((o = options_find(oo, name)) == NULL)
fatalx("missing option");
if (o->type != OPTIONS_STYLE)
fatalx("option not a style");
return (&o->style);
}

View File

@ -29,6 +29,9 @@ int screen_redraw_check_cell(struct client *, u_int, u_int,
int screen_redraw_check_active(u_int, u_int, int, struct window *,
struct window_pane *);
void screen_redraw_draw_borders(struct client *, int, u_int);
void screen_redraw_draw_panes(struct client *, u_int);
void screen_redraw_draw_status(struct client *, u_int);
void screen_redraw_draw_number(struct client *, struct window_pane *);
#define CELL_INSIDE 0
@ -216,15 +219,13 @@ screen_redraw_check_active(u_int px, u_int py, int type, struct window *w,
/* Redraw entire screen. */
void
screen_redraw_screen(struct client *c, int status_only, int borders_only)
screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
int draw_borders)
{
struct window *w = c->session->curw->window;
struct options *oo = &c->session->options;
struct tty *tty = &c->tty;
struct window_pane *wp;
struct grid_cell active_gc, other_gc;
u_int i, j, type, top;
int status, spos, fg, bg;
struct options *oo = &c->session->options;
struct tty *tty = &c->tty;
u_int top;
int status, spos;
/* Suspended clients should not be updated. */
if (c->flags & CLIENT_SUSPENDED)
@ -239,80 +240,15 @@ screen_redraw_screen(struct client *c, int status_only, int borders_only)
top = 0;
if (status && spos == 0)
top = 1;
if (!status)
draw_status = 0;
/* If only drawing status and it is present, don't need the rest. */
if (status_only && status) {
if (top)
tty_draw_line(tty, &c->status, 0, 0, 0);
else
tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
tty_reset(tty);
return;
}
/* Set up pane border attributes. */
memcpy(&other_gc, &grid_marker_cell, sizeof other_gc);
memcpy(&active_gc, &grid_marker_cell, sizeof active_gc);
active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET;
fg = options_get_number(oo, "pane-border-fg");
colour_set_fg(&other_gc, fg);
bg = options_get_number(oo, "pane-border-bg");
colour_set_bg(&other_gc, bg);
fg = options_get_number(oo, "pane-active-border-fg");
colour_set_fg(&active_gc, fg);
bg = options_get_number(oo, "pane-active-border-bg");
colour_set_bg(&active_gc, bg);
/* Draw background and borders. */
for (j = 0; j < tty->sy - status; j++) {
if (status_only) {
if (spos == 1 && j != tty->sy - 1)
continue;
else if (spos == 0 && j != 0)
break;
}
for (i = 0; i < tty->sx; i++) {
type = screen_redraw_check_cell(c, i, j, &wp);
if (type == CELL_INSIDE)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
tty_attributes(tty, &active_gc);
else
tty_attributes(tty, &other_gc);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
}
/* If only drawing borders, that's it. */
if (borders_only)
return;
/* Draw the panes, if necessary. */
TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
for (i = 0; i < wp->sy; i++) {
if (status_only) {
if (spos == 1 && wp->yoff + i != tty->sy - 1)
continue;
else if (spos == 0 && wp->yoff + i != 0)
break;
}
tty_draw_line(
tty, wp->screen, i, wp->xoff, top + wp->yoff);
}
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
/* Draw the status line. */
if (status) {
if (top)
tty_draw_line(tty, &c->status, 0, 0, 0);
else
tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
}
if (draw_borders)
screen_redraw_draw_borders(c, status, top);
if (draw_panes)
screen_redraw_draw_panes(c, top);
if (draw_status)
screen_redraw_draw_status(c, top);
tty_reset(tty);
}
@ -334,6 +270,69 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
tty_reset(&c->tty);
}
/* Draw the borders. */
void
screen_redraw_draw_borders(struct client *c, int status, u_int top)
{
struct window *w = c->session->curw->window;
struct options *oo = &c->session->options;
struct tty *tty = &c->tty;
struct window_pane *wp;
struct grid_cell active_gc, other_gc;
u_int i, j, type;
style_apply(&other_gc, oo, "pane-border-style");
style_apply(&active_gc, oo, "pane-active-border-style");
active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET;
for (j = 0; j < tty->sy - status; j++) {
for (i = 0; i < tty->sx; i++) {
type = screen_redraw_check_cell(c, i, j, &wp);
if (type == CELL_INSIDE)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
tty_attributes(tty, &active_gc);
else
tty_attributes(tty, &other_gc);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
}
}
/* Draw the panes. */
void
screen_redraw_draw_panes(struct client *c, u_int top)
{
struct window *w = c->session->curw->window;
struct tty *tty = &c->tty;
struct window_pane *wp;
struct screen *s;
u_int i;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
}
/* Draw the status line. */
void
screen_redraw_draw_status(struct client *c, u_int top)
{
struct tty *tty = &c->tty;
if (top)
tty_draw_line(tty, &c->status, 0, 0, 0);
else
tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
}
/* Draw number on a pane. */
void
screen_redraw_draw_number(struct client *c, struct window_pane *wp)
@ -368,7 +367,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp)
px -= len * 3;
py -= 2;
memcpy(&gc, &grid_marker_cell, sizeof gc);
memcpy(&gc, &grid_default_cell, sizeof gc);
if (w->active == wp)
colour_set_bg(&gc, active_colour);
else
@ -395,7 +394,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp)
tty_cursor(tty, xoff + wp->sx - len, yoff);
draw_text:
memcpy(&gc, &grid_marker_cell, sizeof gc);
memcpy(&gc, &grid_default_cell, sizeof gc);
if (w->active == wp)
colour_set_fg(&gc, active_colour);
else

View File

@ -248,7 +248,7 @@ screen_write_cnputs(struct screen_write_ctx *ctx,
}
*last = '\0';
screen_write_parsestyle(gc, &lgc, ptr);
style_parse(gc, &lgc, ptr);
ptr = last + 1;
continue;
}
@ -288,89 +288,6 @@ screen_write_cnputs(struct screen_write_ctx *ctx,
free(msg);
}
/* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */
void
screen_write_parsestyle(
struct grid_cell *defgc, struct grid_cell *gc, const char *in)
{
const char delimiters[] = " ,";
char tmp[32];
int val;
size_t end;
u_char fg, bg, attr, flags;
if (*in == '\0')
return;
if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
return;
fg = gc->fg;
bg = gc->bg;
attr = gc->attr;
flags = gc->flags;
do {
end = strcspn(in, delimiters);
if (end > (sizeof tmp) - 1)
return;
memcpy(tmp, in, end);
tmp[end] = '\0';
if (strcasecmp(tmp, "default") == 0) {
fg = defgc->fg;
bg = defgc->bg;
attr = defgc->attr;
flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
flags |=
defgc->flags & (GRID_FLAG_FG256|GRID_FLAG_BG256);
} else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
if ((val = colour_fromstring(tmp + 3)) == -1)
return;
if (*in == 'f' || *in == 'F') {
if (val != 8) {
if (val & 0x100) {
flags |= GRID_FLAG_FG256;
val &= ~0x100;
} else
flags &= ~GRID_FLAG_FG256;
fg = val;
} else {
fg = defgc->fg;
flags &= ~GRID_FLAG_FG256;
flags |= defgc->flags & GRID_FLAG_FG256;
}
} else if (*in == 'b' || *in == 'B') {
if (val != 8) {
if (val & 0x100) {
flags |= GRID_FLAG_BG256;
val &= ~0x100;
} else
flags &= ~GRID_FLAG_BG256;
bg = val;
} else {
bg = defgc->bg;
flags &= ~GRID_FLAG_BG256;
flags |= defgc->flags & GRID_FLAG_BG256;
}
} else
return;
} else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) {
if ((val = attributes_fromstring(tmp + 2)) == -1)
return;
attr &= ~val;
} else {
if ((val = attributes_fromstring(tmp)) == -1)
return;
attr |= val;
}
in += end + strspn(in + end, delimiters);
} while (*in != '\0');
gc->fg = fg;
gc->bg = bg;
gc->attr = attr;
gc->flags = flags;
}
/* Copy from another screen. */
void
screen_write_copy(struct screen_write_ctx *ctx,

View File

@ -111,12 +111,8 @@ screen_set_cursor_colour(struct screen *s, const char *colour_string)
void
screen_set_title(struct screen *s, const char *title)
{
char tmp[BUFSIZ];
strlcpy(tmp, title, sizeof tmp);
free(s->title);
s->title = xstrdup(tmp);
s->title = xstrdup(title);
}
/* Resize screen. */

View File

@ -742,7 +742,7 @@ server_client_check_redraw(struct client *c)
}
if (c->flags & CLIENT_REDRAW) {
screen_redraw_screen(c, 0, 0);
screen_redraw_screen(c, 1, 1, 1);
c->flags &= ~(CLIENT_STATUS|CLIENT_BORDERS);
} else if (c->flags & CLIENT_REDRAWWINDOW) {
TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry)
@ -756,10 +756,10 @@ server_client_check_redraw(struct client *c)
}
if (c->flags & CLIENT_BORDERS)
screen_redraw_screen(c, 0, 1);
screen_redraw_screen(c, 0, 0, 1);
if (c->flags & CLIENT_STATUS)
screen_redraw_screen(c, 1, 0);
screen_redraw_screen(c, 0, 1, 0);
c->tty.flags |= flags;

View File

@ -174,11 +174,11 @@ session_destroy(struct session *s)
RB_INSERT(sessions, &dead_sessions, s);
}
/* Check a session name is valid: not empty and no colons. */
/* Check a session name is valid: not empty and no colons or periods. */
int
session_check_name(const char *name)
{
return (*name != '\0' && strchr(name, ':') == NULL);
return (*name != '\0' && name[strcspn(name, ":.")] == '\0');
}
/* Update session active time. */

118
status.c
View File

@ -80,18 +80,9 @@ status_redraw_get_left(struct client *c,
{
struct session *s = c->session;
char *left;
int fg, bg, attr;
size_t leftlen;
fg = options_get_number(&s->options, "status-left-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(&s->options, "status-left-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(&s->options, "status-left-attr");
if (attr != 0)
gc->attr = attr;
style_apply_update(gc, &s->options, "status-left-style");
left = status_replace(c, NULL,
NULL, NULL, options_get_string(&s->options, "status-left"), t, 1);
@ -110,18 +101,9 @@ status_redraw_get_right(struct client *c,
{
struct session *s = c->session;
char *right;
int fg, bg, attr;
size_t rightlen;
fg = options_get_number(&s->options, "status-right-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(&s->options, "status-right-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(&s->options, "status-right-attr");
if (attr != 0)
gc->attr = attr;
style_apply_update(gc, &s->options, "status-right-style");
right = status_replace(c, NULL,
NULL, NULL, options_get_string(&s->options, "status-right"), t, 1);
@ -177,10 +159,7 @@ status_redraw(struct client *c)
t = c->status_timer.tv_sec;
/* Set up default colour. */
memcpy(&stdgc, &grid_default_cell, sizeof gc);
colour_set_fg(&stdgc, options_get_number(&s->options, "status-fg"));
colour_set_bg(&stdgc, options_get_number(&s->options, "status-bg"));
stdgc.attr |= options_get_number(&s->options, "status-attr");
style_apply(&stdgc, &s->options, "status-style");
/* Create the target screen. */
memcpy(&old_status, &c->status, sizeof old_status);
@ -646,73 +625,22 @@ status_print(
struct session *s = c->session;
const char *fmt;
char *text;
int fg, bg, attr;
fg = options_get_number(oo, "window-status-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-attr");
if (attr != 0)
gc->attr = attr;
style_apply_update(gc, oo, "window-status-style");
fmt = options_get_string(oo, "window-status-format");
if (wl == s->curw) {
fg = options_get_number(oo, "window-status-current-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-current-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-current-attr");
if (attr != 0)
gc->attr = attr;
style_apply_update(gc, oo, "window-status-current-style");
fmt = options_get_string(oo, "window-status-current-format");
}
if (wl == TAILQ_FIRST(&s->lastw)) {
fg = options_get_number(oo, "window-status-last-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-last-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-last-attr");
if (attr != 0)
gc->attr = attr;
}
if (wl == TAILQ_FIRST(&s->lastw))
style_apply_update(gc, oo, "window-status-last-style");
if (wl->flags & WINLINK_BELL) {
fg = options_get_number(oo, "window-status-bell-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-bell-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-bell-attr");
if (attr != 0)
gc->attr = attr;
} else if (wl->flags & WINLINK_CONTENT) {
fg = options_get_number(oo, "window-status-content-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-content-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-content-attr");
if (attr != 0)
gc->attr = attr;
} else if (wl->flags & (WINLINK_ACTIVITY|WINLINK_SILENCE)) {
fg = options_get_number(oo, "window-status-activity-fg");
if (fg != 8)
colour_set_fg(gc, fg);
bg = options_get_number(oo, "window-status-activity-bg");
if (bg != 8)
colour_set_bg(gc, bg);
attr = options_get_number(oo, "window-status-activity-attr");
if (attr != 0)
gc->attr = attr;
}
if (wl->flags & WINLINK_BELL)
style_apply_update(gc, oo, "window-status-bell-style");
else if (wl->flags & WINLINK_CONTENT)
style_apply_update(gc, oo, "window-status-content-style");
else if (wl->flags & (WINLINK_ACTIVITY|WINLINK_SILENCE))
style_apply_update(gc, oo, "window-status-activity-style");
text = status_replace(c, NULL, wl, NULL, fmt, t, 1);
return (text);
@ -814,10 +742,7 @@ status_message_redraw(struct client *c)
if (len > c->tty.sx)
len = c->tty.sx;
memcpy(&gc, &grid_default_cell, sizeof gc);
colour_set_fg(&gc, options_get_number(&s->options, "message-fg"));
colour_set_bg(&gc, options_get_number(&s->options, "message-bg"));
gc.attr |= options_get_number(&s->options, "message-attr");
style_apply(&gc, &s->options, "message-style");
screen_write_start(&ctx, NULL, &c->status);
@ -935,18 +860,11 @@ status_prompt_redraw(struct client *c)
len = c->tty.sx;
off = 0;
memcpy(&gc, &grid_default_cell, sizeof gc);
/* Change colours for command mode. */
if (c->prompt_mdata.mode == 1) {
colour_set_fg(&gc, options_get_number(&s->options, "message-command-fg"));
colour_set_bg(&gc, options_get_number(&s->options, "message-command-bg"));
gc.attr |= options_get_number(&s->options, "message-command-attr");
} else {
colour_set_fg(&gc, options_get_number(&s->options, "message-fg"));
colour_set_bg(&gc, options_get_number(&s->options, "message-bg"));
gc.attr |= options_get_number(&s->options, "message-attr");
}
if (c->prompt_mdata.mode == 1)
style_apply(&gc, &s->options, "message-command-style");
else
style_apply(&gc, &s->options, "message-style");
screen_write_start(&ctx, NULL, &c->status);

224
style.c Normal file
View File

@ -0,0 +1,224 @@
/* $OpenBSD$ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2014 Tiago Cunha <tcunha@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 <string.h>
#include "tmux.h"
/* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */
int
style_parse(const struct grid_cell *defgc, struct grid_cell *gc,
const char *in)
{
const char delimiters[] = " ,";
char tmp[32];
int val;
size_t end;
u_char fg, bg, attr, flags;
if (*in == '\0')
return (0);
if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
return (-1);
fg = gc->fg;
bg = gc->bg;
attr = gc->attr;
flags = gc->flags;
do {
end = strcspn(in, delimiters);
if (end > (sizeof tmp) - 1)
return (-1);
memcpy(tmp, in, end);
tmp[end] = '\0';
if (strcasecmp(tmp, "default") == 0) {
fg = defgc->fg;
bg = defgc->bg;
attr = defgc->attr;
flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
flags |=
defgc->flags & (GRID_FLAG_FG256|GRID_FLAG_BG256);
} else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
if ((val = colour_fromstring(tmp + 3)) == -1)
return (-1);
if (*in == 'f' || *in == 'F') {
if (val != 8) {
if (val & 0x100) {
flags |= GRID_FLAG_FG256;
val &= ~0x100;
} else
flags &= ~GRID_FLAG_FG256;
fg = val;
} else {
fg = defgc->fg;
flags &= ~GRID_FLAG_FG256;
flags |= defgc->flags & GRID_FLAG_FG256;
}
} else if (*in == 'b' || *in == 'B') {
if (val != 8) {
if (val & 0x100) {
flags |= GRID_FLAG_BG256;
val &= ~0x100;
} else
flags &= ~GRID_FLAG_BG256;
bg = val;
} else {
bg = defgc->bg;
flags &= ~GRID_FLAG_BG256;
flags |= defgc->flags & GRID_FLAG_BG256;
}
} else
return (-1);
} else if (strcasecmp(tmp, "none") == 0)
attr = 0;
else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) {
if ((val = attributes_fromstring(tmp + 2)) == -1)
return (-1);
attr &= ~val;
} else {
if ((val = attributes_fromstring(tmp)) == -1)
return (-1);
attr |= val;
}
in += end + strspn(in + end, delimiters);
} while (*in != '\0');
gc->fg = fg;
gc->bg = bg;
gc->attr = attr;
gc->flags = flags;
return (0);
}
/* Convert style to a string. */
const char *
style_tostring(struct grid_cell *gc)
{
int c, off = 0, comma = 0;
static char s[256];
*s = '\0';
if (gc->fg != 8) {
if (gc->flags & GRID_FLAG_FG256)
c = gc->fg | 0x100;
else
c = gc->fg;
off += xsnprintf(s, sizeof s, "fg=%s", colour_tostring(c));
comma = 1;
}
if (gc->bg != 8) {
if (gc->flags & GRID_FLAG_BG256)
c = gc->bg | 0x100;
else
c = gc->bg;
off += xsnprintf(s + off, sizeof s - off, "%sbg=%s",
comma ? "," : "", colour_tostring(c));
comma = 1;
}
if (gc->attr != 0 && gc->attr != GRID_ATTR_CHARSET) {
xsnprintf(s + off, sizeof s - off, "%s%s",
comma ? "," : "", attributes_tostring(gc->attr));
}
if (*s == '\0')
return ("default");
return (s);
}
/* Synchronize new -style option with the old one. */
void
style_update_new(struct options *oo, const char *name, const char *newname)
{
int value;
struct grid_cell *gc;
/* It's a colour or attribute, but with no -style equivalent. */
if (newname == NULL)
return;
gc = options_get_style(oo, newname);
value = options_get_number(oo, name);
if (strstr(name, "-bg") != NULL)
colour_set_bg(gc, value);
else if (strstr(name, "-fg") != NULL)
colour_set_fg(gc, value);
else if (strstr(name, "-attr") != NULL)
gc->attr = value;
}
/* Synchronize all the old options with the new -style one. */
void
style_update_old(struct options *oo, const char *name, struct grid_cell *gc)
{
char newname[128];
int c, size;
size = strrchr(name, '-') - name;
if (gc->flags & GRID_FLAG_BG256)
c = gc->bg | 0x100;
else
c = gc->bg;
xsnprintf(newname, sizeof newname, "%.*s-bg", size, name);
options_set_number(oo, newname, c);
if (gc->flags & GRID_FLAG_FG256)
c = gc->fg | 0x100;
else
c = gc->fg;
xsnprintf(newname, sizeof newname, "%.*s-fg", size, name);
options_set_number(oo, newname, c);
xsnprintf(newname, sizeof newname, "%.*s-attr", size, name);
options_set_number(oo, newname, gc->attr);
}
/* Apply a style. */
void
style_apply(struct grid_cell *gc, struct options *oo, const char *name)
{
struct grid_cell *gcp;
memcpy(gc, &grid_default_cell, sizeof *gc);
gcp = options_get_style(oo, name);
colour_set_fg(gc, gcp->fg);
colour_set_bg(gc, gcp->bg);
gc->attr |= gcp->attr;
}
/* Apply a style, updating if default. */
void
style_apply_update(struct grid_cell *gc, struct options *oo, const char *name)
{
struct grid_cell *gcp;
gcp = options_get_style(oo, name);
if (gcp->fg != 8)
colour_set_fg(gc, gcp->fg);
if (gcp->bg != 8)
colour_set_bg(gc, gcp->bg);
if (gcp->attr != 0)
gc->attr |= gcp->attr;
}

327
tmux.1
View File

@ -774,15 +774,24 @@ is specified, only update the client's status bar.
Rename the session to
.Ar new-name .
.It Xo Ic show-messages
.Op Fl IJT
.Op Fl t Ar target-client
.Xc
.D1 (alias: Ic showmsgs )
Show client messages or server information.
Any messages displayed on the status line are saved in a per-client message
log, up to a maximum of the limit set by the
.Ar message-limit
session option for the session attached to that client.
This command displays the log for
With
.Fl t ,
display the log for
.Ar target-client .
.Fl I,
.Fl J
and
.Fl T
show debugging information about the running server, jobs and terminals.
.It Ic source-file Ar path
.D1 (alias: Ic source )
Execute commands from
@ -2055,11 +2064,6 @@ otherwise a session option.
If
.Fl g
is specified, the global session or window option is set.
With
.Fl a ,
and if the option expects a string,
.Ar value
is appended to the existing setting.
The
.Fl u
flag unsets an option, so a session inherits the option from the global
@ -2076,6 +2080,32 @@ flag suppresses the informational message (as if the
.Ic quiet
server option was set).
.Pp
With
.Fl a ,
and if the option expects a string or a style,
.Ar value
is appended to the existing setting.
For example:
.Bd -literal -offset indent
set -g status-left "foo"
set -ag status-left "bar"
.Ed
.Pp
Will result in
.Ql foobar .
And:
.Bd -literal -offset indent
set -g status-style "bg=red"
set -ag status-style "fg=blue"
.Ed
.Pp
Will result in a red background
.Em and
blue foreground.
Without
.Fl a ,
the result would be the default background and a blue foreground.
.Pp
Available window options are listed under
.Ic set-window-option .
.Pp
@ -2267,26 +2297,18 @@ the entire server will lock after
.Em all
sessions would have locked.
This has no effect as a session option; it must be set as a global option.
.It Ic message-attr Ar attributes
Set status line message attributes, where
.Ar attributes
is either
.Ic none
or a comma-delimited list of one or more of:
.Ic bright
(or
.Ic bold ) ,
.Ic dim ,
.Ic underscore ,
.Ic blink ,
.Ic reverse ,
.Ic hidden ,
or
.Ic italics .
.It Ic message-bg Ar colour
Set status line message background colour, where
.Ar colour
is one of:
.It Ic message-command-style Ar style
Set status line message command style, where
.Ar style
is a comma-separated list of characteristics to be specified.
.Pp
These may be
.Ql bg=colour
to set the background colour,
.Ql fg=colour
to set the foreground colour, and a list of attributes as specified below.
.Pp
The colour is one of:
.Ic black ,
.Ic red ,
.Ic green ,
@ -2307,18 +2329,46 @@ from the 256-colour set,
or a hexadecimal RGB string such as
.Ql #ffffff ,
which chooses the closest match from the default 256-colour set.
.It Ic message-command-attr Ar attributes
Set status line message attributes when in command mode.
.It Ic message-command-bg Ar colour
Set status line message background colour when in command mode.
.It Ic message-command-fg Ar colour
Set status line message foreground colour when in command mode.
.It Ic message-fg Ar colour
Set status line message foreground colour.
.Pp
The attributes is either
.Ic none
or a comma-delimited list of one or more of:
.Ic bright
(or
.Ic bold ) ,
.Ic dim ,
.Ic underscore ,
.Ic blink ,
.Ic reverse ,
.Ic hidden ,
or
.Ic italics ,
to turn an attribute on, or an attribute prefixed with
.Ql no
to turn one off.
.Pp
Examples are:
.Bd -literal -offset indent
fg=yellow,bold,underscore,blink
bg=black,fg=default,noreverse
.Ed
.Pp
With the
.Fl a
flag to the
.Ic set-option
command the new style is added otherwise the existing style is replaced.
.It Ic message-limit Ar number
Set the number of error or information messages to save in the message log for
each client.
The default is 20.
.It Ic message-style Ar style
Set status line message style.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.It Xo Ic mouse-resize-pane
.Op Ic on | off
.Xc
@ -2342,12 +2392,22 @@ window.
.Op Ic on | off
.Xc
If enabled, request mouse input as UTF-8 on UTF-8 terminals.
.It Ic pane-active-border-bg Ar colour
.It Ic pane-active-border-fg Ar colour
Set the pane border colour for the currently active pane.
.It Ic pane-border-bg Ar colour
.It Ic pane-border-fg Ar colour
Set the pane border colour for panes aside from the active pane.
.It Ic pane-active-border-style Ar style
Set the pane border style for the currently active pane.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
Attributes are ignored.
.It Ic pane-border-style Ar style
Set the pane border style for paneas aside from the active pane.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
Attributes are ignored.
.It Ic prefix Ar key
Set the key accepted as a prefix key.
.It Ic prefix2 Ar key
@ -2413,12 +2473,6 @@ option.
.Op Ic on | off
.Xc
Show or hide the status line.
.It Ic status-attr Ar attributes
Set status line attributes.
.It Ic status-bg Ar colour
Set status line background colour.
.It Ic status-fg Ar colour
Set status line foreground colour.
.It Ic status-interval Ar interval
Update the status bar every
.Ar interval
@ -2476,19 +2530,10 @@ section).
For details on how the names and titles can be set see the
.Sx "NAMES AND TITLES"
section.
For a list of allowed attributes see the
.Ic message-command-style
option.
.Pp
#[attributes] allows a comma-separated list of attributes to be specified,
these may be
.Ql fg=colour
to set the foreground colour,
.Ql bg=colour
to set the background colour, the name of one of the attributes (listed under
the
.Ic message-attr
option) to turn an attribute on, or an attribute prefixed with
.Ql no
to turn one off, for example
.Ic nobright .
Examples are:
.Bd -literal -offset indent
#(sysctl vm.loadavg)
@ -2504,17 +2549,18 @@ By default, UTF-8 in
is not interpreted, to enable UTF-8, use the
.Ic status-utf8
option.
.It Ic status-left-attr Ar attributes
Set the attribute of the left part of the status line.
.It Ic status-left-bg Ar colour
Set the background colour of the left part of the status line.
.It Ic status-left-fg Ar colour
Set the foreground colour of the left part of the status line.
.It Ic status-left-length Ar length
Set the maximum
.Ar length
of the left component of the status bar.
The default is 10.
.It Ic status-left-style Ar style
Set the style of the left part of the status line.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.It Xo Ic status-position
.Op Ic top | bottom
.Xc
@ -2533,17 +2579,25 @@ will be passed to
character pairs are replaced, and UTF-8 is dependent on the
.Ic status-utf8
option.
.It Ic status-right-attr Ar attributes
Set the attribute of the right part of the status line.
.It Ic status-right-bg Ar colour
Set the background colour of the right part of the status line.
.It Ic status-right-fg Ar colour
Set the foreground colour of the right part of the status line.
.It Ic status-right-length Ar length
Set the maximum
.Ar length
of the right component of the status bar.
The default is 40.
.It Ic status-right-style Ar style
Set the style of the right part of the status line.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.It Ic status-style Ar style
Set status line style.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.It Xo Ic status-utf8
.Op Ic on | off
.Xc
@ -2770,15 +2824,6 @@ or
.Ic main-vertical
layouts.
.Pp
.It Ic mode-attr Ar attributes
Set window modes attributes.
.Pp
.It Ic mode-bg Ar colour
Set window modes background colour.
.Pp
.It Ic mode-fg Ar colour
Set window modes foreground colour.
.Pp
.It Xo Ic mode-keys
.Op Ic vi | emacs
.Xc
@ -2804,6 +2849,14 @@ If set to
the mouse behaves as set to on, but cannot be used to enter copy
mode.
.Pp
.It Ic mode-style Ar style
Set window modes style.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.Pp
.It Xo Ic monitor-activity
.Op Ic on | off
.Xc
@ -2874,64 +2927,42 @@ Instructs
.Nm
to expect UTF-8 sequences to appear in this window.
.Pp
.It Ic window-status-bell-attr Ar attributes
Set status line attributes for windows which have a bell alert.
.It Ic window-status-activity-style Ar style
Set status line style for windows with an activity alert.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.Pp
.It Ic window-status-bell-bg Ar colour
Set status line background colour for windows with a bell alert.
.It Ic window-status-bell-style Ar style
Set status line style for windows with a bell alert.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.Pp
.It Ic window-status-bell-fg Ar colour
Set status line foreground colour for windows with a bell alert.
.Pp
.It Ic window-status-content-attr Ar attributes
Set status line attributes for windows which have a content alert.
.Pp
.It Ic window-status-content-bg Ar colour
Set status line background colour for windows with a content alert.
.Pp
.It Ic window-status-content-fg Ar colour
Set status line foreground colour for windows with a content alert.
.Pp
.It Ic window-status-activity-attr Ar attributes
Set status line attributes for windows which have an activity (or silence) alert.
.Pp
.It Ic window-status-activity-bg Ar colour
Set status line background colour for windows with an activity alert.
.Pp
.It Ic window-status-activity-fg Ar colour
Set status line foreground colour for windows with an activity alert.
.Pp
.It Ic window-status-attr Ar attributes
Set status line attributes for a single window.
.Pp
.It Ic window-status-bg Ar colour
Set status line background colour for a single window.
.Pp
.It Ic window-status-current-attr Ar attributes
Set status line attributes for the currently active window.
.Pp
.It Ic window-status-current-bg Ar colour
Set status line background colour for the currently active window.
.Pp
.It Ic window-status-current-fg Ar colour
Set status line foreground colour for the currently active window.
.It Ic window-status-content-style Ar style
Set status line style for windows with a content alert.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.Pp
.It Ic window-status-current-format Ar string
Like
.Ar window-status-format ,
but is the format used when the window is the current window.
.Pp
.It Ic window-status-last-attr Ar attributes
Set status line attributes for the last active window.
.Pp
.It Ic window-status-last-bg Ar colour
Set status line background colour for the last active window.
.Pp
.It Ic window-status-last-fg Ar colour
Set status line foreground colour for the last active window.
.Pp
.It Ic window-status-fg Ar colour
Set status line foreground colour for a single window.
.It Ic window-status-current-style Ar style
Set status line style for the currently active window.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.Pp
.It Ic window-status-format Ar string
Set the format in which the window is displayed in the status line window list.
@ -2941,10 +2972,26 @@ option for details of special character sequences available.
The default is
.Ql #I:#W#F .
.Pp
.It Ic window-status-last-style Ar style
Set status line style for the last active window.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.Pp
.It Ic window-status-separator Ar string
Sets the separator drawn between windows in the status line.
The default is a single space character.
.Pp
.It Ic window-status-style Ar style
Set status line style for a single window.
For how to specify
.Ar style ,
see the
.Ic message-command-style
option.
.Pp
.It Xo Ic xterm-keys
.Op Ic on | off
.Xc
@ -3015,6 +3062,9 @@ for example
.Ql #{session_name} .
Some variables also have an shorter alias such as
.Ql #S .
.Ql ##
is replaced by a single
.Ql # .
Conditionals are also accepted by prefixing with
.Ql \&?
and separating two alternatives with a comma;
@ -3281,16 +3331,10 @@ content) is present.
.Pp
The colour and attributes of the status line may be configured, the entire
status line using the
.Ic status-attr ,
.Ic status-fg
and
.Ic status-bg
session options and individual windows using the
.Ic window-status-attr ,
.Ic window-status-fg
and
.Ic window-status-bg
window options.
.Ic status-style
session option and individual windows using the
.Ic window-status-style
window option.
.Pp
The status line is automatically refreshed at interval if it has changed, the
interval may be controlled with the
@ -3568,9 +3612,6 @@ specified by
.Fl t
or the current pane if omitted).
If the command doesn't return success, the exit status is also displayed.
.It Ic server-info
.D1 (alias: Ic info )
Show server information and terminal details.
.It Xo Ic wait-for
.Op Fl L | S | U
.Ar channel
@ -3794,7 +3835,7 @@ bind-key C-a send-prefix
Turning the status line off, or changing its colour:
.Bd -literal -offset indent
set-option -g status off
set-option -g status-bg blue
set-option -g status-style bg=blue
.Ed
.Pp
Setting other options, such as the default command,

21
tmux.c
View File

@ -205,8 +205,9 @@ int
main(int argc, char **argv)
{
struct passwd *pw;
char *s, *path, *label, *home, **var, tmp[MAXPATHLEN];
char *s, *path, *label, **var, tmp[MAXPATHLEN];
char in[256];
const char *home;
long long pid;
int opt, flags, quiet, keys, session;
@ -331,11 +332,15 @@ main(int argc, char **argv)
pw = getpwuid(getuid());
if (pw != NULL)
home = pw->pw_dir;
else
home = NULL;
}
xasprintf(&cfg_file, "%s/.tmux.conf", home);
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
free(cfg_file);
cfg_file = NULL;
if (home != NULL) {
xasprintf(&cfg_file, "%s/.tmux.conf", home);
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
free(cfg_file);
cfg_file = NULL;
}
}
}
@ -367,7 +372,11 @@ main(int argc, char **argv)
}
}
free(label);
strlcpy(socket_path, path, sizeof socket_path);
if (strlcpy(socket_path, path, sizeof socket_path) >= sizeof socket_path) {
fprintf(stderr, "socket path too long: %s\n", path);
exit(1);
}
free(path);
#ifdef HAVE_SETPROCTITLE

42
tmux.h
View File

@ -719,11 +719,12 @@ struct options_entry {
enum {
OPTIONS_STRING,
OPTIONS_NUMBER,
OPTIONS_DATA,
OPTIONS_STYLE
} type;
char *str;
long long num;
char *str;
long long num;
struct grid_cell style;
RB_ENTRY(options_entry) entry;
};
@ -1021,6 +1022,8 @@ struct layout_cell {
u_int yoff;
struct window_pane *wp;
struct window_pane *lastwp;
struct layout_cells cells;
TAILQ_ENTRY(layout_cell) entry;
@ -1444,7 +1447,8 @@ enum options_table_type {
OPTIONS_TABLE_COLOUR,
OPTIONS_TABLE_ATTRIBUTES,
OPTIONS_TABLE_FLAG,
OPTIONS_TABLE_CHOICE
OPTIONS_TABLE_CHOICE,
OPTIONS_TABLE_STYLE
};
struct options_table_entry {
@ -1457,6 +1461,8 @@ struct options_table_entry {
const char *default_str;
long long default_num;
const char *style;
};
/* Tree of format entries. */
@ -1568,12 +1574,15 @@ void options_free(struct options *);
struct options_entry *options_find1(struct options *, const char *);
struct options_entry *options_find(struct options *, const char *);
void options_remove(struct options *, const char *);
struct options_entry *printflike3 options_set_string(
struct options *, const char *, const char *, ...);
struct options_entry *printflike3 options_set_string(struct options *,
const char *, const char *, ...);
char *options_get_string(struct options *, const char *);
struct options_entry *options_set_number(
struct options *, const char *, long long);
struct options_entry *options_set_number(struct options *, const char *,
long long);
long long options_get_number(struct options *, const char *);
struct options_entry *options_set_style(struct options *, const char *,
const char *, int);
struct grid_cell *options_get_style(struct options *, const char *);
/* options-table.c */
extern const struct options_table_entry server_options_table[];
@ -1732,6 +1741,8 @@ int cmd_find_index(struct cmd_q *, const char *,
struct winlink *cmd_find_pane(struct cmd_q *, const char *, struct session **,
struct window_pane **);
char *cmd_template_replace(const char *, const char *, int);
struct window *cmd_lookup_windowid(const char *);
struct window_pane *cmd_lookup_paneid(const char *);
extern const struct cmd_entry *cmd_table[];
extern const struct cmd_entry cmd_attach_session_entry;
extern const struct cmd_entry cmd_bind_key_entry;
@ -2031,8 +2042,6 @@ void printflike5 screen_write_nputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, int, const char *, ...);
void screen_write_vnputs(struct screen_write_ctx *,
ssize_t, struct grid_cell *, int, const char *, va_list);
void screen_write_parsestyle(
struct grid_cell *, struct grid_cell *, const char *);
void screen_write_putc(
struct screen_write_ctx *, struct grid_cell *, u_char);
void screen_write_copy(struct screen_write_ctx *,
@ -2068,7 +2077,7 @@ void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
/* screen-redraw.c */
void screen_redraw_screen(struct client *, int, int);
void screen_redraw_screen(struct client *, int, int, int);
void screen_redraw_pane(struct client *, struct window_pane *);
/* screen.c */
@ -2162,7 +2171,6 @@ struct window_pane *window_pane_find_right(struct window_pane *);
void window_set_name(struct window *, const char *);
void window_remove_ref(struct window *);
void winlink_clear_flags(struct winlink *);
void window_mode_attrs(struct grid_cell *, struct options *);
/* layout.c */
u_int layout_count_cells(struct layout_cell *);
@ -2336,4 +2344,14 @@ int xvasprintf(char **, const char *, va_list);
int printflike3 xsnprintf(char *, size_t, const char *, ...);
int xvsnprintf(char *, size_t, const char *, va_list);
/* style.c */
int style_parse(const struct grid_cell *,
struct grid_cell *, const char *);
const char *style_tostring(struct grid_cell *);
void style_update_new(struct options *, const char *, const char *);
void style_update_old(struct options *, const char *,
struct grid_cell *);
void style_apply(struct grid_cell *, struct options *, const char *);
void style_apply_update(struct grid_cell *, struct options *, const char *);
#endif /* TMUX_H */

View File

@ -30,38 +30,38 @@ struct tty_acs_entry {
const char *string;
};
const struct tty_acs_entry tty_acs_table[] = {
{ '+', "\342\206\222" },
{ ',', "\342\206\220" },
{ '-', "\342\206\221" },
{ '.', "\342\206\223" },
{ '0', "\342\226\256" },
{ '`', "\342\227\206" },
{ 'a', "\342\226\222" },
{ 'f', "\302\260" },
{ 'g', "\302\261" },
{ 'h', "\342\226\222" },
{ 'i', "\342\230\203" },
{ 'j', "\342\224\230" },
{ 'k', "\342\224\220" },
{ 'l', "\342\224\214" },
{ 'm', "\342\224\224" },
{ 'n', "\342\224\274" },
{ 'o', "\342\216\272" },
{ 'p', "\342\216\273" },
{ 'q', "\342\224\200" },
{ 'r', "\342\216\274" },
{ 's', "\342\216\275" },
{ 't', "\342\224\234" },
{ 'u', "\342\224\244" },
{ 'v', "\342\224\264" },
{ 'w', "\342\224\254" },
{ 'x', "\342\224\202" },
{ 'y', "\342\211\244" },
{ 'z', "\342\211\245" },
{ '{', "\317\200" },
{ '|', "\342\211\240" },
{ '}', "\302\243" },
{ '~', "\302\267" }
{ '+', "\342\206\222" }, /* arrow pointing right */
{ ',', "\342\206\220" }, /* arrow pointing left */
{ '-', "\342\206\221" }, /* arrow pointing up */
{ '.', "\342\206\223" }, /* arrow pointing down */
{ '0', "\342\226\256" }, /* solid square block */
{ '`', "\342\227\206" }, /* diamond */
{ 'a', "\342\226\222" }, /* checker board (stipple) */
{ 'f', "\302\260" }, /* degree symbol */
{ 'g', "\302\261" }, /* plus/minus */
{ 'h', "\342\226\222" }, /* board of squares */
{ 'i', "\342\230\203" }, /* lantern symbol */
{ 'j', "\342\224\230" }, /* lower right corner */
{ 'k', "\342\224\220" }, /* upper right corner */
{ 'l', "\342\224\214" }, /* upper left corner */
{ 'm', "\342\224\224" }, /* lower left corner */
{ 'n', "\342\224\274" }, /* large plus or crossover */
{ 'o', "\342\216\272" }, /* scan line 1 */
{ 'p', "\342\216\273" }, /* scan line 3 */
{ 'q', "\342\224\200" }, /* horizontal line */
{ 'r', "\342\216\274" }, /* scan line 7 */
{ 's', "\342\216\275" }, /* scan line 9 */
{ 't', "\342\224\234" }, /* tee pointing right */
{ 'u', "\342\224\244" }, /* tee pointing left */
{ 'v', "\342\224\264" }, /* tee pointing up */
{ 'w', "\342\224\254" }, /* tee pointing down */
{ 'x', "\342\224\202" }, /* vertical line */
{ 'y', "\342\211\244" }, /* less-than-or-equal-to */
{ 'z', "\342\211\245" }, /* greater-than-or-equal-to */
{ '{', "\317\200" }, /* greek pi */
{ '|', "\342\211\240" }, /* not-equal */
{ '}', "\302\243" }, /* UK pound sign */
{ '~', "\302\267" } /* bullet */
};
int

3
tty.c
View File

@ -1354,8 +1354,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc)
tty_putcode(tty, TTYC_BOLD);
if (changed & GRID_ATTR_DIM)
tty_putcode(tty, TTYC_DIM);
if (changed & GRID_ATTR_ITALICS)
{
if (changed & GRID_ATTR_ITALICS) {
if (tty_term_has(tty->term, TTYC_SITM))
tty_putcode(tty, TTYC_SITM);
else

View File

@ -345,8 +345,7 @@ window_choose_collapse(struct window_pane *wp, struct session *s)
* assign the actual result we want to render and copy the new one over
* the top of it.
*/
for (i = 0; i < ARRAY_LENGTH(&data->list); i++)
{
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) {
item = &ARRAY_ITEM(&data->list, i);
wcd = item->wcd;
@ -737,7 +736,7 @@ window_choose_write_line(
utf8flag = options_get_number(&wp->window->options, "utf8");
memcpy(&gc, &grid_default_cell, sizeof gc);
if (data->selected == data->top + py)
window_mode_attrs(&gc, oo);
style_apply(&gc, oo, "mode-style");
screen_write_cursormove(ctx, 0, py);
if (data->top + py < ARRAY_LENGTH(&data->list)) {
@ -764,7 +763,7 @@ window_choose_write_line(
screen_write_putc(ctx, &gc, ' ');
if (data->input_type != WINDOW_CHOOSE_NORMAL) {
window_mode_attrs(&gc, oo);
style_apply(&gc, oo, "mode-style");
xoff = xsnprintf(hdr, sizeof hdr,
"%s: %s", data->input_prompt, data->input_str);

View File

@ -750,8 +750,10 @@ window_copy_key_input(struct window_pane *wp, int key)
{
struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
size_t inputlen;
size_t inputlen, n;
int np;
struct paste_buffer *pb;
u_char ch;
switch (mode_key_lookup(&data->mdata, key, NULL)) {
case MODEKEYEDIT_CANCEL:
@ -765,6 +767,20 @@ window_copy_key_input(struct window_pane *wp, int key)
case MODEKEYEDIT_DELETELINE:
*data->inputstr = '\0';
break;
case MODEKEYEDIT_PASTE:
if ((pb = paste_get_top(&global_buffers)) == NULL)
break;
for (n = 0; n < pb->size; n++) {
ch = (u_char) pb->data[n];
if (ch < 32 || ch == 127)
break;
}
inputlen = strlen(data->inputstr);
data->inputstr = xrealloc(data->inputstr, 1, inputlen + n + 1);
memcpy(data->inputstr + inputlen, pb->data, n);
data->inputstr[inputlen + n] = '\0';
break;
case MODEKEYEDIT_ENTER:
np = data->numprefix;
if (np <= 0)
@ -853,8 +869,12 @@ window_copy_mouse(
} else if (m->wheel == MOUSE_WHEEL_DOWN) {
for (i = 0; i < 5; i++)
window_copy_cursor_down(wp, 1);
if (data->oy == 0)
goto reset_mode;
/*
* We reached the bottom, leave copy mode,
* but only if no selection is in progress.
*/
if (data->oy == 0 && !s->sel.flag)
goto reset_mode;
}
return;
}
@ -1030,7 +1050,7 @@ window_copy_search_up(struct window_pane *wp, const char *searchstr)
cis = 1;
for (ptr = searchstr; *ptr != '\0'; ptr++) {
if (*ptr != tolower(*ptr)) {
if (*ptr != tolower((u_char)*ptr)) {
cis = 0;
break;
}
@ -1097,7 +1117,7 @@ window_copy_search_down(struct window_pane *wp, const char *searchstr)
cis = 1;
for (ptr = searchstr; *ptr != '\0'; ptr++) {
if (*ptr != tolower(*ptr)) {
if (*ptr != tolower((u_char)*ptr)) {
cis = 0;
break;
}
@ -1150,10 +1170,10 @@ window_copy_write_line(
struct screen *s = &data->screen;
struct options *oo = &wp->window->options;
struct grid_cell gc;
char hdr[32];
size_t last, xoff = 0, size = 0;
char hdr[512];
size_t last, xoff = 0, size = 0, limit;
window_mode_attrs(&gc, oo);
style_apply(&gc, oo, "mode-style");
last = screen_size_y(s) - 1;
if (py == 0) {
@ -1164,11 +1184,14 @@ window_copy_write_line(
screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr);
} else if (py == last && data->inputtype != WINDOW_COPY_OFF) {
limit = sizeof hdr;
if (limit > screen_size_x(s))
limit = screen_size_x(s);
if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) {
xoff = size = xsnprintf(hdr, sizeof hdr,
xoff = size = xsnprintf(hdr, limit,
"Repeat: %u", data->numprefix);
} else {
xoff = size = xsnprintf(hdr, sizeof hdr,
xoff = size = xsnprintf(hdr, limit,
"%s: %s", data->inputprompt, data->inputstr);
}
screen_write_cursormove(ctx, 0, last);
@ -1267,7 +1290,7 @@ window_copy_update_selection(struct window_pane *wp, int may_redraw)
return (0);
/* Set colours. */
window_mode_attrs(&gc, oo);
style_apply(&gc, oo, "mode-style");
/* Find top of screen. */
ty = screen_hsize(data->backing) - data->oy;

View File

@ -58,6 +58,10 @@ struct window_pane_tree all_window_panes;
u_int next_window_pane_id;
u_int next_window_id;
struct window_pane *window_pane_active_set(struct window_pane *,
struct window_pane *);
void window_pane_active_lost(struct window_pane *, struct window_pane *);
void window_pane_timer_callback(int, short, void *);
void window_pane_read_callback(struct bufferevent *, void *);
void window_pane_error_callback(struct bufferevent *, short, void *);
@ -383,6 +387,59 @@ window_resize(struct window *w, u_int sx, u_int sy)
w->sy = sy;
}
/*
* Restore previously active pane when changing from wp to nextwp. The intended
* pane is in nextwp and it returns the previously focused pane.
*/
struct window_pane *
window_pane_active_set(struct window_pane *wp, struct window_pane *nextwp)
{
struct layout_cell *lc;
struct window_pane *lastwp;
/* Target pane's parent must not be an ancestor of source pane. */
for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) {
if (lc == nextwp->layout_cell->parent)
return (nextwp);
}
/*
* Previously active pane, if any, must not be the same as the source
* pane.
*/
if (nextwp->layout_cell->parent != NULL) {
lastwp = nextwp->layout_cell->parent->lastwp;
if (lastwp != wp && window_pane_visible(lastwp))
return (lastwp);
}
return (nextwp);
}
/* Remember previously active pane when changing from wp to nextwp. */
void
window_pane_active_lost(struct window_pane *wp, struct window_pane *nextwp)
{
struct layout_cell *lc, *lc2;
/* Save the target pane in its parent. */
nextwp->layout_cell->parent->lastwp = nextwp;
/*
* Save the source pane in all of its parents up to, but not including,
* the common ancestor of itself and the target panes.
*/
if (wp == NULL)
return;
for (lc = wp->layout_cell->parent; lc != NULL; lc = lc->parent) {
lc2 = nextwp->layout_cell->parent;
for (; lc2 != NULL; lc2 = lc2->parent) {
if (lc == lc2)
return;
}
lc->lastwp = wp;
}
}
void
window_set_active_pane(struct window *w, struct window_pane *wp)
{
@ -390,6 +447,7 @@ window_set_active_pane(struct window *w, struct window_pane *wp)
return;
w->last = w->active;
w->active = wp;
window_pane_active_lost(w->last, wp);
while (!window_pane_visible(w->active)) {
w->active = TAILQ_PREV(w->active, window_panes, entry);
if (w->active == NULL)
@ -704,6 +762,16 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
void
window_pane_destroy(struct window_pane *wp)
{
struct window_pane *wp2;
/* Forget removed pane in all layout cells that remember it. */
RB_FOREACH(wp2, window_pane_tree, &all_window_panes) {
if (wp2->layout_cell != NULL &&
wp2->layout_cell->parent != NULL &&
wp2->layout_cell->parent->lastwp == wp)
wp2->layout_cell->parent->lastwp = NULL;
}
window_pane_reset_mode(wp);
if (event_initialized(&wp->changes_timer))
@ -1131,7 +1199,7 @@ window_pane_find_up(struct window_pane *wp)
if (wp2->yoff + wp2->sy + 1 != top)
continue;
if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)
return (wp2);
return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@ -1157,7 +1225,7 @@ window_pane_find_down(struct window_pane *wp)
if (wp2->yoff != bottom)
continue;
if (left >= wp2->xoff && left <= wp2->xoff + wp2->sx)
return (wp2);
return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@ -1186,7 +1254,7 @@ window_pane_find_left(struct window_pane *wp)
if (wp2->xoff + wp2->sx + 1 != left)
continue;
if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)
return (wp2);
return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@ -1215,7 +1283,7 @@ window_pane_find_right(struct window_pane *wp)
if (wp2->xoff != right)
continue;
if (top >= wp2->yoff && top <= wp2->yoff + wp2->sy)
return (wp2);
return (window_pane_active_set(wp, wp2));
}
return (NULL);
}
@ -1248,13 +1316,3 @@ winlink_clear_flags(struct winlink *wl)
}
}
}
/* Set the grid_cell with fg/bg/attr information when window is in a mode. */
void
window_mode_attrs(struct grid_cell *gc, struct options *oo)
{
memcpy(gc, &grid_default_cell, sizeof *gc);
colour_set_fg(gc, options_get_number(oo, "mode-fg"));
colour_set_bg(gc, options_get_number(oo, "mode-bg"));
gc->attr |= options_get_number(oo, "mode-attr");
}

View File

@ -133,7 +133,7 @@ xterm_keys_match(const char *template, const char *buf, size_t len)
do {
if (*template != '_' && buf[pos] != *template)
return (-1);
} while (pos++ != len && *++template != '\0');
} while (*++template != '\0' && ++pos != len);
if (*template != '\0') /* partial */
return (1);