Merge branch 'obsd-master'

Conflicts:
	Makefile
	tmux.1
	window.c
pull/1/head
Thomas Adam 2014-04-23 11:26:11 +01:00
commit 953c3ef47a
49 changed files with 431 additions and 489 deletions

View File

@ -73,7 +73,6 @@ dist_tmux_SOURCES = \
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 \

View File

@ -125,7 +125,7 @@ args_free(struct args *args)
size_t
args_print(struct args *args, char *buf, size_t len)
{
size_t off;
size_t off, used;
int i;
const char *quotes;
struct args_entry *entry;
@ -165,9 +165,12 @@ args_print(struct args *args, char *buf, size_t len)
quotes = "\"";
else
quotes = "";
off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
used = xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
off != 0 ? " " : "", entry->flag, quotes, entry->value,
quotes);
if (used > len - off)
used = len - off;
off += used;
}
/* And finally the argument vector. */
@ -181,8 +184,11 @@ args_print(struct args *args, char *buf, size_t len)
quotes = "\"";
else
quotes = "";
off += xsnprintf(buf + off, len - off, "%s%s%s%s",
used = xsnprintf(buf + off, len - off, "%s%s%s%s",
off != 0 ? " " : "", quotes, args->argv[i], quotes);
if (used > len - off)
used = len - off;
off += used;
}
return (off);

1
cfg.c
View File

@ -17,7 +17,6 @@
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>

View File

@ -25,8 +25,6 @@
#include <errno.h>
#include <event.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

View File

@ -65,16 +65,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
server_unzoom_window(w);
TAILQ_REMOVE(&w->panes, wp, entry);
if (wp == w->active) {
w->active = w->last;
w->last = NULL;
if (w->active == NULL) {
w->active = TAILQ_PREV(wp, window_panes, entry);
if (w->active == NULL)
w->active = TAILQ_NEXT(wp, entry);
}
} else if (wp == w->last)
w->last = NULL;
window_lost_pane(w, wp);
layout_close_pane(wp);
w = wp->window = window_create1(s->sx, s->sy);

View File

@ -1,97 +0,0 @@
/* $Id$ */
/*
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
*
* 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 <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
#define CMD_CHOOSE_LIST_DEFAULT_TEMPLATE "run-shell '%%'"
/*
* Enter choose mode to choose a custom list.
*/
enum cmd_retval cmd_choose_list_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_choose_list_entry = {
"choose-list", NULL,
"l:t:", 0, 1,
"[-l items] " CMD_TARGET_WINDOW_USAGE "[template]",
0,
NULL,
cmd_choose_list_exec
};
enum cmd_retval
cmd_choose_list_exec(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
struct client *c;
struct winlink *wl;
const char *list1;
char *template, *item, *copy, *list;
u_int idx;
if ((c = cmd_current_client(cmdq)) == NULL) {
cmdq_error(cmdq, "no client available");
return (CMD_RETURN_ERROR);
}
if ((list1 = args_get(args, 'l')) == NULL)
return (CMD_RETURN_ERROR);
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
return (CMD_RETURN_ERROR);
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
return (CMD_RETURN_NORMAL);
if (args->argc != 0)
template = xstrdup(args->argv[0]);
else
template = xstrdup(CMD_CHOOSE_LIST_DEFAULT_TEMPLATE);
copy = list = xstrdup(list1);
idx = 0;
while ((item = strsep(&list, ",")) != NULL)
{
if (*item == '\0') /* no empty entries */
continue;
window_choose_add_item(wl->window->active, c, wl, item,
template, idx);
idx++;
}
free(copy);
if (idx == 0) {
free(template);
window_pane_reset_mode(wl->window->active);
return (CMD_RETURN_ERROR);
}
window_choose_ready(wl->window->active, 0, NULL);
free(template);
return (CMD_RETURN_NORMAL);
}

View File

@ -84,7 +84,8 @@ cmd_find_window_match_flags(struct args *args)
void
cmd_find_window_match(struct cmd_find_window_data_list *find_list,
int match_flags, struct winlink *wl, const char *str, const char *searchstr)
int match_flags, struct winlink *wl, const char *str,
const char *searchstr)
{
struct cmd_find_window_data find_data;
struct window_pane *wp;

View File

@ -138,11 +138,7 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
layout_close_pane(src_wp);
if (src_w->active == src_wp) {
src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
if (src_w->active == NULL)
src_w->active = TAILQ_NEXT(src_wp, entry);
}
window_lost_pane(src_w, src_wp);
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
if (window_count_panes(src_w) == 0)

View File

@ -103,7 +103,7 @@ size_t
cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
{
struct cmd *cmd;
size_t off;
size_t off, used;
off = 0;
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
@ -112,8 +112,12 @@ cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
off += cmd_print(cmd, buf + off, len - off);
if (off >= len)
break;
if (TAILQ_NEXT(cmd, qentry) != NULL)
off += xsnprintf(buf + off, len - off, " ; ");
if (TAILQ_NEXT(cmd, qentry) != NULL) {
used = xsnprintf(buf + off, len - off, " ; ");
if (used > len - off)
used = len - off;
off += used;
}
}
return (off);
}

View File

@ -18,10 +18,6 @@
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
/*

View File

@ -20,7 +20,6 @@
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
@ -55,10 +54,12 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
struct environ env;
struct termios tio, *tiop;
const char *newname, *target, *update, *errstr, *template;
const char *path;
char *cmd, *cause, *cp;
int detached, already_attached, idx, cwd, fd = -1;
u_int sx, sy;
struct format_tree *ft;
struct environ_entry *envent;
if (args_has(args, 't') && (args->argc != 0 || args_has(args, 'n'))) {
cmdq_error(cmdq, "command or window name given with target");
@ -189,6 +190,14 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
else
cmd = options_get_string(&global_s_options, "default-command");
path = NULL;
if (c != NULL && c->session == NULL)
envent = environ_find(&c->environ, "PATH");
else
envent = environ_find(&global_environ, "PATH");
if (envent != NULL)
path = envent->value;
/* Construct the environment. */
environ_init(&env);
update = options_get_string(&global_s_options, "update-environment");
@ -197,7 +206,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
/* Create the new session. */
idx = -1 - options_get_number(&global_s_options, "base-index");
s = session_create(newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause);
s = session_create(newname, cmd, path, cwd, &env, tiop, idx, sx, sy,
&cause);
if (s == NULL) {
cmdq_error(cmdq, "create session failed: %s", cause);
free(cause);

View File

@ -49,10 +49,11 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct session *s;
struct winlink *wl;
struct client *c;
const char *cmd, *template;
const char *cmd, *path, *template;
char *cause, *cp;
int idx, last, detached, cwd, fd = -1;
struct format_tree *ft;
struct environ_entry *envent;
if (args_has(args, 'a')) {
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
@ -77,7 +78,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
server_unlink_window(s, wl);
}
} else {
if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &s)) == -2)
idx = cmd_find_index(cmdq, args_get(args, 't'), &s);
if (idx == -2)
return (CMD_RETURN_ERROR);
}
detached = args_has(args, 'd');
@ -87,6 +89,14 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
else
cmd = args->argv[0];
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (args_has(args, 'c')) {
ft = format_create();
if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
@ -135,7 +145,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
if (idx == -1)
idx = -1 - options_get_number(&s->options, "base-index");
wl = session_new(s, args_get(args, 'n'), cmd, cwd, idx, &cause);
wl = session_new(s, args_get(args, 'n'), cmd, path, cwd, idx, &cause);
if (wl == NULL) {
cmdq_error(cmdq, "create window failed: %s", cause);
free(cause);

View File

@ -86,37 +86,6 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
va_end(ap);
}
/* Show info from command. */
void printflike2
cmdq_info(struct cmd_q *cmdq, const char *fmt, ...)
{
struct client *c = cmdq->client;
va_list ap;
char *msg;
if (options_get_number(&global_options, "quiet"))
return;
va_start(ap, fmt);
if (c == NULL)
/* nothing */;
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
evbuffer_add(c->stdout_data, "\n", 1);
server_push_stdout(c);
} else {
xvasprintf(&msg, fmt, ap);
*msg = toupper((u_char) *msg);
status_message_set(c, "%s", msg);
free(msg);
}
va_end(ap);
}
/* Show error from command. */
void printflike2
cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)

View File

@ -48,9 +48,10 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
struct window_pane *wp;
struct session *s;
struct environ env;
const char *cmd;
const char *cmd, *path;
char *cause;
u_int idx;
struct environ_entry *envent;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
@ -77,7 +78,17 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
cmd = args->argv[0];
else
cmd = NULL;
if (window_pane_spawn(wp, cmd, NULL, -1, &env, s->tio, &cause) != 0) {
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(wp, cmd, path, NULL, -1, &env, s->tio,
&cause) != 0) {
cmdq_error(cmdq, "respawn pane failed: %s", cause);
free(cause);
environ_free(&env);

View File

@ -47,8 +47,9 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window_pane *wp;
struct session *s;
struct environ env;
const char *cmd;
const char *cmd, *path;
char *cause;
struct environ_entry *envent;
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
return (CMD_RETURN_ERROR);
@ -79,7 +80,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
cmd = args->argv[0];
else
cmd = NULL;
if (window_pane_spawn(wp, cmd, NULL, -1, &env, s->tio, &cause) != 0) {
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(wp, cmd, path, NULL, -1, &env, s->tio,
&cause) != 0) {
cmdq_error(cmdq, "respawn window failed: %s", cause);
free(cause);
environ_free(&env);

View File

@ -161,13 +161,9 @@ cmd_run_shell_callback(struct job *job)
retcode = WTERMSIG(job->status);
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL) {
if (lines == 0)
cmdq_info(cmdq, "%s", msg);
else
cmd_run_shell_print(job, msg);
free(msg);
}
if (msg != NULL)
cmd_run_shell_print(job, msg);
free(msg);
}
void

View File

@ -111,7 +111,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
if (fd != -1)
f = fdopen(fd, "ab");
} else {
fd = openat(cwd, path, O_CREAT|O_RDWR, 0600);
fd = openat(cwd, path, O_CREAT|O_RDWR|O_TRUNC, 0600);
if (fd != -1)
f = fdopen(fd, "wb");
}
@ -141,7 +141,6 @@ do_print:
return (CMD_RETURN_ERROR);
}
msg = NULL;
msglen = 0;
used = 0;
while (used != pb->size) {

View File

@ -104,7 +104,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
else
layout = layout_set_previous(wl->window);
server_redraw_window(wl->window);
cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout));
return (CMD_RETURN_NORMAL);
}
@ -115,7 +114,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
if (layout != -1) {
layout = layout_set_select(wl->window, layout);
server_redraw_window(wl->window);
cmdq_info(cmdq, "arranging in: %s", layout_set_name(layout));
return (CMD_RETURN_NORMAL);
}
@ -126,7 +124,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
server_redraw_window(wl->window);
cmdq_info(cmdq, "arranging in: %s", layoutname);
}
return (CMD_RETURN_NORMAL);
}

View File

@ -117,8 +117,11 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
}
if (oe == NULL) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
/* Work out the tree from the table. */
@ -163,8 +166,10 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
} else {
if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
if (!args_has(args, 'q'))
cmdq_print(cmdq, "already set: %s", optstr);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "already set: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
if (cmd_set_option_set(self, cmdq, oe, oo, valstr) != 0)
@ -229,8 +234,11 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
if (args_has(args, 'u')) {
if (options_find1(oo, optstr) == NULL) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "unknown option: %s", optstr);
return (CMD_RETURN_ERROR);
}
return (CMD_RETURN_NORMAL);
}
if (valstr != NULL) {
cmdq_error(cmdq, "value passed to unset option: %s",
@ -244,15 +252,13 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
return (CMD_RETURN_ERROR);
}
if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
if (!args_has(args, 'q'))
cmdq_print(cmdq, "already set: %s", optstr);
if (!args_has(args, 'q')) {
cmdq_error(cmdq, "already set: %s", optstr);
return CMD_RETURN_ERROR;
}
return (CMD_RETURN_NORMAL);
}
options_set_string(oo, optstr, "%s", valstr);
if (!args_has(args, 'q')) {
cmdq_info(cmdq, "set option: %s -> %s", optstr,
valstr);
}
}
return (CMD_RETURN_NORMAL);
}
@ -261,7 +267,8 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
/* Unset an option. */
int
cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
struct args *args = self->args;
@ -275,19 +282,16 @@ cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
}
options_remove(oo, oe->name);
if (!args_has(args, 'q'))
cmdq_info(cmdq, "unset option: %s", oe->name);
return (0);
}
/* Set an option. */
int
cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
struct args *args = self->args;
struct options_entry *o;
const char *s;
if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
cmdq_error(cmdq, "empty value");
@ -327,17 +331,14 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
}
if (o == NULL)
return (-1);
s = options_table_print_entry(oe, o, 0);
if (!args_has(args, 'q'))
cmdq_info(cmdq, "set option: %s -> %s", oe->name, s);
return (0);
}
/* Set a string option. */
struct options_entry *
cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
struct args *args = self->args;
struct options_entry *o;
@ -358,7 +359,8 @@ cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
/* Set a number option. */
struct options_entry *
cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
long long ll;
const char *errstr;
@ -375,7 +377,8 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a key option. */
struct options_entry *
cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int key;
@ -390,7 +393,8 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a colour option. */
struct options_entry *
cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int colour;
@ -405,7 +409,8 @@ cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
/* Set an attributes option. */
struct options_entry *
cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int attr;
@ -420,7 +425,8 @@ cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
/* Set a flag option. */
struct options_entry *
cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
const struct options_table_entry *oe, struct options *oo, const char *value)
const struct options_table_entry *oe, struct options *oo,
const char *value)
{
int flag;

View File

@ -100,15 +100,17 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
struct options *oo, int quiet)
{
struct args *args = self->args;
const char *name = args->argv[0];
const struct options_table_entry *table, *oe;
struct options_entry *o;
const char *optval;
if (*args->argv[0] == '@') {
if ((o = options_find1(oo, args->argv[0])) == NULL) {
retry:
if (*name == '@') {
if ((o = options_find1(oo, name)) == NULL) {
if (quiet)
return (CMD_RETURN_NORMAL);
cmdq_error(cmdq, "unknown option: %s", args->argv[0]);
cmdq_error(cmdq, "unknown option: %s", name);
return (CMD_RETURN_ERROR);
}
if (args_has(self->args, 'v'))
@ -119,16 +121,20 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
}
table = oe = NULL;
if (options_table_find(args->argv[0], &table, &oe) != 0) {
cmdq_error(cmdq, "ambiguous option: %s", args->argv[0]);
if (options_table_find(name, &table, &oe) != 0) {
cmdq_error(cmdq, "ambiguous option: %s", name);
return (CMD_RETURN_ERROR);
}
if (oe == NULL) {
if (quiet)
return (CMD_RETURN_NORMAL);
cmdq_error(cmdq, "unknown option: %s", args->argv[0]);
cmdq_error(cmdq, "unknown option: %s", name);
return (CMD_RETURN_ERROR);
}
if (oe->style != NULL) {
name = oe->style;
goto retry;
}
if ((o = options_find1(oo, oe->name)) == NULL)
return (CMD_RETURN_NORMAL);
optval = options_table_print_entry(oe, o, args_has(self->args, 'v'));
@ -157,6 +163,8 @@ cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq,
}
for (oe = table; oe->name != NULL; oe++) {
if (oe->style != NULL)
continue;
if ((o = options_find1(oo, oe->name)) == NULL)
continue;
optval = options_table_print_entry(oe, o,

View File

@ -60,7 +60,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct window *w;
struct window_pane *wp, *new_wp = NULL;
struct environ env;
const char *cmd, *shell, *template;
const char *cmd, *path, *shell, *template;
char *cause, *new_cause, *cp;
u_int hlimit;
int size, percentage, cwd, fd = -1;
@ -68,6 +68,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
struct layout_cell *lc;
struct client *c;
struct format_tree *ft;
struct environ_entry *envent;
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
@ -147,8 +148,17 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
goto error;
}
new_wp = window_add_pane(w, hlimit);
path = NULL;
if (cmdq->client != NULL && cmdq->client->session == NULL)
envent = environ_find(&cmdq->client->environ, "PATH");
else
envent = environ_find(&s->environ, "PATH");
if (envent != NULL)
path = envent->value;
if (window_pane_spawn(
new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
new_wp, cmd, path, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
layout_assign_pane(lc, new_wp);

View File

@ -71,13 +71,10 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
return (CMD_RETURN_ERROR);
if (args_has(args, 'r')) {
if (c->flags & CLIENT_READONLY) {
if (c->flags & CLIENT_READONLY)
c->flags &= ~CLIENT_READONLY;
cmdq_info(cmdq, "made client writable");
} else {
else
c->flags |= CLIENT_READONLY;
cmdq_info(cmdq, "made client read-only");
}
}
tflag = args_get(args, 't');

1
cmd.c
View File

@ -34,7 +34,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_capture_pane_entry,
&cmd_choose_buffer_entry,
&cmd_choose_client_entry,
&cmd_choose_list_entry,
&cmd_choose_session_entry,
&cmd_choose_tree_entry,
&cmd_choose_window_entry,

View File

@ -137,7 +137,8 @@ environ_unset(struct environ *env, const char *name)
* environment.
*/
void
environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv)
environ_update(const char *vars, struct environ *srcenv,
struct environ *dstenv)
{
struct environ_entry *envent;
char *copyvars, *var, *next;

View File

@ -194,10 +194,10 @@ int
format_replace(struct format_tree *ft, const char *key, size_t keylen,
char **buf, size_t *len, size_t *off)
{
char *copy, *copy0, *endptr, *ptr, *saved;
char *copy, *copy0, *endptr, *ptr, *saved, *trimmed;
const char *value;
size_t valuelen;
u_long limit = ULONG_MAX;
u_long limit = 0;
/* Make a copy of the key. */
copy0 = copy = xmalloc(keylen + 1);
@ -256,11 +256,14 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
value = "";
saved = NULL;
}
valuelen = strlen(value);
/* Truncate the value if needed. */
if (valuelen > limit)
valuelen = limit;
if (limit != 0) {
value = trimmed = utf8_trimcstr(value, limit);
free(saved);
saved = trimmed;
}
valuelen = strlen(value);
/* Expand the buffer and copy in the value. */
while (*len - *off < valuelen + 1) {
@ -487,8 +490,6 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl)
format_add(ft, "window_bell_flag", "%u",
!!(wl->flags & WINLINK_BELL));
format_add(ft, "window_content_flag", "%u",
!!(wl->flags & WINLINK_CONTENT));
format_add(ft, "window_activity_flag", "%u",
!!(wl->flags & WINLINK_ACTIVITY));
format_add(ft, "window_silence_flag", "%u",

View File

@ -131,7 +131,8 @@ grid_view_insert_lines(struct grid *gd, u_int py, u_int ny)
/* Insert lines in region. */
void
grid_view_insert_lines_region(struct grid *gd, u_int rlower, u_int py, u_int ny)
grid_view_insert_lines_region(struct grid *gd, u_int rlower, u_int py,
u_int ny)
{
u_int ny2;
@ -160,7 +161,8 @@ grid_view_delete_lines(struct grid *gd, u_int py, u_int ny)
/* Delete lines inside scroll region. */
void
grid_view_delete_lines_region(struct grid *gd, u_int rlower, u_int py, u_int ny)
grid_view_delete_lines_region(struct grid *gd, u_int rlower, u_int py,
u_int ny)
{
u_int ny2;

2
grid.c
View File

@ -624,7 +624,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
off += size;
}
if (trim) {
if (trim) {
while (off > 0 && buf[off - 1] == ' ')
off--;
}

55
input.c
View File

@ -55,6 +55,7 @@ void input_set_state(struct window_pane *, const struct input_transition *);
/* Transition entry/exit handlers. */
void input_clear(struct input_ctx *);
void input_ground(struct input_ctx *);
void input_enter_osc(struct input_ctx *);
void input_exit_osc(struct input_ctx *);
void input_enter_apc(struct input_ctx *);
@ -242,7 +243,7 @@ const struct input_transition input_state_utf8_one_table[];
/* ground state definition. */
const struct input_state input_state_ground = {
"ground",
NULL, NULL,
input_ground, NULL,
input_state_ground_table
};
@ -701,6 +702,12 @@ input_init(struct window_pane *wp)
*ictx->param_buf = '\0';
ictx->param_len = 0;
ictx->input_space = INPUT_BUF_START;
ictx->input_buf = xmalloc(INPUT_BUF_START);
*ictx->input_buf = '\0';
ictx->input_len = 0;
ictx->state = &input_state_ground;
ictx->flags = 0;
@ -711,8 +718,11 @@ input_init(struct window_pane *wp)
void
input_free(struct window_pane *wp)
{
if (wp != NULL)
evbuffer_free(wp->ictx.since_ground);
if (wp == NULL)
return;
free(wp->ictx.input_buf);
evbuffer_free(wp->ictx.since_ground);
}
/* Change input state. */
@ -720,14 +730,9 @@ void
input_set_state(struct window_pane *wp, const struct input_transition *itr)
{
struct input_ctx *ictx = &wp->ictx;
struct evbuffer *ground_evb = ictx->since_ground;
if (ictx->state->exit != NULL)
ictx->state->exit(ictx);
if (itr->state == &input_state_ground)
evbuffer_drain(ground_evb, EVBUFFER_LENGTH(ground_evb));
ictx->state = itr->state;
if (ictx->state->enter != NULL)
ictx->state->enter(ictx);
@ -882,6 +887,18 @@ input_clear(struct input_ctx *ictx)
ictx->flags &= ~INPUT_DISCARD;
}
/* Reset for ground state. */
void
input_ground(struct input_ctx *ictx)
{
evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));
if (ictx->input_space > INPUT_BUF_START) {
ictx->input_space = INPUT_BUF_START;
ictx->input_buf = xrealloc(ictx->input_buf, 1, INPUT_BUF_START);
}
}
/* Output this character to the screen. */
int
input_print(struct input_ctx *ictx)
@ -924,12 +941,20 @@ input_parameter(struct input_ctx *ictx)
int
input_input(struct input_ctx *ictx)
{
if (ictx->input_len == (sizeof ictx->input_buf) - 1)
ictx->flags |= INPUT_DISCARD;
else {
ictx->input_buf[ictx->input_len++] = ictx->ch;
ictx->input_buf[ictx->input_len] = '\0';
size_t available;
available = ictx->input_space;
while (ictx->input_len + 1 >= available) {
available *= 2;
if (available > INPUT_BUF_LIMIT) {
ictx->flags |= INPUT_DISCARD;
return (0);
}
ictx->input_buf = xrealloc(ictx->input_buf, 1, available);
ictx->input_space = available;
}
ictx->input_buf[ictx->input_len++] = ictx->ch;
ictx->input_buf[ictx->input_len] = '\0';
return (0);
}
@ -1666,8 +1691,8 @@ input_enter_osc(struct input_ctx *ictx)
void
input_exit_osc(struct input_ctx *ictx)
{
u_char *p = ictx->input_buf;
int option;
u_char *p = ictx->input_buf;
int option;
if (ictx->flags & INPUT_DISCARD)
return;

2
job.c
View File

@ -59,6 +59,8 @@ job_run(const char *cmd, struct session *s,
switch (pid = fork()) {
case -1:
environ_free(&env);
close(out[0]);
close(out[1]);
return (NULL);
case 0: /* child */
clear_signals(1);

View File

@ -212,7 +212,7 @@ key_bindings_dispatch(struct key_binding *bd, struct client *c)
readonly = 0;
}
if (!readonly && (c->flags & CLIENT_READONLY)) {
cmdq_info(c->cmdq, "client is read-only");
cmdq_error(c->cmdq, "client is read-only");
return;
}

View File

@ -23,8 +23,8 @@
#include "tmux.h"
/*
* Set window layouts - predefined methods to arrange windows. These are one-off
* and generate a layout tree.
* Set window layouts - predefined methods to arrange windows. These are
* one-off and generate a layout tree.
*/
void layout_set_even_h(struct window *);

View File

@ -27,8 +27,8 @@
* options. These tables are the master copy of the options with their real
* (user-visible) types, range limits and default values. At start these are
* copied into the runtime global options trees (which only has number and
* string types). These tables are then used to loop up the real type when
* the user sets an option or its value needs to be shown.
* string types). These tables are then used to look up the real type when the
* user sets an option or its value needs to be shown.
*/
/* Choice option type lists. */
@ -89,7 +89,7 @@ const struct options_table_entry server_options_table[] = {
{ .name = "quiet",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0 /* overridden in main() */
.default_num = 0
},
{ .name = "set-clipboard",
@ -490,11 +490,6 @@ const struct options_table_entry session_options_table[] = {
.default_num = 0
},
{ .name = "visual-content",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
},
{ .name = "visual-silence",
.type = OPTIONS_TABLE_FLAG,
.default_num = 0
@ -532,7 +527,8 @@ const struct options_table_entry window_options_table[] = {
{ .name = "automatic-rename-format",
.type = OPTIONS_TABLE_STRING,
.default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}#{?pane_dead,[dead],}"
.default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}"
"#{?pane_dead,[dead],}"
},
{ .name = "c0-change-trigger",
@ -628,11 +624,6 @@ const struct options_table_entry window_options_table[] = {
.default_num = 0
},
{ .name = "monitor-content",
.type = OPTIONS_TABLE_STRING,
.default_str = ""
},
{ .name = "monitor-silence",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
@ -734,29 +725,6 @@ const struct options_table_entry window_options_table[] = {
.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,

View File

@ -99,7 +99,7 @@ osdep_get_name(int fd, char *tty)
retry:
if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
return (NULL);
goto error;
len = (len * 5) / 4;
if ((newbuf = realloc(buf, len)) == NULL)

View File

@ -65,7 +65,8 @@ screen_write_reset(struct screen_write_ctx *ctx)
/* Write character. */
void
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch)
screen_write_putc(struct screen_write_ctx *ctx, struct grid_cell *gc,
u_char ch)
{
grid_cell_one(gc, ch);
screen_write_cell(ctx, gc);

View File

@ -118,6 +118,11 @@ server_client_open(struct client *c, char **cause)
if (c->flags & CLIENT_CONTROL)
return (0);
if (strcmp(c->ttyname, "/dev/tty") == 0) {
*cause = xstrdup("can't use /dev/tty");
return (-1);
}
if (!(c->flags & CLIENT_TERMINAL)) {
*cause = xstrdup("not a terminal");
return (-1);

View File

@ -291,7 +291,8 @@ server_kill_window(struct window *w)
int
server_link_window(struct session *src, struct winlink *srcwl,
struct session *dst, int dstidx, int killflag, int selectflag, char **cause)
struct session *dst, int dstidx, int killflag, int selectflag,
char **cause)
{
struct winlink *dstwl;
struct session_group *srcsg, *dstsg;

View File

@ -27,19 +27,16 @@
int server_window_check_bell(struct session *, struct winlink *);
int server_window_check_activity(struct session *, struct winlink *);
int server_window_check_silence(struct session *, struct winlink *);
int server_window_check_content(
struct session *, struct winlink *, struct window_pane *);
void ring_bell(struct session *);
/* Window functions that need to happen every loop. */
void
server_window_loop(void)
{
struct window *w;
struct winlink *wl;
struct window_pane *wp;
struct session *s;
u_int i;
struct window *w;
struct winlink *wl;
struct session *s;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
w = ARRAY_ITEM(&windows, i);
@ -55,8 +52,6 @@ server_window_loop(void)
server_window_check_activity(s, wl) ||
server_window_check_silence(s, wl))
server_status_session(s);
TAILQ_FOREACH(wp, &w->panes, entry)
server_window_check_content(s, wl, wp);
}
}
}
@ -187,48 +182,6 @@ server_window_check_silence(struct session *s, struct winlink *wl)
return (1);
}
/* Check for content change in window. */
int
server_window_check_content(
struct session *s, struct winlink *wl, struct window_pane *wp)
{
struct client *c;
struct window *w = wl->window;
u_int i;
char *found, *ptr;
/* Activity flag must be set for new content. */
if (s->curw->window == w)
w->flags &= ~WINDOW_ACTIVITY;
if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_CONTENT)
return (0);
if (s->curw == wl && !(s->flags & SESSION_UNATTACHED))
return (0);
ptr = options_get_string(&w->options, "monitor-content");
if (ptr == NULL || *ptr == '\0')
return (0);
if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
return (0);
free(found);
if (options_get_number(&s->options, "bell-on-alert"))
ring_bell(s);
wl->flags |= WINLINK_CONTENT;
if (options_get_number(&s->options, "visual-content")) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
status_message_set(c, "Content in window %u", wl->idx);
}
}
return (1);
}
/* Ring terminal bell. */
void
ring_bell(struct session *s)

View File

@ -217,7 +217,7 @@ server_loop(void)
}
}
/* Check if the server should be shutting down (no more clients or sessions). */
/* Check if the server should exit (no more clients or sessions). */
int
server_should_shutdown(void)
{

View File

@ -84,8 +84,9 @@ session_find_by_id(u_int id)
/* Create a new session. */
struct session *
session_create(const char *name, const char *cmd, int cwd, struct environ *env,
struct termios *tio, int idx, u_int sx, u_int sy, char **cause)
session_create(const char *name, const char *cmd, const char *path, int cwd,
struct environ *env, struct termios *tio, int idx, u_int sx, u_int sy,
char **cause)
{
struct session *s;
@ -131,7 +132,7 @@ session_create(const char *name, const char *cmd, int cwd, struct environ *env,
RB_INSERT(sessions, &sessions, s);
if (cmd != NULL) {
if (session_new(s, NULL, cmd, cwd, idx, cause) == NULL) {
if (session_new(s, NULL, cmd, path, cwd, idx, cause) == NULL) {
session_destroy(s);
return (NULL);
}
@ -225,8 +226,8 @@ session_previous_session(struct session *s)
/* Create a new window on a session. */
struct winlink *
session_new(struct session *s, const char *name, const char *cmd, int cwd,
int idx, char **cause)
session_new(struct session *s, const char *name, const char *cmd,
const char *path, int cwd, int idx, char **cause)
{
struct window *w;
struct winlink *wl;
@ -249,8 +250,8 @@ session_new(struct session *s, const char *name, const char *cmd, int cwd,
shell = _PATH_BSHELL;
hlimit = options_get_number(&s->options, "history-limit");
w = window_create(name, cmd, shell, cwd, &env, s->tio, s->sx, s->sy,
hlimit, cause);
w = window_create(name, cmd, path, shell, cwd, &env, s->tio, s->sx,
s->sy, hlimit, cause);
if (w == NULL) {
winlink_remove(&s->windows, wl);
environ_free(&env);

View File

@ -638,8 +638,6 @@ status_print(
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");

77
tmux.1
View File

@ -168,10 +168,6 @@ server process to recreate it.
Behave as a login shell.
This flag currently has no effect and is for compatibility with other shells
when using tmux as a login shell.
.It Fl q
Set the
.Ic quiet
server option to prevent the server sending various informational messages.
.It Fl S Ar socket-path
Specify a full alternative path to the server socket.
If
@ -1159,32 +1155,6 @@ flag, see the
section.
This command works only if at least one client is attached.
.It Xo
.Ic choose-list
.Op Fl l Ar items
.Op Fl t Ar target-window
.Op Ar template
.Xc
Put a window into list choice mode, allowing
.Ar items
to be selected.
.Ar items
can be a comma-separated list to display more than one item.
If an item has spaces, that entry must be quoted.
After an item is chosen,
.Ql %%
is replaced by the chosen item in the
.Ar template
and the result is executed as a command.
If
.Ar template
is not given, "run-shell '%%'" is used.
.Ar items
also accepts format specifiers.
For the meaning of this see the
.Sx FORMATS
section.
This command works only if at least one client is attached.
.It Xo
.Ic choose-session
.Op Fl F Ar format
.Op Fl t Ar target-window
@ -2077,9 +2047,7 @@ flag prevents setting an option that is already set.
.Pp
The
.Fl q
flag suppresses the informational message (as if the
.Ic quiet
server option was set).
flag suppresses errors about unknown options.
.Pp
With
.Fl a ,
@ -2142,12 +2110,6 @@ option.
Set the number of error or information messages to save in the message log for
each client.
The default is 100.
.It Xo Ic quiet
.Op Ic on | off
.Xc
Enable or disable the display of various informational messages (see also the
.Fl q
command line flag).
.It Xo Ic set-clipboard
.Op Ic on | off
.Xc
@ -2577,10 +2539,6 @@ Examples are:
#[fg=yellow,bold]#(apm -l)%%#[default] [#S]
.Ed
.Pp
Where appropriate, special character sequences may be prefixed with a number to
specify the maximum length, for example
.Ql #24T .
.Pp
By default, UTF-8 in
.Ar string
is not interpreted, to enable UTF-8, use the
@ -2674,15 +2632,6 @@ through to the terminal (which normally makes a sound).
Also see the
.Ic bell-action
option.
.It Xo Ic visual-content
.Op Ic on | off
.Xc
Like
.Ic visual-activity ,
display a message when content is present in a window
for which the
.Ic monitor-content
window option is enabled.
.It Xo Ic visual-silence
.Op Ic on | off
.Xc
@ -2864,14 +2813,6 @@ option.
Monitor for activity in the window.
Windows with activity are highlighted in the status line.
.Pp
.It Ic monitor-content Ar match-string
Monitor content in the window.
When
.Xr fnmatch 3
pattern
.Ar match-string
appears in the window, it is highlighted in the status line.
.Pp
.It Xo Ic monitor-silence
.Op Ic interval
.Xc
@ -2944,14 +2885,6 @@ see the
.Ic message-command-style
option.
.Pp
.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 ,
@ -3155,7 +3088,6 @@ The following variables are available, where appropriate:
.It Li "window_active" Ta "" Ta "1 if window active"
.It Li "window_activity_flag" Ta "" Ta "1 if window has activity alert"
.It Li "window_bell_flag" Ta "" Ta "1 if window has bell"
.It Li "window_content_flag" Ta "" Ta "1 if window has content alert"
.It Li "window_find_matches" Ta "" Ta "Matched data from the find-window"
.It Li "window_flags" Ta "#F" Ta "Window flags"
.It Li "window_height" Ta "" Ta "Height of window"
@ -3317,18 +3249,15 @@ The flag is one of the following symbols appended to the window name:
.It Li "-" Ta "Marks the last window (previously selected)."
.It Li "#" Ta "Window is monitored and activity has been detected."
.It Li "!" Ta "A bell has occurred in the window."
.It Li "+" Ta "Window is monitored for content and it has appeared."
.It Li "~" Ta "The window has been silent for the monitor-silence interval."
.It Li "Z" Ta "The window's active pane is zoomed."
.El
.Pp
The # symbol relates to the
.Ic monitor-activity
and + to the
.Ic monitor-content
window options.
window option.
The window name is printed in inverted colours if an alert (bell, activity or
content) is present.
silence) is present.
.Pp
The colour and attributes of the status line may be configured, the entire
status line using the

9
tmux.c
View File

@ -209,7 +209,7 @@ main(int argc, char **argv)
char in[256];
const char *home;
long long pid;
int opt, flags, quiet, keys, session;
int opt, flags, keys, session;
#if defined(DEBUG) && defined(__OpenBSD__)
malloc_options = (char *) "AFGJPX";
@ -217,7 +217,7 @@ main(int argc, char **argv)
setlocale(LC_TIME, "");
quiet = flags = 0;
flags = 0;
label = path = NULL;
login_shell = (**argv == '-');
while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUVv")) != -1) {
@ -250,7 +250,6 @@ main(int argc, char **argv)
label = xstrdup(optarg);
break;
case 'q':
quiet = 1;
break;
case 'S':
free(path);
@ -297,11 +296,11 @@ main(int argc, char **argv)
options_init(&global_options, NULL);
options_table_populate_tree(server_options_table, &global_options);
options_set_number(&global_options, "quiet", quiet);
options_init(&global_s_options, NULL);
options_table_populate_tree(session_options_table, &global_s_options);
options_set_string(&global_s_options, "default-shell", "%s", getshell());
options_set_string(&global_s_options, "default-shell", "%s",
getshell());
options_init(&global_w_options, NULL);
options_table_populate_tree(window_options_table, &global_w_options);

55
tmux.h
View File

@ -815,8 +815,11 @@ struct input_ctx {
u_char param_buf[64];
size_t param_len;
u_char input_buf[256];
#define INPUT_BUF_START 32
#define INPUT_BUF_LIMIT 1048576
u_char* input_buf;
size_t input_len;
size_t input_space;
int param_list[24]; /* -1 not present */
u_int param_list_len;
@ -987,10 +990,8 @@ struct winlink {
int flags;
#define WINLINK_BELL 0x1
#define WINLINK_ACTIVITY 0x2
#define WINLINK_CONTENT 0x4
#define WINLINK_SILENCE 0x8
#define WINLINK_ALERTFLAGS \
(WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT|WINLINK_SILENCE)
#define WINLINK_SILENCE 0x4
#define WINLINK_ALERTFLAGS (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_SILENCE)
RB_ENTRY(winlink) entry;
TAILQ_ENTRY(winlink) sentry;
@ -1756,7 +1757,6 @@ extern const struct cmd_entry cmd_break_pane_entry;
extern const struct cmd_entry cmd_capture_pane_entry;
extern const struct cmd_entry cmd_choose_buffer_entry;
extern const struct cmd_entry cmd_choose_client_entry;
extern const struct cmd_entry cmd_choose_list_entry;
extern const struct cmd_entry cmd_choose_session_entry;
extern const struct cmd_entry cmd_choose_tree_entry;
extern const struct cmd_entry cmd_choose_window_entry;
@ -1851,7 +1851,6 @@ size_t cmd_list_print(struct cmd_list *, char *, size_t);
struct cmd_q *cmdq_new(struct client *);
int cmdq_free(struct cmd_q *);
void printflike2 cmdq_print(struct cmd_q *, const char *, ...);
void printflike2 cmdq_info(struct cmd_q *, const char *, ...);
void printflike2 cmdq_error(struct cmd_q *, const char *, ...);
int cmdq_guard(struct cmd_q *, const char *, int);
void cmdq_run(struct cmd_q *, struct cmd_list *);
@ -2127,9 +2126,9 @@ void winlink_stack_remove(struct winlink_stack *, struct winlink *);
int window_index(struct window *, u_int *);
struct window *window_find_by_id(u_int);
struct window *window_create1(u_int, u_int);
struct window *window_create(const char *, const char *, const char *, int,
struct environ *, struct termios *, u_int, u_int, u_int,
char **);
struct window *window_create(const char *, const char *, const char *,
const char *, int, struct environ *, struct termios *,
u_int, u_int, u_int, char **);
void window_destroy(struct window *);
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
void window_set_active_at(struct window *, u_int, u_int);
@ -2139,6 +2138,7 @@ struct window_pane *window_add_pane(struct window *, u_int);
void window_resize(struct window *, u_int, u_int);
int window_zoom(struct window_pane *);
int window_unzoom(struct window *);
void window_lost_pane(struct window *, struct window_pane *);
void window_remove_pane(struct window *, struct window_pane *);
struct window_pane *window_pane_at_index(struct window *, u_int);
struct window_pane *window_pane_next_by_number(struct window *,
@ -2153,8 +2153,8 @@ struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
void window_pane_destroy(struct window_pane *);
void window_pane_timer_start(struct window_pane *);
int window_pane_spawn(struct window_pane *, const char *,
const char *, int, struct environ *, struct termios *,
char **);
const char *, const char *, int, struct environ *,
struct termios *, char **);
void window_pane_resize(struct window_pane *, u_int, u_int);
void window_pane_alternate_on(struct window_pane *,
struct grid_cell *, int);
@ -2290,7 +2290,7 @@ RB_PROTOTYPE(sessions, session, entry, session_cmp);
int session_alive(struct session *);
struct session *session_find(const char *);
struct session *session_find_by_id(u_int);
struct session *session_create(const char *, const char *, int,
struct session *session_create(const char *, const char *, const char *, int,
struct environ *, struct termios *, int, u_int, u_int,
char **);
void session_destroy(struct session *);
@ -2298,12 +2298,12 @@ int session_check_name(const char *);
void session_update_activity(struct session *);
struct session *session_next_session(struct session *);
struct session *session_previous_session(struct session *);
struct winlink *session_new(struct session *, const char *, const char *, int,
int, char **);
struct winlink *session_new(struct session *, const char *, const char *,
const char *, int, int, char **);
struct winlink *session_attach(
struct session *, struct window *, int, char **);
int session_detach(struct session *, struct winlink *);
struct winlink* session_has(struct session *, struct window *);
struct winlink *session_has(struct session *, struct window *);
int session_next(struct session *, int);
int session_previous(struct session *, int);
int session_select(struct session *, int);
@ -2319,12 +2319,17 @@ void session_group_synchronize1(struct session *, struct session *);
void session_renumber_windows(struct session *);
/* utf8.c */
void utf8_build(void);
int utf8_open(struct utf8_data *, u_char);
int utf8_append(struct utf8_data *, u_char);
u_int utf8_combine(const struct utf8_data *);
u_int utf8_split2(u_int, u_char *);
int utf8_strvis(char *, const char *, size_t, int);
void utf8_build(void);
void utf8_set(struct utf8_data *, u_char);
int utf8_open(struct utf8_data *, u_char);
int utf8_append(struct utf8_data *, u_char);
u_int utf8_combine(const struct utf8_data *);
u_int utf8_split2(u_int, u_char *);
int utf8_strvis(char *, const char *, size_t, int);
struct utf8_data *utf8_fromcstr(const char *);
char *utf8_tocstr(struct utf8_data *);
u_int utf8_cstrwidth(const char *);
char *utf8_trimcstr(const char *, u_int);
/* osdep-*.c */
char *osdep_get_name(int, char *);
@ -2355,7 +2360,9 @@ 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 *);
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

@ -512,7 +512,8 @@ tty_term_ptr1(struct tty_term *term, enum tty_code_code code, const void *a)
}
const char *
tty_term_ptr2(struct tty_term *term, enum tty_code_code code, const void *a, const void *b)
tty_term_ptr2(struct tty_term *term, enum tty_code_code code, const void *a,
const void *b)
{
return (tparm((char *) tty_term_string(term, code), a, b, 0, 0, 0, 0, 0, 0, 0));
}

7
tty.c
View File

@ -388,7 +388,8 @@ tty_putcode_ptr1(struct tty *tty, enum tty_code_code code, const void *a)
}
void
tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a, const void *b)
tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a,
const void *b)
{
if (a != NULL && b != NULL)
tty_puts(tty, tty_term_ptr2(tty->term, code, a, b));
@ -547,8 +548,8 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s)
}
void
tty_emulate_repeat(
struct tty *tty, enum tty_code_code code, enum tty_code_code code1, u_int n)
tty_emulate_repeat(struct tty *tty, enum tty_code_code code,
enum tty_code_code code1, u_int n)
{
if (tty_term_has(tty->term, code))
tty_putcode1(tty, code, n);

122
utf8.c
View File

@ -18,6 +18,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@ -200,6 +201,16 @@ int utf8_overlap(struct utf8_width_entry *, struct utf8_width_entry *);
u_int utf8_combine(const struct utf8_data *);
u_int utf8_width(const struct utf8_data *);
/* Set a single character. */
void
utf8_set(struct utf8_data *utf8data, u_char ch)
{
*utf8data->data = ch;
utf8data->size = 1;
utf8data->width = 1;
}
/*
* Open UTF-8 sequence.
*
@ -248,8 +259,7 @@ utf8_append(struct utf8_data *utf8data, u_char ch)
/* Check if two width tree entries overlap. */
int
utf8_overlap(
struct utf8_width_entry *item1, struct utf8_width_entry *item2)
utf8_overlap(struct utf8_width_entry *item1, struct utf8_width_entry *item2)
{
if (item1->first >= item2->first && item1->first <= item2->last)
return (1);
@ -394,3 +404,111 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
*dst = '\0';
return (dst - start);
}
/*
* Convert a string into a buffer of UTF-8 characters. Terminated by size == 0.
* Caller frees.
*/
struct utf8_data *
utf8_fromcstr(const char *src)
{
struct utf8_data *dst;
size_t n;
int more;
dst = NULL;
n = 0;
while (*src != '\0') {
dst = xrealloc(dst, n + 1, sizeof *dst);
if (utf8_open(&dst[n], *src)) {
more = 1;
while (*++src != '\0' && more)
more = utf8_append(&dst[n], *src);
if (!more) {
n++;
continue;
}
src -= dst[n].have;
}
utf8_set(&dst[n], *src);
src++;
n++;
}
dst = xrealloc(dst, n + 1, sizeof *dst);
dst[n].size = 0;
return (dst);
}
/* Convert from a buffer of UTF-8 characters into a string. Caller frees. */
char *
utf8_tocstr(struct utf8_data *src)
{
char *dst;
size_t n;
dst = NULL;
n = 0;
for(; src->size != 0; src++) {
dst = xrealloc(dst, n + src->size, 1);
memcpy(dst + n, src->data, src->size);
n += src->size;
}
dst = xrealloc(dst, n + 1, 1);
dst[n] = '\0';
return (dst);
}
/* Get width of UTF-8 string. */
u_int
utf8_cstrwidth(const char *s)
{
struct utf8_data tmp;
u_int width;
int more;
width = 0;
while (*s != '\0') {
if (utf8_open(&tmp, *s)) {
more = 1;
while (*++s != '\0' && more)
more = utf8_append(&tmp, *s);
if (!more) {
width += tmp.width;
continue;
}
s -= tmp.have;
}
width++;
s++;
}
return (width);
}
/* Trim UTF-8 string to width. Caller frees. */
char *
utf8_trimcstr(const char *s, u_int width)
{
struct utf8_data *tmp, *next;
char *out;
u_int at;
tmp = utf8_fromcstr(s);
at = 0;
for (next = tmp; next->size != 0; next++) {
if (at + next->width > width) {
next->size = 0;
break;
}
at += next->width;
}
out = utf8_tocstr(tmp);
free(tmp);
return (out);
}

View File

@ -715,21 +715,23 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key)
}
void
window_choose_mouse(
struct window_pane *wp, unused struct session *sess, struct mouse_event *m)
window_choose_mouse(struct window_pane *wp, struct session *sess,
struct mouse_event *m)
{
struct window_choose_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct window_choose_mode_item *item;
u_int i, idx;
u_int idx;
if (m->event == MOUSE_EVENT_WHEEL) {
for (i = 0; i < m->scroll; i++) {
if (m->wheel == MOUSE_WHEEL_UP)
window_choose_key(wp, sess, KEYC_UP);
else
window_choose_key(wp, sess, KEYC_DOWN);
}
/*
* Don't use m->scroll and just move line-by-line or it's
* annoying.
*/
if (m->wheel == MOUSE_WHEEL_UP)
window_choose_key(wp, sess, KEYC_UP);
else
window_choose_key(wp, sess, KEYC_DOWN);
return;
}

View File

@ -1194,8 +1194,8 @@ window_copy_write_line(
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 (limit > screen_size_x(s) + 1)
limit = screen_size_x(s) + 1;
if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) {
xoff = size = xsnprintf(hdr, limit,
"Repeat: %u", data->numprefix);
@ -1208,10 +1208,12 @@ window_copy_write_line(
} else
size = 0;
screen_write_cursormove(ctx, xoff, py);
screen_write_copy(ctx, data->backing, xoff,
(screen_hsize(data->backing) - data->oy) + py,
screen_size_x(s) - size, 1);
if (size < screen_size_x(s)) {
screen_write_cursormove(ctx, xoff, py);
screen_write_copy(ctx, data->backing, xoff,
(screen_hsize(data->backing) - data->oy) + py,
screen_size_x(s) - size, 1);
}
if (py == data->cy && data->cx == screen_size_x(s)) {
memcpy(&gc, &grid_default_cell, sizeof gc);
@ -2031,7 +2033,8 @@ window_copy_cursor_next_word(struct window_pane *wp, const char *separators)
}
void
window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators)
window_copy_cursor_next_word_end(struct window_pane *wp,
const char *separators)
{
struct window_copy_mode_data *data = wp->modedata;
struct options *oo = &wp->window->options;
@ -2082,7 +2085,8 @@ window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators)
/* Move to the previous place where a word begins. */
void
window_copy_cursor_previous_word(struct window_pane *wp, const char *separators)
window_copy_cursor_previous_word(struct window_pane *wp,
const char *separators)
{
struct window_copy_mode_data *data = wp->modedata;
u_int px, py;

View File

@ -17,13 +17,11 @@
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <pwd.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
@ -309,8 +307,8 @@ window_create1(u_int sx, u_int sy)
}
struct window *
window_create(const char *name, const char *cmd, const char *shell,
int cwd, struct environ *env, struct termios *tio,
window_create(const char *name, const char *cmd, const char *path,
const char *shell, int cwd, struct environ *env, struct termios *tio,
u_int sx, u_int sy, u_int hlimit, char **cause)
{
struct window *w;
@ -320,7 +318,8 @@ window_create(const char *name, const char *cmd, const char *shell,
wp = window_add_pane(w, hlimit);
layout_init(w, wp);
if (window_pane_spawn(wp, cmd, shell, cwd, env, tio, cause) != 0) {
if (window_pane_spawn(wp, cmd, path, shell, cwd, env, tio,
cause) != 0) {
window_destroy(w);
return (NULL);
}
@ -588,7 +587,7 @@ window_add_pane(struct window *w, u_int hlimit)
}
void
window_remove_pane(struct window *w, struct window_pane *wp)
window_lost_pane(struct window *w, struct window_pane *wp)
{
if (wp == w->active) {
w->active = w->last;
@ -600,6 +599,12 @@ window_remove_pane(struct window *w, struct window_pane *wp)
}
} else if (wp == w->last)
w->last = NULL;
}
void
window_remove_pane(struct window *w, struct window_pane *wp)
{
window_lost_pane(w, wp);
TAILQ_REMOVE(&w->panes, wp, entry);
window_pane_destroy(wp);
@ -696,8 +701,6 @@ window_printable_flags(struct session *s, struct winlink *wl)
flags[pos++] = '#';
if (wl->flags & WINLINK_BELL)
flags[pos++] = '!';
if (wl->flags & WINLINK_CONTENT)
flags[pos++] = '+';
if (wl->flags & WINLINK_SILENCE)
flags[pos++] = '~';
if (wl == s->curw)
@ -810,8 +813,9 @@ window_pane_destroy(struct window_pane *wp)
}
int
window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
int cwd, struct environ *env, struct termios *tio, char **cause)
window_pane_spawn(struct window_pane *wp, const char *cmd, const char *path,
const char *shell, int cwd, struct environ *env, struct termios *tio,
char **cause)
{
struct winsize ws;
char *argv0, paneid[16];
@ -867,6 +871,8 @@ window_pane_spawn(struct window_pane *wp, const char *cmd, const char *shell,
closefrom(STDERR_FILENO + 1);
if (path != NULL)
environ_set(env, "PATH", path);
xsnprintf(paneid, sizeof paneid, "%%%u", wp->id);
environ_set(env, "TMUX_PANE", paneid);
environ_push(env);
@ -1170,7 +1176,8 @@ window_pane_visible(struct window_pane *wp)
}
char *
window_pane_search(struct window_pane *wp, const char *searchstr, u_int *lineno)
window_pane_search(struct window_pane *wp, const char *searchstr,
u_int *lineno)
{
struct screen *s = &wp->base;
char *newsearchstr, *line, *msg;