merge conflicts
This commit is contained in:
parent
aa83ff61b0
commit
68e6ba8497
359
external/bsd/tmux/dist/client.c
vendored
359
external/bsd/tmux/dist/client.c
vendored
@ -35,7 +35,6 @@
|
||||
static struct tmuxproc *client_proc;
|
||||
static struct tmuxpeer *client_peer;
|
||||
static int client_flags;
|
||||
static struct event client_stdin;
|
||||
static enum {
|
||||
CLIENT_EXIT_NONE,
|
||||
CLIENT_EXIT_DETACHED,
|
||||
@ -46,19 +45,19 @@ static enum {
|
||||
CLIENT_EXIT_EXITED,
|
||||
CLIENT_EXIT_SERVER_EXITED,
|
||||
} client_exitreason = CLIENT_EXIT_NONE;
|
||||
static int client_exitflag;
|
||||
static int client_exitval;
|
||||
static enum msgtype client_exittype;
|
||||
static const char *client_exitsession;
|
||||
static const char *client_execshell;
|
||||
static const char *client_execcmd;
|
||||
static int client_attached;
|
||||
static struct client_files client_files = RB_INITIALIZER(&client_files);
|
||||
|
||||
static __dead void client_exec(const char *,const char *);
|
||||
static int client_get_lock(char *);
|
||||
static int client_connect(struct event_base *, const char *, int);
|
||||
static void client_send_identify(const char *, const char *);
|
||||
static void client_stdin_callback(int, short, void *);
|
||||
static void client_write(int, const char *, size_t);
|
||||
static void client_signal(int);
|
||||
static void client_dispatch(struct imsg *, void *);
|
||||
static void client_dispatch_attached(struct imsg *);
|
||||
@ -211,13 +210,34 @@ client_exit_message(void)
|
||||
return ("unknown reason");
|
||||
}
|
||||
|
||||
/* Exit if all streams flushed. */
|
||||
static void
|
||||
client_exit(void)
|
||||
{
|
||||
struct client_file *cf;
|
||||
size_t left;
|
||||
int waiting = 0;
|
||||
|
||||
RB_FOREACH (cf, client_files, &client_files) {
|
||||
if (cf->event == NULL)
|
||||
continue;
|
||||
left = EVBUFFER_LENGTH(cf->event->output);
|
||||
if (left != 0) {
|
||||
waiting++;
|
||||
log_debug("file %u %zu bytes left", cf->stream, left);
|
||||
}
|
||||
}
|
||||
if (waiting == 0)
|
||||
proc_exit(client_proc);
|
||||
}
|
||||
|
||||
/* Client main loop. */
|
||||
int
|
||||
client_main(struct event_base *base, int argc, char **argv, int flags)
|
||||
{
|
||||
struct cmd_parse_result *pr;
|
||||
struct cmd *cmd;
|
||||
struct msg_command_data *data;
|
||||
struct msg_command *data;
|
||||
int cmdflags, fd, i;
|
||||
const char *ttynam, *cwd;
|
||||
pid_t ppid;
|
||||
@ -291,7 +311,9 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
||||
*
|
||||
* "sendfd" is dropped later in client_dispatch_wait().
|
||||
*/
|
||||
if (pledge("stdio unix sendfd proc exec tty", NULL) != 0)
|
||||
if (pledge(
|
||||
"stdio rpath wpath cpath unix sendfd proc exec tty",
|
||||
NULL) != 0)
|
||||
fatal("pledge failed");
|
||||
|
||||
/* Free stuff that is not used in the client. */
|
||||
@ -302,10 +324,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
||||
options_free(global_w_options);
|
||||
environ_free(global_environ);
|
||||
|
||||
/* Create stdin handler. */
|
||||
setblocking(STDIN_FILENO, 0);
|
||||
event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST,
|
||||
client_stdin_callback, NULL);
|
||||
/* Set up control mode. */
|
||||
if (client_flags & CLIENT_CONTROLCONTROL) {
|
||||
if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
|
||||
fprintf(stderr, "tcgetattr failed: %s\n",
|
||||
@ -428,39 +447,255 @@ client_send_identify(const char *ttynam, const char *cwd)
|
||||
proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0);
|
||||
}
|
||||
|
||||
/* Callback for client stdin read events. */
|
||||
/* File write error callback. */
|
||||
static void
|
||||
client_stdin_callback(__unused int fd, __unused short events,
|
||||
__unused void *arg)
|
||||
client_write_error_callback(__unused struct bufferevent *bev,
|
||||
__unused short what, void *arg)
|
||||
{
|
||||
struct msg_stdin_data data;
|
||||
struct client_file *cf = arg;
|
||||
|
||||
data.size = read(STDIN_FILENO, data.data, sizeof data.data);
|
||||
if (data.size == -1 && (errno == EINTR || errno == EAGAIN))
|
||||
return;
|
||||
log_debug("write error file %d", cf->stream);
|
||||
|
||||
proc_send(client_peer, MSG_STDIN, -1, &data, sizeof data);
|
||||
if (data.size <= 0)
|
||||
event_del(&client_stdin);
|
||||
bufferevent_free(cf->event);
|
||||
cf->event = NULL;
|
||||
|
||||
close(cf->fd);
|
||||
cf->fd = -1;
|
||||
|
||||
if (client_exitflag)
|
||||
client_exit();
|
||||
}
|
||||
|
||||
/* Force write to file descriptor. */
|
||||
/* File write callback. */
|
||||
static void
|
||||
client_write(int fd, const char *data, size_t size)
|
||||
client_write_callback(__unused struct bufferevent *bev, void *arg)
|
||||
{
|
||||
ssize_t used;
|
||||
struct client_file *cf = arg;
|
||||
|
||||
log_debug("%s: %.*s", __func__, (int)size, data);
|
||||
while (size != 0) {
|
||||
used = write(fd, data, size);
|
||||
if (used == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
data += used;
|
||||
size -= used;
|
||||
if (cf->closed && EVBUFFER_LENGTH(cf->event->output) == 0) {
|
||||
bufferevent_free(cf->event);
|
||||
close(cf->fd);
|
||||
RB_REMOVE(client_files, &client_files, cf);
|
||||
file_free(cf);
|
||||
}
|
||||
|
||||
if (client_exitflag)
|
||||
client_exit();
|
||||
}
|
||||
|
||||
/* Open write file. */
|
||||
static void
|
||||
client_write_open(void *data, size_t datalen)
|
||||
{
|
||||
struct msg_write_open *msg = data;
|
||||
const char *path;
|
||||
struct msg_write_ready reply;
|
||||
struct client_file find, *cf;
|
||||
const int flags = O_NONBLOCK|O_WRONLY|O_CREAT;
|
||||
int error = 0;
|
||||
|
||||
if (datalen < sizeof *msg)
|
||||
fatalx("bad MSG_WRITE_OPEN size");
|
||||
if (datalen == sizeof *msg)
|
||||
path = "-";
|
||||
else
|
||||
path = (const char *)(msg + 1);
|
||||
log_debug("open write file %d %s", msg->stream, path);
|
||||
|
||||
find.stream = msg->stream;
|
||||
if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) {
|
||||
cf = file_create(NULL, msg->stream, NULL, NULL);
|
||||
RB_INSERT(client_files, &client_files, cf);
|
||||
} else {
|
||||
error = EBADF;
|
||||
goto reply;
|
||||
}
|
||||
if (cf->closed) {
|
||||
error = EBADF;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
cf->fd = -1;
|
||||
if (msg->fd == -1)
|
||||
cf->fd = open(path, msg->flags|flags, 0644);
|
||||
else {
|
||||
if (msg->fd != STDOUT_FILENO && msg->fd != STDERR_FILENO)
|
||||
errno = EBADF;
|
||||
else {
|
||||
cf->fd = dup(msg->fd);
|
||||
if (~client_flags & CLIENT_CONTROL)
|
||||
close(msg->fd); /* can only be used once */
|
||||
}
|
||||
}
|
||||
if (cf->fd == -1) {
|
||||
error = errno;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
cf->event = bufferevent_new(cf->fd, NULL, client_write_callback,
|
||||
client_write_error_callback, cf);
|
||||
bufferevent_enable(cf->event, EV_WRITE);
|
||||
goto reply;
|
||||
|
||||
reply:
|
||||
reply.stream = msg->stream;
|
||||
reply.error = error;
|
||||
proc_send(client_peer, MSG_WRITE_READY, -1, &reply, sizeof reply);
|
||||
}
|
||||
|
||||
/* Write to client file. */
|
||||
static void
|
||||
client_write_data(void *data, size_t datalen)
|
||||
{
|
||||
struct msg_write_data *msg = data;
|
||||
struct client_file find, *cf;
|
||||
size_t size = datalen - sizeof *msg;
|
||||
|
||||
if (datalen < sizeof *msg)
|
||||
fatalx("bad MSG_WRITE size");
|
||||
find.stream = msg->stream;
|
||||
if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL)
|
||||
fatalx("unknown stream number");
|
||||
log_debug("write %zu to file %d", size, cf->stream);
|
||||
|
||||
if (cf->event != NULL)
|
||||
bufferevent_write(cf->event, msg + 1, size);
|
||||
}
|
||||
|
||||
/* Close client file. */
|
||||
static void
|
||||
client_write_close(void *data, size_t datalen)
|
||||
{
|
||||
struct msg_write_close *msg = data;
|
||||
struct client_file find, *cf;
|
||||
|
||||
if (datalen != sizeof *msg)
|
||||
fatalx("bad MSG_WRITE_CLOSE size");
|
||||
find.stream = msg->stream;
|
||||
if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL)
|
||||
fatalx("unknown stream number");
|
||||
log_debug("close file %d", cf->stream);
|
||||
|
||||
if (cf->event == NULL || EVBUFFER_LENGTH(cf->event->output) == 0) {
|
||||
if (cf->event != NULL)
|
||||
bufferevent_free(cf->event);
|
||||
if (cf->fd != -1)
|
||||
close(cf->fd);
|
||||
RB_REMOVE(client_files, &client_files, cf);
|
||||
file_free(cf);
|
||||
}
|
||||
}
|
||||
|
||||
/* File read callback. */
|
||||
static void
|
||||
client_read_callback(__unused struct bufferevent *bev, void *arg)
|
||||
{
|
||||
struct client_file *cf = arg;
|
||||
void *bdata;
|
||||
size_t bsize;
|
||||
struct msg_read_data *msg;
|
||||
size_t msglen;
|
||||
|
||||
msg = xmalloc(sizeof *msg);
|
||||
for (;;) {
|
||||
bdata = EVBUFFER_DATA(cf->event->input);
|
||||
bsize = EVBUFFER_LENGTH(cf->event->input);
|
||||
|
||||
if (bsize == 0)
|
||||
break;
|
||||
if (bsize > MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg)
|
||||
bsize = MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg;
|
||||
log_debug("read %zu from file %d", bsize, cf->stream);
|
||||
|
||||
msglen = (sizeof *msg) + bsize;
|
||||
msg = xrealloc(msg, msglen);
|
||||
msg->stream = cf->stream;
|
||||
memcpy(msg + 1, bdata, bsize);
|
||||
proc_send(client_peer, MSG_READ, -1, msg, msglen);
|
||||
|
||||
evbuffer_drain(cf->event->input, bsize);
|
||||
}
|
||||
free(msg);
|
||||
}
|
||||
|
||||
/* File read error callback. */
|
||||
static void
|
||||
client_read_error_callback(__unused struct bufferevent *bev,
|
||||
__unused short what, void *arg)
|
||||
{
|
||||
struct client_file *cf = arg;
|
||||
struct msg_read_done msg;
|
||||
|
||||
log_debug("read error file %d", cf->stream);
|
||||
|
||||
msg.stream = cf->stream;
|
||||
msg.error = 0;
|
||||
proc_send(client_peer, MSG_READ_DONE, -1, &msg, sizeof msg);
|
||||
|
||||
bufferevent_free(cf->event);
|
||||
close(cf->fd);
|
||||
RB_REMOVE(client_files, &client_files, cf);
|
||||
file_free(cf);
|
||||
}
|
||||
|
||||
/* Open read file. */
|
||||
static void
|
||||
client_read_open(void *data, size_t datalen)
|
||||
{
|
||||
struct msg_read_open *msg = data;
|
||||
const char *path;
|
||||
struct msg_read_done reply;
|
||||
struct client_file find, *cf;
|
||||
const int flags = O_NONBLOCK|O_RDONLY;
|
||||
int error = 0;
|
||||
|
||||
if (datalen < sizeof *msg)
|
||||
fatalx("bad MSG_READ_OPEN size");
|
||||
if (datalen == sizeof *msg)
|
||||
path = "-";
|
||||
else
|
||||
path = (const char *)(msg + 1);
|
||||
log_debug("open read file %d %s", msg->stream, path);
|
||||
|
||||
find.stream = msg->stream;
|
||||
if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) {
|
||||
cf = file_create(NULL, msg->stream, NULL, NULL);
|
||||
RB_INSERT(client_files, &client_files, cf);
|
||||
} else {
|
||||
error = EBADF;
|
||||
goto reply;
|
||||
}
|
||||
if (cf->closed) {
|
||||
error = EBADF;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
cf->fd = -1;
|
||||
if (msg->fd == -1)
|
||||
cf->fd = open(path, flags);
|
||||
else {
|
||||
if (msg->fd != STDIN_FILENO)
|
||||
errno = EBADF;
|
||||
else {
|
||||
cf->fd = dup(msg->fd);
|
||||
if (~client_flags & CLIENT_CONTROL)
|
||||
close(msg->fd); /* can only be used once */
|
||||
}
|
||||
}
|
||||
if (cf->fd == -1) {
|
||||
error = errno;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
cf->event = bufferevent_new(cf->fd, client_read_callback, NULL,
|
||||
client_read_error_callback, cf);
|
||||
bufferevent_enable(cf->event, EV_READ);
|
||||
return;
|
||||
|
||||
reply:
|
||||
reply.stream = msg->stream;
|
||||
reply.error = error;
|
||||
proc_send(client_peer, MSG_READ_DONE, -1, &reply, sizeof reply);
|
||||
}
|
||||
|
||||
/* Run command in shell; used for -c. */
|
||||
@ -555,12 +790,10 @@ client_dispatch(struct imsg *imsg, __unused void *arg)
|
||||
static void
|
||||
client_dispatch_wait(struct imsg *imsg)
|
||||
{
|
||||
char *data;
|
||||
ssize_t datalen;
|
||||
struct msg_stdout_data stdoutdata;
|
||||
struct msg_stderr_data stderrdata;
|
||||
int retval;
|
||||
static int pledge_applied;
|
||||
char *data;
|
||||
ssize_t datalen;
|
||||
int retval;
|
||||
static int pledge_applied;
|
||||
|
||||
/*
|
||||
* "sendfd" is no longer required once all of the identify messages
|
||||
@ -569,10 +802,12 @@ client_dispatch_wait(struct imsg *imsg)
|
||||
* get the first message from the server.
|
||||
*/
|
||||
if (!pledge_applied) {
|
||||
if (pledge("stdio unix proc exec tty", NULL) != 0)
|
||||
if (pledge(
|
||||
"stdio rpath wpath cpath unix proc exec tty",
|
||||
NULL) != 0)
|
||||
fatal("pledge failed");
|
||||
pledge_applied = 1;
|
||||
};
|
||||
}
|
||||
|
||||
data = imsg->data;
|
||||
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
@ -586,38 +821,16 @@ client_dispatch_wait(struct imsg *imsg)
|
||||
memcpy(&retval, data, sizeof retval);
|
||||
client_exitval = retval;
|
||||
}
|
||||
proc_exit(client_proc);
|
||||
client_exitflag = 1;
|
||||
client_exit();
|
||||
break;
|
||||
case MSG_READY:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_READY size");
|
||||
|
||||
event_del(&client_stdin);
|
||||
client_attached = 1;
|
||||
proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
|
||||
break;
|
||||
case MSG_STDIN:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_STDIN size");
|
||||
|
||||
event_add(&client_stdin, NULL);
|
||||
break;
|
||||
case MSG_STDOUT:
|
||||
if (datalen != sizeof stdoutdata)
|
||||
fatalx("bad MSG_STDOUT size");
|
||||
memcpy(&stdoutdata, data, sizeof stdoutdata);
|
||||
|
||||
client_write(STDOUT_FILENO, stdoutdata.data,
|
||||
stdoutdata.size);
|
||||
break;
|
||||
case MSG_STDERR:
|
||||
if (datalen != sizeof stderrdata)
|
||||
fatalx("bad MSG_STDERR size");
|
||||
memcpy(&stderrdata, data, sizeof stderrdata);
|
||||
|
||||
client_write(STDERR_FILENO, stderrdata.data,
|
||||
stderrdata.size);
|
||||
break;
|
||||
case MSG_VERSION:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_VERSION size");
|
||||
@ -641,6 +854,24 @@ client_dispatch_wait(struct imsg *imsg)
|
||||
case MSG_EXITED:
|
||||
proc_exit(client_proc);
|
||||
break;
|
||||
case MSG_READ_OPEN:
|
||||
client_read_open(data, datalen);
|
||||
break;
|
||||
case MSG_WRITE_OPEN:
|
||||
client_write_open(data, datalen);
|
||||
break;
|
||||
case MSG_WRITE:
|
||||
client_write_data(data, datalen);
|
||||
break;
|
||||
case MSG_WRITE_CLOSE:
|
||||
client_write_close(data, datalen);
|
||||
break;
|
||||
case MSG_OLDSTDERR:
|
||||
case MSG_OLDSTDIN:
|
||||
case MSG_OLDSTDOUT:
|
||||
fprintf(stderr, "server version is too old for client\n");
|
||||
proc_exit(client_proc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
2
external/bsd/tmux/dist/cmd-attach-session.c
vendored
2
external/bsd/tmux/dist/cmd-attach-session.c
vendored
@ -127,6 +127,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
|
||||
gettimeofday(&s->last_attached_time, NULL);
|
||||
server_redraw_client(c);
|
||||
s->curw->flags &= ~WINLINK_ALERTFLAGS;
|
||||
s->curw->window->latest = c;
|
||||
} else {
|
||||
if (server_client_open(c, &cause) != 0) {
|
||||
cmdq_error(item, "open terminal failed: %s", cause);
|
||||
@ -159,6 +160,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
|
||||
gettimeofday(&s->last_attached_time, NULL);
|
||||
server_redraw_client(c);
|
||||
s->curw->flags &= ~WINLINK_ALERTFLAGS;
|
||||
s->curw->window->latest = c;
|
||||
|
||||
if (~c->flags & CLIENT_CONTROL)
|
||||
proc_send(c->peer, MSG_READY, -1, NULL, 0);
|
||||
|
24
external/bsd/tmux/dist/cmd-capture-pane.c
vendored
24
external/bsd/tmux/dist/cmd-capture-pane.c
vendored
@ -39,8 +39,8 @@ const struct cmd_entry cmd_capture_pane_entry = {
|
||||
.name = "capture-pane",
|
||||
.alias = "capturep",
|
||||
|
||||
.args = { "ab:CeE:JpPqS:t:", 0, 0 },
|
||||
.usage = "[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] "
|
||||
.args = { "ab:CeE:JNpPqS:t:", 0, 0 },
|
||||
.usage = "[-aCeJNpPq] " CMD_BUFFER_USAGE " [-E end-line] "
|
||||
"[-S start-line] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
@ -110,7 +110,7 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
|
||||
struct grid *gd;
|
||||
const struct grid_line *gl;
|
||||
struct grid_cell *gc = NULL;
|
||||
int n, with_codes, escape_c0, join_lines;
|
||||
int n, with_codes, escape_c0, join_lines, no_trim;
|
||||
u_int i, sx, top, bottom, tmp;
|
||||
char *cause, *buf, *line;
|
||||
const char *Sflag, *Eflag;
|
||||
@ -170,11 +170,12 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
|
||||
with_codes = args_has(args, 'e');
|
||||
escape_c0 = args_has(args, 'C');
|
||||
join_lines = args_has(args, 'J');
|
||||
no_trim = args_has(args, 'N');
|
||||
|
||||
buf = NULL;
|
||||
for (i = top; i <= bottom; i++) {
|
||||
line = grid_string_cells(gd, 0, i, sx, &gc, with_codes,
|
||||
escape_c0, !join_lines);
|
||||
escape_c0, !join_lines && !no_trim);
|
||||
linelen = strlen(line);
|
||||
|
||||
buf = cmd_capture_pane_append(buf, len, line, linelen);
|
||||
@ -192,7 +193,7 @@ static enum cmd_retval
|
||||
cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct client *c = item->client;
|
||||
struct window_pane *wp = item->target.wp;
|
||||
char *buf, *cause;
|
||||
const char *bufname;
|
||||
@ -213,18 +214,15 @@ cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (args_has(args, 'p')) {
|
||||
c = item->client;
|
||||
if (c == NULL ||
|
||||
(c->session != NULL && !(c->flags & CLIENT_CONTROL))) {
|
||||
cmdq_error(item, "can't write to stdout");
|
||||
if (!file_can_print(c)) {
|
||||
cmdq_error(item, "can't write output to client");
|
||||
free(buf);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
evbuffer_add(c->stdout_data, buf, len);
|
||||
free(buf);
|
||||
file_print_buffer(c, buf, len);
|
||||
if (args_has(args, 'P') && len > 0)
|
||||
evbuffer_add(c->stdout_data, "\n", 1);
|
||||
server_client_push_stdout(c);
|
||||
file_print(c, "\n");
|
||||
free(buf);
|
||||
} else {
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
|
160
external/bsd/tmux/dist/cmd-load-buffer.c
vendored
160
external/bsd/tmux/dist/cmd-load-buffer.c
vendored
@ -33,8 +33,6 @@
|
||||
|
||||
static enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmdq_item *);
|
||||
|
||||
static void cmd_load_buffer_callback(struct client *, int, void *);
|
||||
|
||||
const struct cmd_entry cmd_load_buffer_entry = {
|
||||
.name = "load-buffer",
|
||||
.alias = "loadb",
|
||||
@ -48,9 +46,40 @@ const struct cmd_entry cmd_load_buffer_entry = {
|
||||
|
||||
struct cmd_load_buffer_data {
|
||||
struct cmdq_item *item;
|
||||
char *bufname;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static void
|
||||
cmd_load_buffer_done(__unused struct client *c, const char *path, int error,
|
||||
int closed, struct evbuffer *buffer, void *data)
|
||||
{
|
||||
struct cmd_load_buffer_data *cdata = data;
|
||||
struct cmdq_item *item = cdata->item;
|
||||
void *bdata = EVBUFFER_DATA(buffer);
|
||||
size_t bsize = EVBUFFER_LENGTH(buffer);
|
||||
void *copy;
|
||||
char *cause;
|
||||
|
||||
if (!closed)
|
||||
return;
|
||||
|
||||
if (error != 0)
|
||||
cmdq_error(item, "%s: %s", path, strerror(error));
|
||||
else if (bsize != 0) {
|
||||
copy = xmalloc(bsize);
|
||||
memcpy(copy, bdata, bsize);
|
||||
if (paste_set(copy, bsize, cdata->name, &cause) != 0) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
free(cause);
|
||||
free(copy);
|
||||
}
|
||||
}
|
||||
cmdq_continue(item);
|
||||
|
||||
free(cdata->name);
|
||||
free(cdata);
|
||||
}
|
||||
|
||||
static enum cmd_retval
|
||||
cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
@ -60,124 +89,19 @@ cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct session *s = item->target.s;
|
||||
struct winlink *wl = item->target.wl;
|
||||
struct window_pane *wp = item->target.wp;
|
||||
FILE *f;
|
||||
const char *bufname;
|
||||
char *pdata = NULL, *new_pdata, *cause;
|
||||
char *path, *file;
|
||||
size_t psize;
|
||||
int ch, error;
|
||||
const char *bufname = args_get(args, 'b');
|
||||
char *path;
|
||||
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
bufname = args_get(args, 'b');
|
||||
cdata = xmalloc(sizeof *cdata);
|
||||
cdata->item = item;
|
||||
if (bufname != NULL)
|
||||
cdata->name = xstrdup(bufname);
|
||||
else
|
||||
cdata->name = NULL;
|
||||
|
||||
path = format_single(item, args->argv[0], c, s, wl, wp);
|
||||
if (strcmp(path, "-") == 0) {
|
||||
free(path);
|
||||
c = item->client;
|
||||
|
||||
cdata = xcalloc(1, sizeof *cdata);
|
||||
cdata->item = item;
|
||||
|
||||
if (bufname != NULL)
|
||||
cdata->bufname = xstrdup(bufname);
|
||||
|
||||
error = server_set_stdin_callback(c, cmd_load_buffer_callback,
|
||||
cdata, &cause);
|
||||
if (error != 0) {
|
||||
cmdq_error(item, "-: %s", cause);
|
||||
free(cause);
|
||||
free(cdata);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
return (CMD_RETURN_WAIT);
|
||||
}
|
||||
|
||||
file = server_client_get_path(item->client, path);
|
||||
file_read(item->client, path, cmd_load_buffer_done, cdata);
|
||||
free(path);
|
||||
|
||||
f = fopen(file, "rb");
|
||||
if (f == NULL) {
|
||||
cmdq_error(item, "%s: %s", file, strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
pdata = NULL;
|
||||
psize = 0;
|
||||
while ((ch = getc(f)) != EOF) {
|
||||
/* Do not let the server die due to memory exhaustion. */
|
||||
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
|
||||
cmdq_error(item, "realloc error: %s", strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
pdata = new_pdata;
|
||||
pdata[psize++] = ch;
|
||||
}
|
||||
if (ferror(f)) {
|
||||
cmdq_error(item, "%s: read error", file);
|
||||
goto error;
|
||||
}
|
||||
if (pdata != NULL)
|
||||
pdata[psize] = '\0';
|
||||
|
||||
fclose(f);
|
||||
free(file);
|
||||
|
||||
if (paste_set(pdata, psize, bufname, &cause) != 0) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
free(pdata);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
error:
|
||||
free(pdata);
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
free(file);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_load_buffer_callback(struct client *c, int closed, void *data)
|
||||
{
|
||||
struct cmd_load_buffer_data *cdata = data;
|
||||
char *pdata, *cause, *saved;
|
||||
size_t psize;
|
||||
|
||||
if (!closed)
|
||||
return;
|
||||
c->stdin_callback = NULL;
|
||||
|
||||
server_client_unref(c);
|
||||
if (c->flags & CLIENT_DEAD)
|
||||
goto out;
|
||||
|
||||
psize = EVBUFFER_LENGTH(c->stdin_data);
|
||||
if (psize == 0 || (pdata = malloc(psize + 1)) == NULL)
|
||||
goto out;
|
||||
|
||||
memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize);
|
||||
pdata[psize] = '\0';
|
||||
evbuffer_drain(c->stdin_data, psize);
|
||||
|
||||
if (paste_set(pdata, psize, cdata->bufname, &cause) != 0) {
|
||||
/* No context so can't use server_client_msg_error. */
|
||||
if (~c->flags & CLIENT_UTF8) {
|
||||
saved = cause;
|
||||
cause = utf8_sanitize(saved);
|
||||
free(saved);
|
||||
}
|
||||
evbuffer_add_printf(c->stderr_data, "%s", cause);
|
||||
server_client_push_stderr(c);
|
||||
free(pdata);
|
||||
free(cause);
|
||||
}
|
||||
out:
|
||||
cmdq_continue(cdata->item);
|
||||
|
||||
free(cdata->bufname);
|
||||
free(cdata);
|
||||
return (CMD_RETURN_WAIT);
|
||||
}
|
||||
|
36
external/bsd/tmux/dist/cmd-new-session.c
vendored
36
external/bsd/tmux/dist/cmd-new-session.c
vendored
@ -94,26 +94,31 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (args_has(args, 's')) {
|
||||
newname = format_single(item, args_get(args, 's'), c, NULL,
|
||||
NULL, NULL);
|
||||
tmp = args_get(args, 's');
|
||||
if (tmp != NULL) {
|
||||
newname = format_single(item, tmp, c, NULL, NULL, NULL);
|
||||
if (!session_check_name(newname)) {
|
||||
cmdq_error(item, "bad session name: %s", newname);
|
||||
goto fail;
|
||||
}
|
||||
if ((as = session_find(newname)) != NULL) {
|
||||
if (args_has(args, 'A')) {
|
||||
retval = cmd_attach_session(item,
|
||||
newname, args_has(args, 'D'),
|
||||
args_has(args, 'X'), 0, NULL,
|
||||
args_has(args, 'E'));
|
||||
free(newname);
|
||||
return (retval);
|
||||
}
|
||||
cmdq_error(item, "duplicate session: %s", newname);
|
||||
goto fail;
|
||||
}
|
||||
if (args_has(args, 'A')) {
|
||||
if (newname != NULL)
|
||||
as = session_find(newname);
|
||||
else
|
||||
as = item->target.s;
|
||||
if (as != NULL) {
|
||||
retval = cmd_attach_session(item, as->name,
|
||||
args_has(args, 'D'), args_has(args, 'X'), 0, NULL,
|
||||
args_has(args, 'E'));
|
||||
free(newname);
|
||||
return (retval);
|
||||
}
|
||||
}
|
||||
if (newname != NULL && session_find(newname) != NULL) {
|
||||
cmdq_error(item, "duplicate session: %s", newname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Is this going to be part of a session group? */
|
||||
group = args_get(args, 't');
|
||||
@ -259,6 +264,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
|
||||
memset(&sc, 0, sizeof sc);
|
||||
sc.item = item;
|
||||
sc.s = s;
|
||||
sc.c = c;
|
||||
|
||||
sc.name = args_get(args, 'n');
|
||||
sc.argc = args->argc;
|
||||
@ -328,7 +334,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (args_has(args, 'P')) {
|
||||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = NEW_SESSION_TEMPLATE;
|
||||
cp = format_single(item, template, c, s, NULL, NULL);
|
||||
cp = format_single(item, template, c, s, s->curw, NULL);
|
||||
cmdq_print(item, "%s", cp);
|
||||
free(cp);
|
||||
}
|
||||
|
4
external/bsd/tmux/dist/cmd-new-window.c
vendored
4
external/bsd/tmux/dist/cmd-new-window.c
vendored
@ -72,6 +72,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
memset(&sc, 0, sizeof sc);
|
||||
sc.item = item;
|
||||
sc.s = s;
|
||||
sc.c = c;
|
||||
|
||||
sc.name = args_get(args, 'n');
|
||||
sc.argc = args->argc;
|
||||
@ -107,7 +108,8 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (args_has(args, 'P')) {
|
||||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = NEW_WINDOW_TEMPLATE;
|
||||
cp = format_single(item, template, c, s, new_wl, NULL);
|
||||
cp = format_single(item, template, c, s, new_wl,
|
||||
new_wl->window->active);
|
||||
cmdq_print(item, "%s", cp);
|
||||
free(cp);
|
||||
}
|
||||
|
63
external/bsd/tmux/dist/cmd-parse.y
vendored
63
external/bsd/tmux/dist/cmd-parse.y
vendored
@ -133,7 +133,12 @@ statements : statement '\n'
|
||||
free($2);
|
||||
}
|
||||
|
||||
statement : condition
|
||||
statement : /* empty */
|
||||
{
|
||||
$$ = xmalloc (sizeof *$$);
|
||||
TAILQ_INIT($$);
|
||||
}
|
||||
| condition
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
@ -144,11 +149,6 @@ statement : condition
|
||||
cmd_parse_free_commands($1);
|
||||
}
|
||||
}
|
||||
| assignment
|
||||
{
|
||||
$$ = xmalloc (sizeof *$$);
|
||||
TAILQ_INIT($$);
|
||||
}
|
||||
| commands
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
@ -176,26 +176,28 @@ expanded : format
|
||||
struct cmd_parse_input *pi = ps->input;
|
||||
struct format_tree *ft;
|
||||
struct client *c = pi->c;
|
||||
struct cmd_find_state *fs;
|
||||
struct cmd_find_state *fsp;
|
||||
struct cmd_find_state fs;
|
||||
int flags = FORMAT_NOJOBS;
|
||||
|
||||
if (cmd_find_valid_state(&pi->fs))
|
||||
fs = &pi->fs;
|
||||
else
|
||||
fs = NULL;
|
||||
fsp = &pi->fs;
|
||||
else {
|
||||
cmd_find_from_client(&fs, c, 0);
|
||||
fsp = &fs;
|
||||
}
|
||||
ft = format_create(NULL, pi->item, FORMAT_NONE, flags);
|
||||
if (fs != NULL)
|
||||
format_defaults(ft, c, fs->s, fs->wl, fs->wp);
|
||||
else
|
||||
format_defaults(ft, c, NULL, NULL, NULL);
|
||||
format_defaults(ft, c, fsp->s, fsp->wl, fsp->wp);
|
||||
|
||||
$$ = format_expand(ft, $1);
|
||||
format_free(ft);
|
||||
free($1);
|
||||
}
|
||||
|
||||
assignment : /* empty */
|
||||
| EQUALS
|
||||
optional_assignment : /* empty */
|
||||
| assignment
|
||||
|
||||
assignment : EQUALS
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
int flags = ps->input->flags;
|
||||
@ -339,7 +341,8 @@ commands : command
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
$$ = cmd_parse_new_commands();
|
||||
if (ps->scope == NULL || ps->scope->flag)
|
||||
if ($1->name != NULL &&
|
||||
(ps->scope == NULL || ps->scope->flag))
|
||||
TAILQ_INSERT_TAIL($$, $1, entry);
|
||||
else
|
||||
cmd_parse_free_command($1);
|
||||
@ -358,7 +361,8 @@ commands : command
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
if (ps->scope == NULL || ps->scope->flag) {
|
||||
if ($3->name != NULL &&
|
||||
(ps->scope == NULL || ps->scope->flag)) {
|
||||
$$ = $1;
|
||||
TAILQ_INSERT_TAIL($$, $3, entry);
|
||||
} else {
|
||||
@ -372,7 +376,15 @@ commands : command
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
command : assignment TOKEN
|
||||
command : assignment
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
$$ = xcalloc(1, sizeof *$$);
|
||||
$$->name = NULL;
|
||||
$$->line = ps->input->line;
|
||||
}
|
||||
| optional_assignment TOKEN
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
@ -381,7 +393,7 @@ command : assignment TOKEN
|
||||
$$->line = ps->input->line;
|
||||
|
||||
}
|
||||
| assignment TOKEN arguments
|
||||
| optional_assignment TOKEN arguments
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
@ -696,6 +708,7 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
|
||||
pr.status = CMD_PARSE_ERROR;
|
||||
pr.error = cmd_parse_get_error(pi->file, line, cause);
|
||||
free(cause);
|
||||
cmd_list_free(cmdlist);
|
||||
goto out;
|
||||
}
|
||||
cmd_list_append(cmdlist, add);
|
||||
@ -744,6 +757,12 @@ cmd_parse_from_file(FILE *f, struct cmd_parse_input *pi)
|
||||
|
||||
struct cmd_parse_result *
|
||||
cmd_parse_from_string(const char *s, struct cmd_parse_input *pi)
|
||||
{
|
||||
return (cmd_parse_from_buffer(s, strlen(s), pi));
|
||||
}
|
||||
|
||||
struct cmd_parse_result *
|
||||
cmd_parse_from_buffer(const void *buf, size_t len, struct cmd_parse_input *pi)
|
||||
{
|
||||
static struct cmd_parse_result pr;
|
||||
struct cmd_parse_input input;
|
||||
@ -756,14 +775,14 @@ cmd_parse_from_string(const char *s, struct cmd_parse_input *pi)
|
||||
}
|
||||
memset(&pr, 0, sizeof pr);
|
||||
|
||||
if (*s == '\0') {
|
||||
if (len == 0) {
|
||||
pr.status = CMD_PARSE_EMPTY;
|
||||
pr.cmdlist = NULL;
|
||||
pr.error = NULL;
|
||||
return (&pr);
|
||||
}
|
||||
|
||||
cmds = cmd_parse_do_buffer(s, strlen(s), pi, &cause);
|
||||
cmds = cmd_parse_do_buffer(buf, len, pi, &cause);
|
||||
if (cmds == NULL) {
|
||||
pr.status = CMD_PARSE_ERROR;
|
||||
pr.error = cause;
|
||||
|
55
external/bsd/tmux/dist/cmd-queue.c
vendored
55
external/bsd/tmux/dist/cmd-queue.c
vendored
@ -53,7 +53,7 @@ cmdq_get(struct client *c)
|
||||
}
|
||||
|
||||
/* Append an item. */
|
||||
void
|
||||
struct cmdq_item *
|
||||
cmdq_append(struct client *c, struct cmdq_item *item)
|
||||
{
|
||||
struct cmdq_list *queue = cmdq_get(c);
|
||||
@ -73,10 +73,11 @@ cmdq_append(struct client *c, struct cmdq_item *item)
|
||||
|
||||
item = next;
|
||||
} while (item != NULL);
|
||||
return (TAILQ_LAST(queue, cmdq_list));
|
||||
}
|
||||
|
||||
/* Insert an item. */
|
||||
void
|
||||
struct cmdq_item *
|
||||
cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
|
||||
{
|
||||
struct client *c = after->client;
|
||||
@ -100,9 +101,9 @@ cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
|
||||
after = item;
|
||||
item = next;
|
||||
} while (item != NULL);
|
||||
return (after);
|
||||
}
|
||||
|
||||
|
||||
/* Insert a hook. */
|
||||
void
|
||||
cmdq_insert_hook(struct session *s, struct cmdq_item *item,
|
||||
@ -144,11 +145,10 @@ cmdq_insert_hook(struct session *s, struct cmdq_item *item,
|
||||
|
||||
new_item = cmdq_get_command(cmdlist, fs, NULL, CMDQ_NOHOOKS);
|
||||
cmdq_format(new_item, "hook", "%s", name);
|
||||
if (item != NULL) {
|
||||
cmdq_insert_after(item, new_item);
|
||||
item = new_item;
|
||||
} else
|
||||
cmdq_append(NULL, new_item);
|
||||
if (item != NULL)
|
||||
item = cmdq_insert_after(item, new_item);
|
||||
else
|
||||
item = cmdq_append(NULL, new_item);
|
||||
|
||||
a = options_array_next(a);
|
||||
}
|
||||
@ -476,13 +476,11 @@ void
|
||||
cmdq_guard(struct cmdq_item *item, const char *guard, int flags)
|
||||
{
|
||||
struct client *c = item->client;
|
||||
long t = item->time;
|
||||
u_int number = item->number;
|
||||
|
||||
if (c == NULL || !(c->flags & CLIENT_CONTROL))
|
||||
return;
|
||||
|
||||
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
|
||||
(long)item->time, item->number, flags);
|
||||
server_client_push_stdout(c);
|
||||
if (c != NULL && (c->flags & CLIENT_CONTROL))
|
||||
file_print(c, "%%%s %ld %u %d\n", guard, t, number, flags);
|
||||
}
|
||||
|
||||
/* Show message from command. */
|
||||
@ -496,29 +494,29 @@ cmdq_print(struct cmdq_item *item, const char *fmt, ...)
|
||||
char *tmp, *msg;
|
||||
|
||||
va_start(ap, fmt);
|
||||
xvasprintf(&msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
log_debug("%s: %s", __func__, msg);
|
||||
|
||||
if (c == NULL)
|
||||
/* nothing */;
|
||||
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
|
||||
if (~c->flags & CLIENT_UTF8) {
|
||||
xvasprintf(&tmp, fmt, ap);
|
||||
tmp = msg;
|
||||
msg = utf8_sanitize(tmp);
|
||||
free(tmp);
|
||||
evbuffer_add(c->stdout_data, msg, strlen(msg));
|
||||
free(msg);
|
||||
} else
|
||||
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
|
||||
evbuffer_add(c->stdout_data, "\n", 1);
|
||||
server_client_push_stdout(c);
|
||||
}
|
||||
file_print(c, "%s\n", msg);
|
||||
} else {
|
||||
wp = c->session->curw->window->active;
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme == NULL || wme->mode != &window_view_mode)
|
||||
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
||||
window_copy_vadd(wp, fmt, ap);
|
||||
window_copy_add(wp, "%s", msg);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
/* Show error from command. */
|
||||
@ -529,11 +527,10 @@ cmdq_error(struct cmdq_item *item, const char *fmt, ...)
|
||||
struct cmd *cmd = item->cmd;
|
||||
va_list ap;
|
||||
char *msg;
|
||||
size_t msglen;
|
||||
char *tmp;
|
||||
|
||||
va_start(ap, fmt);
|
||||
msglen = xvasprintf(&msg, fmt, ap);
|
||||
xvasprintf(&msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
log_debug("%s: %s", __func__, msg);
|
||||
@ -545,11 +542,11 @@ cmdq_error(struct cmdq_item *item, const char *fmt, ...)
|
||||
tmp = msg;
|
||||
msg = utf8_sanitize(tmp);
|
||||
free(tmp);
|
||||
msglen = strlen(msg);
|
||||
}
|
||||
evbuffer_add(c->stderr_data, msg, msglen);
|
||||
evbuffer_add(c->stderr_data, "\n", 1);
|
||||
server_client_push_stderr(c);
|
||||
if (c->flags & CLIENT_CONTROL)
|
||||
file_print(c, "%s\n", msg);
|
||||
else
|
||||
file_error(c, "%s\n", msg);
|
||||
c->retval = 1;
|
||||
} else {
|
||||
*msg = toupper((u_char) *msg);
|
||||
|
2
external/bsd/tmux/dist/cmd-resize-window.c
vendored
2
external/bsd/tmux/dist/cmd-resize-window.c
vendored
@ -53,7 +53,7 @@ cmd_resize_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
const char *errstr;
|
||||
char *cause;
|
||||
u_int adjust, sx, sy;
|
||||
int xpixel = -1, ypixel = -1;
|
||||
u_int xpixel = ~0, ypixel = ~0;
|
||||
|
||||
if (args->argc == 0)
|
||||
adjust = 1;
|
||||
|
19
external/bsd/tmux/dist/cmd-send-keys.c
vendored
19
external/bsd/tmux/dist/cmd-send-keys.c
vendored
@ -33,8 +33,9 @@ const struct cmd_entry cmd_send_keys_entry = {
|
||||
.name = "send-keys",
|
||||
.alias = "send",
|
||||
|
||||
.args = { "HlXRMN:t:", 0, -1 },
|
||||
.usage = "[-HlXRM] [-N repeat-count] " CMD_TARGET_PANE_USAGE " key ...",
|
||||
.args = { "FHlMN:Rt:X", 0, -1 },
|
||||
.usage = "[-FHlMRX] [-N repeat-count] " CMD_TARGET_PANE_USAGE
|
||||
" key ...",
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
|
||||
@ -59,6 +60,9 @@ static struct cmdq_item *
|
||||
cmd_send_keys_inject_key(struct client *c, struct cmd_find_state *fs,
|
||||
struct cmdq_item *item, key_code key)
|
||||
{
|
||||
struct session *s = fs->s;
|
||||
struct winlink *wl = fs->wl;
|
||||
struct window_pane *wp = fs->wp;
|
||||
struct window_mode_entry *wme;
|
||||
struct key_table *table;
|
||||
struct key_binding *bd;
|
||||
@ -67,7 +71,8 @@ cmd_send_keys_inject_key(struct client *c, struct cmd_find_state *fs,
|
||||
if (wme == NULL || wme->mode->key_table == NULL) {
|
||||
if (options_get_number(fs->wp->window->options, "xterm-keys"))
|
||||
key |= KEYC_XTERM;
|
||||
window_pane_key(fs->wp, item->client, fs->s, fs->wl, key, NULL);
|
||||
if (window_pane_key(wp, item->client, s, wl, key, NULL) != 0)
|
||||
return (NULL);
|
||||
return (item);
|
||||
}
|
||||
table = key_bindings_get_table(wme->mode->key_table(wme), 1);
|
||||
@ -86,6 +91,7 @@ cmd_send_keys_inject_string(struct client *c, struct cmd_find_state *fs,
|
||||
struct cmdq_item *item, struct args *args, int i)
|
||||
{
|
||||
const char *s = args->argv[i];
|
||||
struct cmdq_item *new_item;
|
||||
struct utf8_data *ud, *uc;
|
||||
wchar_t wc;
|
||||
key_code key;
|
||||
@ -103,8 +109,11 @@ cmd_send_keys_inject_string(struct client *c, struct cmd_find_state *fs,
|
||||
literal = args_has(args, 'l');
|
||||
if (!literal) {
|
||||
key = key_string_lookup_string(s);
|
||||
if (key != KEYC_NONE && key != KEYC_UNKNOWN)
|
||||
return (cmd_send_keys_inject_key(c, fs, item, key));
|
||||
if (key != KEYC_NONE && key != KEYC_UNKNOWN) {
|
||||
new_item = cmd_send_keys_inject_key(c, fs, item, key);
|
||||
if (new_item != NULL)
|
||||
return (new_item);
|
||||
}
|
||||
literal = 1;
|
||||
}
|
||||
if (literal) {
|
||||
|
37
external/bsd/tmux/dist/cmd-split-window.c
vendored
37
external/bsd/tmux/dist/cmd-split-window.c
vendored
@ -41,8 +41,7 @@ const struct cmd_entry cmd_split_window_entry = {
|
||||
|
||||
.args = { "bc:de:fF:hIl:p:Pt:v", 0, -1 },
|
||||
.usage = "[-bdefhIPv] [-c start-directory] [-e environment] "
|
||||
"[-F format] [-p percentage|-l size] " CMD_TARGET_PANE_USAGE
|
||||
" [command]",
|
||||
"[-F format] [-l size] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
|
||||
@ -64,20 +63,37 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct layout_cell *lc;
|
||||
struct cmd_find_state fs;
|
||||
int size, percentage, flags, input;
|
||||
const char *template, *add;
|
||||
char *cause, *cp;
|
||||
const char *template, *add, *errstr, *p;
|
||||
char *cause, *cp, *copy;
|
||||
size_t plen;
|
||||
struct args_value *value;
|
||||
|
||||
if (args_has(args, 'h'))
|
||||
type = LAYOUT_LEFTRIGHT;
|
||||
else
|
||||
type = LAYOUT_TOPBOTTOM;
|
||||
if (args_has(args, 'l')) {
|
||||
size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(item, "create pane failed: -l %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
if ((p = args_get(args, 'l')) != NULL) {
|
||||
plen = strlen(p);
|
||||
if (p[plen - 1] == '%') {
|
||||
copy = xstrdup(p);
|
||||
copy[plen - 1] = '\0';
|
||||
percentage = strtonum(copy, 0, INT_MAX, &errstr);
|
||||
free(copy);
|
||||
if (errstr != NULL) {
|
||||
cmdq_error(item, "percentage %s", errstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
size = (wp->sy * percentage) / 100;
|
||||
else
|
||||
size = (wp->sx * percentage) / 100;
|
||||
} else {
|
||||
size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
|
||||
if (cause != NULL) {
|
||||
cmdq_error(item, "lines %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
} else if (args_has(args, 'p')) {
|
||||
percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
|
||||
@ -137,7 +153,6 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
sc.flags |= SPAWN_DETACHED;
|
||||
|
||||
if ((new_wp = spawn_pane(&sc, &cause)) == NULL) {
|
||||
layout_close_pane(new_wp);
|
||||
cmdq_error(item, "create pane failed: %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
2
external/bsd/tmux/dist/compat.h
vendored
2
external/bsd/tmux/dist/compat.h
vendored
@ -371,6 +371,7 @@ int utf8proc_wctomb(char *, wchar_t);
|
||||
#endif
|
||||
|
||||
/* getopt.c */
|
||||
#ifndef HAVE_BSD_GETOPT
|
||||
extern int BSDopterr;
|
||||
extern int BSDoptind;
|
||||
extern int BSDoptopt;
|
||||
@ -383,5 +384,6 @@ int BSDgetopt(int, char *const *, const char *);
|
||||
#define optopt BSDoptopt
|
||||
#define optreset BSDoptreset
|
||||
#define optarg BSDoptarg
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_H */
|
||||
|
412
external/bsd/tmux/dist/format.c
vendored
412
external/bsd/tmux/dist/format.c
vendored
@ -456,6 +456,35 @@ format_cb_pid(__unused struct format_tree *ft, struct format_entry *fe)
|
||||
xasprintf(&fe->value, "%ld", (long)getpid());
|
||||
}
|
||||
|
||||
/* Callback for session_attached_list. */
|
||||
static void
|
||||
format_cb_session_attached_list(struct format_tree *ft, struct format_entry *fe)
|
||||
{
|
||||
struct session *s = ft->s;
|
||||
struct client *loop;
|
||||
struct evbuffer *buffer;
|
||||
int size;
|
||||
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
buffer = evbuffer_new();
|
||||
if (buffer == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
if (loop->session == s) {
|
||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||
evbuffer_add(buffer, ",", 1);
|
||||
evbuffer_add_printf(buffer, "%s", loop->name);
|
||||
}
|
||||
}
|
||||
|
||||
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
||||
evbuffer_free(buffer);
|
||||
}
|
||||
|
||||
/* Callback for session_alerts. */
|
||||
static void
|
||||
format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe)
|
||||
@ -528,6 +557,128 @@ format_cb_window_stack_index(struct format_tree *ft, struct format_entry *fe)
|
||||
fe->value = xstrdup("0");
|
||||
}
|
||||
|
||||
/* Callback for window_linked_sessions_list. */
|
||||
static void
|
||||
format_cb_window_linked_sessions_list(struct format_tree *ft,
|
||||
struct format_entry *fe)
|
||||
{
|
||||
struct window *w = ft->wl->window;
|
||||
struct winlink *wl;
|
||||
struct evbuffer *buffer;
|
||||
int size;
|
||||
|
||||
buffer = evbuffer_new();
|
||||
if (buffer == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
|
||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||
evbuffer_add(buffer, ",", 1);
|
||||
evbuffer_add_printf(buffer, "%s", wl->session->name);
|
||||
}
|
||||
|
||||
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
||||
evbuffer_free(buffer);
|
||||
}
|
||||
|
||||
/* Callback for window_active_sessions. */
|
||||
static void
|
||||
format_cb_window_active_sessions(struct format_tree *ft,
|
||||
struct format_entry *fe)
|
||||
{
|
||||
struct window *w = ft->wl->window;
|
||||
struct winlink *wl;
|
||||
u_int n = 0;
|
||||
|
||||
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
|
||||
if (wl->session->curw == wl)
|
||||
n++;
|
||||
}
|
||||
|
||||
xasprintf(&fe->value, "%u", n);
|
||||
}
|
||||
|
||||
/* Callback for window_active_sessions_list. */
|
||||
static void
|
||||
format_cb_window_active_sessions_list(struct format_tree *ft,
|
||||
struct format_entry *fe)
|
||||
{
|
||||
struct window *w = ft->wl->window;
|
||||
struct winlink *wl;
|
||||
struct evbuffer *buffer;
|
||||
int size;
|
||||
|
||||
buffer = evbuffer_new();
|
||||
if (buffer == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
|
||||
if (wl->session->curw == wl) {
|
||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||
evbuffer_add(buffer, ",", 1);
|
||||
evbuffer_add_printf(buffer, "%s", wl->session->name);
|
||||
}
|
||||
}
|
||||
|
||||
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
||||
evbuffer_free(buffer);
|
||||
}
|
||||
|
||||
/* Callback for window_active_clients. */
|
||||
static void
|
||||
format_cb_window_active_clients(struct format_tree *ft, struct format_entry *fe)
|
||||
{
|
||||
struct window *w = ft->wl->window;
|
||||
struct client *loop;
|
||||
struct session *client_session;
|
||||
u_int n = 0;
|
||||
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
client_session = loop->session;
|
||||
if (client_session == NULL)
|
||||
continue;
|
||||
|
||||
if (w == client_session->curw->window)
|
||||
n++;
|
||||
}
|
||||
|
||||
xasprintf(&fe->value, "%u", n);
|
||||
}
|
||||
|
||||
/* Callback for window_active_clients_list. */
|
||||
static void
|
||||
format_cb_window_active_clients_list(struct format_tree *ft,
|
||||
struct format_entry *fe)
|
||||
{
|
||||
struct window *w = ft->wl->window;
|
||||
struct client *loop;
|
||||
struct session *client_session;
|
||||
struct evbuffer *buffer;
|
||||
int size;
|
||||
|
||||
buffer = evbuffer_new();
|
||||
if (buffer == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
client_session = loop->session;
|
||||
if (client_session == NULL)
|
||||
continue;
|
||||
|
||||
if (w == client_session->curw->window) {
|
||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||
evbuffer_add(buffer, ",", 1);
|
||||
evbuffer_add_printf(buffer, "%s", loop->name);
|
||||
}
|
||||
}
|
||||
|
||||
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
||||
evbuffer_free(buffer);
|
||||
}
|
||||
|
||||
/* Callback for window_layout. */
|
||||
static void
|
||||
format_cb_window_layout(struct format_tree *ft, struct format_entry *fe)
|
||||
@ -574,7 +725,7 @@ format_cb_current_command(struct format_tree *ft, struct format_entry *fe)
|
||||
struct window_pane *wp = ft->wp;
|
||||
char *cmd;
|
||||
|
||||
if (wp == NULL)
|
||||
if (wp == NULL || wp->shell == NULL)
|
||||
return;
|
||||
|
||||
cmd = osdep_get_name(wp->fd, wp->tty);
|
||||
@ -677,11 +828,52 @@ format_cb_session_group_list(struct format_tree *ft, struct format_entry *fe)
|
||||
buffer = evbuffer_new();
|
||||
if (buffer == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
TAILQ_FOREACH(loop, &sg->sessions, gentry) {
|
||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||
evbuffer_add(buffer, ",", 1);
|
||||
evbuffer_add_printf(buffer, "%s", loop->name);
|
||||
}
|
||||
|
||||
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
||||
evbuffer_free(buffer);
|
||||
}
|
||||
|
||||
/* Callback for session_group_attached_list. */
|
||||
static void
|
||||
format_cb_session_group_attached_list(struct format_tree *ft,
|
||||
struct format_entry *fe)
|
||||
{
|
||||
struct session *s = ft->s, *client_session, *session_loop;
|
||||
struct session_group *sg;
|
||||
struct client *loop;
|
||||
struct evbuffer *buffer;
|
||||
int size;
|
||||
|
||||
if (s == NULL)
|
||||
return;
|
||||
sg = session_group_contains(s);
|
||||
if (sg == NULL)
|
||||
return;
|
||||
|
||||
buffer = evbuffer_new();
|
||||
if (buffer == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
TAILQ_FOREACH(loop, &clients, entry) {
|
||||
client_session = loop->session;
|
||||
if (client_session == NULL)
|
||||
continue;
|
||||
TAILQ_FOREACH(session_loop, &sg->sessions, gentry) {
|
||||
if (session_loop == client_session){
|
||||
if (EVBUFFER_LENGTH(buffer) > 0)
|
||||
evbuffer_add(buffer, ",", 1);
|
||||
evbuffer_add_printf(buffer, "%s", loop->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((size = EVBUFFER_LENGTH(buffer)) != 0)
|
||||
xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer));
|
||||
evbuffer_free(buffer);
|
||||
@ -703,6 +895,44 @@ format_cb_pane_in_mode(struct format_tree *ft, struct format_entry *fe)
|
||||
xasprintf(&fe->value, "%u", n);
|
||||
}
|
||||
|
||||
/* Callback for pane_at_top. */
|
||||
static void
|
||||
format_cb_pane_at_top(struct format_tree *ft, struct format_entry *fe)
|
||||
{
|
||||
struct window_pane *wp = ft->wp;
|
||||
struct window *w = wp->window;
|
||||
int status, flag;
|
||||
|
||||
if (wp == NULL)
|
||||
return;
|
||||
|
||||
status = options_get_number(w->options, "pane-border-status");
|
||||
if (status == PANE_STATUS_TOP)
|
||||
flag = (wp->yoff == 1);
|
||||
else
|
||||
flag = (wp->yoff == 0);
|
||||
xasprintf(&fe->value, "%d", flag);
|
||||
}
|
||||
|
||||
/* Callback for pane_at_bottom. */
|
||||
static void
|
||||
format_cb_pane_at_bottom(struct format_tree *ft, struct format_entry *fe)
|
||||
{
|
||||
struct window_pane *wp = ft->wp;
|
||||
struct window *w = wp->window;
|
||||
int status, flag;
|
||||
|
||||
if (wp == NULL)
|
||||
return;
|
||||
|
||||
status = options_get_number(w->options, "pane-border-status");
|
||||
if (status == PANE_STATUS_BOTTOM)
|
||||
flag = (wp->yoff + wp->sy == w->sy - 1);
|
||||
else
|
||||
flag = (wp->yoff + wp->sy == w->sy);
|
||||
xasprintf(&fe->value, "%d", flag);
|
||||
}
|
||||
|
||||
/* Callback for cursor_character. */
|
||||
static void
|
||||
format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe)
|
||||
@ -718,30 +948,19 @@ format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe)
|
||||
xasprintf(&fe->value, "%.*s", (int)gc.data.size, gc.data.data);
|
||||
}
|
||||
|
||||
/* Callback for mouse_word. */
|
||||
static void
|
||||
format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe)
|
||||
/* Return word at given coordinates. Caller frees. */
|
||||
char *
|
||||
format_grid_word(struct grid *gd, u_int x, u_int y)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
u_int x, y, end;
|
||||
struct grid *gd;
|
||||
struct grid_line *gl;
|
||||
struct grid_cell gc;
|
||||
const char *ws;
|
||||
struct utf8_data *ud = NULL;
|
||||
u_int end;
|
||||
size_t size = 0;
|
||||
int found = 0;
|
||||
char *s = NULL;
|
||||
|
||||
if (!ft->m.valid)
|
||||
return;
|
||||
wp = cmd_mouse_pane(&ft->m, NULL, NULL);
|
||||
if (wp == NULL)
|
||||
return;
|
||||
if (!TAILQ_EMPTY (&wp->modes))
|
||||
return;
|
||||
if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
|
||||
return;
|
||||
gd = wp->base.grid;
|
||||
ws = options_get_string(global_s_options, "word-separators");
|
||||
|
||||
y = gd->hsize + y;
|
||||
@ -794,21 +1013,19 @@ format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe)
|
||||
}
|
||||
if (size != 0) {
|
||||
ud[size].size = 0;
|
||||
fe->value = utf8_tocstr(ud);
|
||||
s = utf8_tocstr(ud);
|
||||
free(ud);
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Callback for mouse_line. */
|
||||
/* Callback for mouse_word. */
|
||||
static void
|
||||
format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe)
|
||||
format_cb_mouse_word(struct format_tree *ft, struct format_entry *fe)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
u_int x, y;
|
||||
struct grid *gd;
|
||||
struct grid_cell gc;
|
||||
struct utf8_data *ud = NULL;
|
||||
size_t size = 0;
|
||||
char *s;
|
||||
|
||||
if (!ft->m.valid)
|
||||
return;
|
||||
@ -819,7 +1036,21 @@ format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe)
|
||||
return;
|
||||
if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
|
||||
return;
|
||||
gd = wp->base.grid;
|
||||
|
||||
s = format_grid_word(wp->base.grid, x, y);
|
||||
if (s != NULL)
|
||||
fe->value = s;
|
||||
}
|
||||
|
||||
/* Return line at given coordinates. Caller frees. */
|
||||
char *
|
||||
format_grid_line(struct grid *gd, u_int y)
|
||||
{
|
||||
struct grid_cell gc;
|
||||
struct utf8_data *ud = NULL;
|
||||
u_int x;
|
||||
size_t size = 0;
|
||||
char *s = NULL;
|
||||
|
||||
y = gd->hsize + y;
|
||||
for (x = 0; x < grid_line_length(gd, y); x++) {
|
||||
@ -832,9 +1063,33 @@ format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe)
|
||||
}
|
||||
if (size != 0) {
|
||||
ud[size].size = 0;
|
||||
fe->value = utf8_tocstr(ud);
|
||||
s = utf8_tocstr(ud);
|
||||
free(ud);
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Callback for mouse_line. */
|
||||
static void
|
||||
format_cb_mouse_line(struct format_tree *ft, struct format_entry *fe)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
u_int x, y;
|
||||
char *s;
|
||||
|
||||
if (!ft->m.valid)
|
||||
return;
|
||||
wp = cmd_mouse_pane(&ft->m, NULL, NULL);
|
||||
if (wp == NULL)
|
||||
return;
|
||||
if (!TAILQ_EMPTY (&wp->modes))
|
||||
return;
|
||||
if (cmd_mouse_at(wp, &ft->m, &x, &y, 0) != 0)
|
||||
return;
|
||||
|
||||
s = format_grid_line(wp->base.grid, y);
|
||||
if (s != NULL)
|
||||
fe->value = s;
|
||||
}
|
||||
|
||||
/* Merge a format tree. */
|
||||
@ -904,7 +1159,7 @@ format_create(struct client *c, struct cmdq_item *item, int tag, int flags)
|
||||
ft->flags = flags;
|
||||
ft->time = time(NULL);
|
||||
|
||||
format_add(ft, "version", "%s", VERSION);
|
||||
format_add(ft, "version", "%s", getversion());
|
||||
format_add_cb(ft, "host", format_cb_host);
|
||||
format_add_cb(ft, "host_short", format_cb_host_short);
|
||||
format_add_cb(ft, "pid", format_cb_pid);
|
||||
@ -949,12 +1204,12 @@ format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
|
||||
void *), void *arg)
|
||||
{
|
||||
struct format_entry *fe;
|
||||
static char s[64];
|
||||
char s[64];
|
||||
|
||||
RB_FOREACH(fe, format_entry_tree, &ft->tree) {
|
||||
if (fe->t != 0) {
|
||||
xsnprintf(s, sizeof s, "%lld", (long long)fe->t);
|
||||
cb(fe->key, fe->value, s);
|
||||
cb(fe->key, s, arg);
|
||||
} else {
|
||||
if (fe->value == NULL && fe->cb != NULL) {
|
||||
fe->cb(ft, fe);
|
||||
@ -966,7 +1221,6 @@ format_each(struct format_tree *ft, void (*cb)(const char *, const char *,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add a key-value pair. */
|
||||
void
|
||||
format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
|
||||
@ -998,8 +1252,7 @@ format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
|
||||
static void
|
||||
format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
|
||||
{
|
||||
struct format_entry *fe;
|
||||
struct format_entry *fe_now;
|
||||
struct format_entry *fe, *fe_now;
|
||||
|
||||
fe = xmalloc(sizeof *fe);
|
||||
fe->key = xstrdup(key);
|
||||
@ -1290,7 +1543,7 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count)
|
||||
}
|
||||
|
||||
/* Now try single character with arguments. */
|
||||
if (strchr("mCs=", cp[0]) == NULL)
|
||||
if (strchr("mCs=p", cp[0]) == NULL)
|
||||
break;
|
||||
c = cp[0];
|
||||
|
||||
@ -1551,15 +1804,15 @@ static int
|
||||
format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
||||
char **buf, size_t *len, size_t *off)
|
||||
{
|
||||
struct window_pane *wp = ft->wp;
|
||||
const char *errptr, *copy, *cp, *marker = NULL;
|
||||
char *copy0, *condition, *found, *new;
|
||||
char *value, *left, *right;
|
||||
size_t valuelen;
|
||||
int modifiers = 0, limit = 0, j;
|
||||
struct format_modifier *list, *fm, *cmp = NULL, *search = NULL;
|
||||
struct format_modifier *sub = NULL;
|
||||
u_int i, count;
|
||||
struct window_pane *wp = ft->wp;
|
||||
const char *errptr, *copy, *cp, *marker = NULL;
|
||||
char *copy0, *condition, *found, *new;
|
||||
char *value, *left, *right;
|
||||
size_t valuelen;
|
||||
int modifiers = 0, limit = 0, width = 0, j;
|
||||
struct format_modifier *list, *fm, *cmp = NULL, *search = NULL;
|
||||
struct format_modifier **sub = NULL;
|
||||
u_int i, count, nsub = 0;
|
||||
|
||||
/* Make a copy of the key. */
|
||||
copy = copy0 = xstrndup(key, keylen);
|
||||
@ -1588,7 +1841,9 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
||||
case 's':
|
||||
if (fm->argc < 2)
|
||||
break;
|
||||
sub = fm;
|
||||
sub = xreallocarray (sub, nsub + 1,
|
||||
sizeof *sub);
|
||||
sub[nsub++] = fm;
|
||||
break;
|
||||
case '=':
|
||||
if (fm->argc < 1)
|
||||
@ -1600,6 +1855,14 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
|
||||
if (fm->argc >= 2 && fm->argv[1] != NULL)
|
||||
marker = fm->argv[1];
|
||||
break;
|
||||
case 'p':
|
||||
if (fm->argc < 1)
|
||||
break;
|
||||
width = strtonum(fm->argv[0], INT_MIN, INT_MAX,
|
||||
&errptr);
|
||||
if (errptr != NULL)
|
||||
width = 0;
|
||||
break;
|
||||
case 'l':
|
||||
modifiers |= FORMAT_LITERAL;
|
||||
break;
|
||||
@ -1800,10 +2063,10 @@ done:
|
||||
}
|
||||
|
||||
/* Perform substitution if any. */
|
||||
if (sub != NULL) {
|
||||
left = format_expand(ft, sub->argv[0]);
|
||||
right = format_expand(ft, sub->argv[1]);
|
||||
new = format_sub(sub, value, left, right);
|
||||
for (i = 0; i < nsub; i++) {
|
||||
left = format_expand(ft, sub[i]->argv[0]);
|
||||
right = format_expand(ft, sub[i]->argv[1]);
|
||||
new = format_sub(sub[i], value, left, right);
|
||||
format_log(ft, "substitute '%s' to '%s': %s", left, right, new);
|
||||
free(value);
|
||||
value = new;
|
||||
@ -1834,6 +2097,19 @@ done:
|
||||
format_log(ft, "applied length limit %d: %s", limit, value);
|
||||
}
|
||||
|
||||
/* Pad the value if needed. */
|
||||
if (width > 0) {
|
||||
new = utf8_padcstr(value, width);
|
||||
free(value);
|
||||
value = new;
|
||||
format_log(ft, "applied padding width %d: %s", width, value);
|
||||
} else if (width < 0) {
|
||||
new = utf8_rpadcstr(value, -width);
|
||||
free(value);
|
||||
value = new;
|
||||
format_log(ft, "applied padding width %d: %s", width, value);
|
||||
}
|
||||
|
||||
/* Expand the buffer and copy in the value. */
|
||||
valuelen = strlen(value);
|
||||
while (*len - *off < valuelen + 1) {
|
||||
@ -1846,12 +2122,15 @@ done:
|
||||
format_log(ft, "replaced '%s' with '%s'", copy0, value);
|
||||
free(value);
|
||||
|
||||
free(sub);
|
||||
format_free_modifiers(list, count);
|
||||
free(copy0);
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
format_log(ft, "failed %s", copy0);
|
||||
|
||||
free(sub);
|
||||
format_free_modifiers(list, count);
|
||||
free(copy0);
|
||||
return (-1);
|
||||
@ -2091,8 +2370,14 @@ format_defaults_session(struct format_tree *ft, struct session *s)
|
||||
format_add(ft, "session_group", "%s", sg->name);
|
||||
format_add(ft, "session_group_size", "%u",
|
||||
session_group_count (sg));
|
||||
format_add(ft, "session_group_attached", "%u",
|
||||
session_group_attached_count (sg));
|
||||
format_add(ft, "session_group_many_attached", "%u",
|
||||
session_group_attached_count (sg) > 1);
|
||||
format_add_cb(ft, "session_group_list",
|
||||
format_cb_session_group_list);
|
||||
format_add_cb(ft, "session_group_attached_list",
|
||||
format_cb_session_group_attached_list);
|
||||
}
|
||||
|
||||
format_add_tv(ft, "session_created", &s->creation_time);
|
||||
@ -2101,6 +2386,8 @@ format_defaults_session(struct format_tree *ft, struct session *s)
|
||||
|
||||
format_add(ft, "session_attached", "%u", s->attached);
|
||||
format_add(ft, "session_many_attached", "%d", s->attached > 1);
|
||||
format_add_cb(ft, "session_attached_list",
|
||||
format_cb_session_attached_list);
|
||||
|
||||
format_add_cb(ft, "session_alerts", format_cb_session_alerts);
|
||||
format_add_cb(ft, "session_stack", format_cb_session_stack);
|
||||
@ -2113,7 +2400,6 @@ format_defaults_client(struct format_tree *ft, struct client *c)
|
||||
struct session *s;
|
||||
const char *name;
|
||||
struct tty *tty = &c->tty;
|
||||
const char *types[] = TTY_TYPES;
|
||||
|
||||
if (ft->s == NULL)
|
||||
ft->s = c->session;
|
||||
@ -2123,14 +2409,14 @@ format_defaults_client(struct format_tree *ft, struct client *c)
|
||||
format_add(ft, "client_pid", "%ld", (long) c->pid);
|
||||
format_add(ft, "client_height", "%u", tty->sy);
|
||||
format_add(ft, "client_width", "%u", tty->sx);
|
||||
format_add(ft, "client_cell_width", "%u", tty->xpixel);
|
||||
format_add(ft, "client_cell_height", "%u", tty->ypixel);
|
||||
format_add(ft, "client_tty", "%s", c->ttyname);
|
||||
format_add(ft, "client_control_mode", "%d",
|
||||
!!(c->flags & CLIENT_CONTROL));
|
||||
|
||||
if (tty->term_name != NULL)
|
||||
format_add(ft, "client_termname", "%s", tty->term_name);
|
||||
if (tty->term_name != NULL)
|
||||
format_add(ft, "client_termtype", "%s", types[tty->term_type]);
|
||||
|
||||
format_add_tv(ft, "client_created", &c->creation_time);
|
||||
format_add_tv(ft, "client_activity", &c->activity_time);
|
||||
@ -2174,6 +2460,8 @@ format_defaults_window(struct format_tree *ft, struct window *w)
|
||||
format_add(ft, "window_name", "%s", w->name);
|
||||
format_add(ft, "window_width", "%u", w->sx);
|
||||
format_add(ft, "window_height", "%u", w->sy);
|
||||
format_add(ft, "window_cell_width", "%u", w->xpixel);
|
||||
format_add(ft, "window_cell_height", "%u", w->ypixel);
|
||||
format_add_cb(ft, "window_layout", format_cb_window_layout);
|
||||
format_add_cb(ft, "window_visible_layout",
|
||||
format_cb_window_visible_layout);
|
||||
@ -2211,12 +2499,25 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
|
||||
format_add_cb(ft, "window_stack_index", format_cb_window_stack_index);
|
||||
format_add(ft, "window_flags", "%s", window_printable_flags(wl));
|
||||
format_add(ft, "window_active", "%d", wl == s->curw);
|
||||
format_add_cb(ft, "window_active_sessions",
|
||||
format_cb_window_active_sessions);
|
||||
format_add_cb(ft, "window_active_sessions_list",
|
||||
format_cb_window_active_sessions_list);
|
||||
format_add_cb(ft, "window_active_clients",
|
||||
format_cb_window_active_clients);
|
||||
format_add_cb(ft, "window_active_clients_list",
|
||||
format_cb_window_active_clients_list);
|
||||
|
||||
format_add(ft, "window_start_flag", "%d",
|
||||
!!(wl == RB_MIN(winlinks, &s->windows)));
|
||||
format_add(ft, "window_end_flag", "%d",
|
||||
!!(wl == RB_MAX(winlinks, &s->windows)));
|
||||
|
||||
if (server_check_marked() && marked_pane.wl == wl)
|
||||
format_add(ft, "window_marked_flag", "1");
|
||||
else
|
||||
format_add(ft, "window_marked_flag", "0");
|
||||
|
||||
format_add(ft, "window_bell_flag", "%d",
|
||||
!!(wl->flags & WINLINK_BELL));
|
||||
format_add(ft, "window_activity_flag", "%d",
|
||||
@ -2226,6 +2527,11 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
|
||||
format_add(ft, "window_last_flag", "%d",
|
||||
!!(wl == TAILQ_FIRST(&s->lastw)));
|
||||
format_add(ft, "window_linked", "%d", session_is_linked(s, wl->window));
|
||||
|
||||
format_add_cb(ft, "window_linked_sessions_list",
|
||||
format_cb_window_linked_sessions_list);
|
||||
format_add(ft, "window_linked_sessions", "%u",
|
||||
wl->window->references);
|
||||
}
|
||||
|
||||
/* Set default format keys for a window pane. */
|
||||
@ -2253,6 +2559,8 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
|
||||
format_add(ft, "pane_width", "%u", wp->sx);
|
||||
format_add(ft, "pane_height", "%u", wp->sy);
|
||||
format_add(ft, "pane_title", "%s", wp->base.title);
|
||||
if (wp->base.path != NULL)
|
||||
format_add(ft, "pane_path", "%s", wp->base.path);
|
||||
format_add(ft, "pane_id", "%%%u", wp->id);
|
||||
format_add(ft, "pane_active", "%d", wp == w->active);
|
||||
format_add(ft, "pane_input_off", "%d", !!(wp->flags & PANE_INPUTOFF));
|
||||
@ -2276,9 +2584,9 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
|
||||
format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1);
|
||||
format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1);
|
||||
format_add(ft, "pane_at_left", "%d", wp->xoff == 0);
|
||||
format_add(ft, "pane_at_top", "%d", wp->yoff == 0);
|
||||
format_add_cb(ft, "pane_at_top", format_cb_pane_at_top);
|
||||
format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == w->sx);
|
||||
format_add(ft, "pane_at_bottom", "%d", wp->yoff + wp->sy == w->sy);
|
||||
format_add_cb(ft, "pane_at_bottom", format_cb_pane_at_bottom);
|
||||
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme != NULL) {
|
||||
|
24
external/bsd/tmux/dist/grid.c
vendored
24
external/bsd/tmux/dist/grid.c
vendored
@ -186,23 +186,25 @@ grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg)
|
||||
struct grid_cell *gc;
|
||||
|
||||
memcpy(gce, &grid_cleared_entry, sizeof *gce);
|
||||
if (bg & COLOUR_FLAG_RGB) {
|
||||
grid_get_extended_cell(gl, gce, gce->flags);
|
||||
gl->flags |= GRID_LINE_EXTENDED;
|
||||
if (bg != 8) {
|
||||
if (bg & COLOUR_FLAG_RGB) {
|
||||
grid_get_extended_cell(gl, gce, gce->flags);
|
||||
gl->flags |= GRID_LINE_EXTENDED;
|
||||
|
||||
gc = &gl->extddata[gce->offset];
|
||||
memcpy(gc, &grid_cleared_cell, sizeof *gc);
|
||||
gc->bg = bg;
|
||||
} else {
|
||||
if (bg & COLOUR_FLAG_256)
|
||||
gce->flags |= GRID_FLAG_BG256;
|
||||
gce->data.bg = bg;
|
||||
gc = &gl->extddata[gce->offset];
|
||||
memcpy(gc, &grid_cleared_cell, sizeof *gc);
|
||||
gc->bg = bg;
|
||||
} else {
|
||||
if (bg & COLOUR_FLAG_256)
|
||||
gce->flags |= GRID_FLAG_BG256;
|
||||
gce->data.bg = bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check grid y position. */
|
||||
static int
|
||||
grid_check_y(struct grid *gd, const char* from, u_int py)
|
||||
grid_check_y(struct grid *gd, const char *from, u_int py)
|
||||
{
|
||||
if (py >= gd->hsize + gd->sy) {
|
||||
log_debug("%s: y out of range: %u", from, py);
|
||||
|
30
external/bsd/tmux/dist/input-keys.c
vendored
30
external/bsd/tmux/dist/input-keys.c
vendored
@ -42,9 +42,6 @@ struct input_key_ent {
|
||||
};
|
||||
|
||||
static const struct input_key_ent input_keys[] = {
|
||||
/* Backspace key. */
|
||||
{ KEYC_BSPACE, "\177", 0 },
|
||||
|
||||
/* Paste keys. */
|
||||
{ KEYC_PASTE_START, "\033[200~", 0 },
|
||||
{ KEYC_PASTE_END, "\033[201~", 0 },
|
||||
@ -152,14 +149,14 @@ input_split2(u_int c, u_char *dst)
|
||||
}
|
||||
|
||||
/* Translate a key code into an output key sequence. */
|
||||
void
|
||||
int
|
||||
input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
|
||||
{
|
||||
const struct input_key_ent *ike;
|
||||
u_int i;
|
||||
size_t dlen;
|
||||
char *out;
|
||||
key_code justkey;
|
||||
key_code justkey, newkey;
|
||||
struct utf8_data ud;
|
||||
|
||||
log_debug("writing key 0x%llx (%s) to %%%u", key,
|
||||
@ -169,14 +166,22 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
|
||||
if (KEYC_IS_MOUSE(key)) {
|
||||
if (m != NULL && m->wp != -1 && (u_int)m->wp == wp->id)
|
||||
input_key_mouse(wp, m);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Literal keys go as themselves (can't be more than eight bits). */
|
||||
if (key & KEYC_LITERAL) {
|
||||
ud.data[0] = (u_char)key;
|
||||
bufferevent_write(wp->event, &ud.data[0], 1);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Is this backspace? */
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) {
|
||||
newkey = options_get_number(global_options, "backspace");
|
||||
if (newkey >= 0x7f)
|
||||
newkey = '\177';
|
||||
key = newkey|(key & KEYC_MASK_MOD);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -189,15 +194,15 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
|
||||
bufferevent_write(wp->event, "\033", 1);
|
||||
ud.data[0] = justkey;
|
||||
bufferevent_write(wp->event, &ud.data[0], 1);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
if (justkey > 0x7f && justkey < KEYC_BASE) {
|
||||
if (utf8_split(justkey, &ud) != UTF8_DONE)
|
||||
return;
|
||||
return (-1);
|
||||
if (key & KEYC_ESCAPE)
|
||||
bufferevent_write(wp->event, "\033", 1);
|
||||
bufferevent_write(wp->event, ud.data, ud.size);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -208,7 +213,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
|
||||
if ((out = xterm_keys_lookup(key)) != NULL) {
|
||||
bufferevent_write(wp->event, out, strlen(out));
|
||||
free(out);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
key &= ~KEYC_XTERM;
|
||||
@ -231,7 +236,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
|
||||
}
|
||||
if (i == nitems(input_keys)) {
|
||||
log_debug("key 0x%llx missing", key);
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
dlen = strlen(ike->data);
|
||||
log_debug("found key 0x%llx: \"%s\"", key, ike->data);
|
||||
@ -240,6 +245,7 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m)
|
||||
if (key & KEYC_ESCAPE)
|
||||
bufferevent_write(wp->event, "\033", 1);
|
||||
bufferevent_write(wp->event, ike->data, dlen);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Translate mouse and output. */
|
||||
|
137
external/bsd/tmux/dist/input.c
vendored
137
external/bsd/tmux/dist/input.c
vendored
@ -20,6 +20,7 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -740,7 +741,7 @@ input_timer_callback(__unused int fd, __unused short events, void *arg)
|
||||
static void
|
||||
input_start_timer(struct input_ctx *ictx)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 100000 };
|
||||
struct timeval tv = { .tv_sec = 5, .tv_usec = 0 };
|
||||
|
||||
event_del(&ictx->timer);
|
||||
event_add(&ictx->timer, &tv);
|
||||
@ -772,6 +773,7 @@ input_save_state(struct input_ctx *ictx)
|
||||
ictx->old_mode = s->mode;
|
||||
}
|
||||
|
||||
/* Restore screen state. */
|
||||
static void
|
||||
input_restore_state(struct input_ctx *ictx)
|
||||
{
|
||||
@ -876,7 +878,7 @@ input_set_state(struct window_pane *wp, const struct input_transition *itr)
|
||||
void
|
||||
input_parse(struct window_pane *wp)
|
||||
{
|
||||
struct evbuffer *evb = wp->event->input;
|
||||
struct evbuffer *evb = wp->event->input;
|
||||
|
||||
input_parse_buffer(wp, EVBUFFER_DATA(evb), EVBUFFER_LENGTH(evb));
|
||||
evbuffer_drain(evb, EVBUFFER_LENGTH(evb));
|
||||
@ -888,7 +890,8 @@ input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
|
||||
{
|
||||
struct input_ctx *ictx = wp->ictx;
|
||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||
const struct input_transition *itr;
|
||||
const struct input_state *state = NULL;
|
||||
const struct input_transition *itr = NULL;
|
||||
size_t off = 0;
|
||||
|
||||
if (len == 0)
|
||||
@ -916,16 +919,23 @@ input_parse_buffer(struct window_pane *wp, u_char *buf, size_t len)
|
||||
ictx->ch = buf[off++];
|
||||
|
||||
/* Find the transition. */
|
||||
itr = ictx->state->transitions;
|
||||
while (itr->first != -1 && itr->last != -1) {
|
||||
if (ictx->ch >= itr->first && ictx->ch <= itr->last)
|
||||
break;
|
||||
itr++;
|
||||
}
|
||||
if (itr->first == -1 || itr->last == -1) {
|
||||
/* No transition? Eh? */
|
||||
fatalx("no transition from state");
|
||||
if (ictx->state != state ||
|
||||
itr == NULL ||
|
||||
ictx->ch < itr->first ||
|
||||
ictx->ch > itr->last) {
|
||||
itr = ictx->state->transitions;
|
||||
while (itr->first != -1 && itr->last != -1) {
|
||||
if (ictx->ch >= itr->first &&
|
||||
ictx->ch <= itr->last)
|
||||
break;
|
||||
itr++;
|
||||
}
|
||||
if (itr->first == -1 || itr->last == -1) {
|
||||
/* No transition? Eh? */
|
||||
fatalx("no transition from state");
|
||||
}
|
||||
}
|
||||
state = ictx->state;
|
||||
|
||||
/*
|
||||
* Any state except print stops the current collection. This is
|
||||
@ -1293,6 +1303,7 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
struct input_table_entry *entry;
|
||||
int i, n, m;
|
||||
u_int cx, bg = ictx->cell.cell.bg;
|
||||
char *copy, *cp;
|
||||
|
||||
if (ictx->flags & INPUT_DISCARD)
|
||||
return (0);
|
||||
@ -1424,6 +1435,13 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
case 6:
|
||||
input_reply(ictx, "\033[%u;%uR", s->cy + 1, s->cx + 1);
|
||||
break;
|
||||
case 1337: /* Terminal version, from iTerm2. */
|
||||
copy = xstrdup(getversion());
|
||||
for (cp = copy; *cp != '\0'; cp++)
|
||||
*cp = toupper((u_char)*cp);
|
||||
input_reply(ictx, "\033[TMUX %sn", copy);
|
||||
free(copy);
|
||||
break;
|
||||
default:
|
||||
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
||||
break;
|
||||
@ -1911,8 +1929,13 @@ input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i)
|
||||
free(copy);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
n++;
|
||||
if (n == nitems(p)) {
|
||||
free(copy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
log_debug("%s: %u = %d", __func__, n - 1, p[n - 1]);
|
||||
}
|
||||
free(copy);
|
||||
@ -2195,14 +2218,18 @@ input_exit_osc(struct input_ctx *ictx)
|
||||
switch (option) {
|
||||
case 0:
|
||||
case 2:
|
||||
if (utf8_isvalid(p)) {
|
||||
screen_set_title(sctx->s, p);
|
||||
if (screen_set_title(sctx->s, p))
|
||||
server_status_window(ictx->wp->window);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
input_osc_4(ictx, p);
|
||||
break;
|
||||
case 7:
|
||||
if (utf8_isvalid(p)) {
|
||||
screen_set_path(sctx->s, p);
|
||||
server_status_window(ictx->wp->window);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
input_osc_10(ictx, p);
|
||||
break;
|
||||
@ -2251,10 +2278,8 @@ input_exit_apc(struct input_ctx *ictx)
|
||||
return;
|
||||
log_debug("%s: \"%s\"", __func__, p);
|
||||
|
||||
if (!utf8_isvalid(p))
|
||||
return;
|
||||
screen_set_title(sctx->s, p);
|
||||
server_status_window(ictx->wp->window);
|
||||
if (screen_set_title(sctx->s, p))
|
||||
server_status_window(ictx->wp->window);
|
||||
}
|
||||
|
||||
/* Rename string started. */
|
||||
@ -2272,7 +2297,10 @@ input_enter_rename(struct input_ctx *ictx)
|
||||
static void
|
||||
input_exit_rename(struct input_ctx *ictx)
|
||||
{
|
||||
struct window_pane *wp = ictx->wp;
|
||||
struct options_entry *oe;
|
||||
char *p = (char *)ictx->input_buf;
|
||||
|
||||
if (ictx->flags & INPUT_DISCARD)
|
||||
return;
|
||||
if (!options_get_number(ictx->wp->options, "allow-rename"))
|
||||
@ -2281,6 +2309,13 @@ input_exit_rename(struct input_ctx *ictx)
|
||||
|
||||
if (!utf8_isvalid(p))
|
||||
return;
|
||||
|
||||
if (ictx->input_len == 0) {
|
||||
oe = options_get_only(wp->window->options, "automatic-rename");
|
||||
if (oe != NULL)
|
||||
options_remove(oe);
|
||||
return;
|
||||
}
|
||||
window_set_name(ictx->wp->window, p);
|
||||
options_set_number(ictx->wp->window->options, "automatic-rename", 0);
|
||||
server_status_window(ictx->wp->window);
|
||||
@ -2322,6 +2357,54 @@ input_top_bit_set(struct input_ctx *ictx)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Parse colour from OSC. */
|
||||
static int
|
||||
input_osc_parse_colour(const char *p, u_int *r, u_int *g, u_int *b)
|
||||
{
|
||||
u_int rsize, gsize, bsize;
|
||||
const char *cp, *s = p;
|
||||
|
||||
if (sscanf(p, "rgb:%x/%x/%x", r, g, b) != 3)
|
||||
return (0);
|
||||
p += 4;
|
||||
|
||||
cp = strchr(p, '/');
|
||||
rsize = cp - p;
|
||||
if (rsize == 1)
|
||||
(*r) = (*r) | ((*r) << 4);
|
||||
else if (rsize == 3)
|
||||
(*r) >>= 4;
|
||||
else if (rsize == 4)
|
||||
(*r) >>= 8;
|
||||
else if (rsize != 2)
|
||||
return (0);
|
||||
|
||||
p = cp + 1;
|
||||
cp = strchr(p, '/');
|
||||
gsize = cp - p;
|
||||
if (gsize == 1)
|
||||
(*g) = (*g) | ((*g) << 4);
|
||||
else if (gsize == 3)
|
||||
(*g) >>= 4;
|
||||
else if (gsize == 4)
|
||||
(*g) >>= 8;
|
||||
else if (gsize != 2)
|
||||
return (0);
|
||||
|
||||
bsize = strlen(cp + 1);
|
||||
if (bsize == 1)
|
||||
(*b) = (*b) | ((*b) << 4);
|
||||
else if (bsize == 3)
|
||||
(*b) >>= 4;
|
||||
else if (bsize == 4)
|
||||
(*b) >>= 8;
|
||||
else if (bsize != 2)
|
||||
return (0);
|
||||
|
||||
log_debug("%s: %s = %02x%02x%02x", __func__, s, *r, *g, *b);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Handle the OSC 4 sequence for setting (multiple) palette entries. */
|
||||
static void
|
||||
input_osc_4(struct input_ctx *ictx, const char *p)
|
||||
@ -2340,7 +2423,7 @@ input_osc_4(struct input_ctx *ictx, const char *p)
|
||||
goto bad;
|
||||
|
||||
s = strsep(&next, ";");
|
||||
if (sscanf(s, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) {
|
||||
if (!input_osc_parse_colour(s, &r, &g, &b)) {
|
||||
s = next;
|
||||
continue;
|
||||
}
|
||||
@ -2365,8 +2448,11 @@ input_osc_10(struct input_ctx *ictx, const char *p)
|
||||
u_int r, g, b;
|
||||
char tmp[16];
|
||||
|
||||
if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3)
|
||||
goto bad;
|
||||
if (strcmp(p, "?") == 0)
|
||||
return;
|
||||
|
||||
if (!input_osc_parse_colour(p, &r, &g, &b))
|
||||
goto bad;
|
||||
xsnprintf(tmp, sizeof tmp, "fg=#%02x%02x%02x", r, g, b);
|
||||
options_set_style(wp->options, "window-style", 1, tmp);
|
||||
options_set_style(wp->options, "window-active-style", 1, tmp);
|
||||
@ -2386,7 +2472,10 @@ input_osc_11(struct input_ctx *ictx, const char *p)
|
||||
u_int r, g, b;
|
||||
char tmp[16];
|
||||
|
||||
if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3)
|
||||
if (strcmp(p, "?") == 0)
|
||||
return;
|
||||
|
||||
if (!input_osc_parse_colour(p, &r, &g, &b))
|
||||
goto bad;
|
||||
xsnprintf(tmp, sizeof tmp, "bg=#%02x%02x%02x", r, g, b);
|
||||
options_set_style(wp->options, "window-style", 1, tmp);
|
||||
|
233
external/bsd/tmux/dist/key-bindings.c
vendored
233
external/bsd/tmux/dist/key-bindings.c
vendored
@ -24,12 +24,6 @@
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
#define DEFAULT_CLIENT_MENU \
|
||||
" 'Detach' 'd' {detach-client}" \
|
||||
" 'Detach & Kill' 'X' {detach-client -P}" \
|
||||
" 'Detach Others' 'o' {detach-client -a}" \
|
||||
" ''" \
|
||||
" 'Lock' 'l' {lock-client}"
|
||||
#define DEFAULT_SESSION_MENU \
|
||||
" 'Next' 'n' {switch-client -n}" \
|
||||
" 'Previous' 'p' {switch-client -p}" \
|
||||
@ -69,7 +63,6 @@
|
||||
" '#{?pane_marked,Unmark,Mark}' 'm' {select-pane -m}" \
|
||||
" '#{?window_zoomed_flag,Unzoom,Zoom}' 'z' {resize-pane -Z}"
|
||||
|
||||
|
||||
static int key_bindings_cmp(struct key_binding *, struct key_binding *);
|
||||
RB_GENERATE_STATIC(key_bindings, key_binding, entry, key_bindings_cmp);
|
||||
static int key_table_cmp(struct key_table *, struct key_table *);
|
||||
@ -92,6 +85,15 @@ key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
key_bindings_free(struct key_table *table, struct key_binding *bd)
|
||||
{
|
||||
RB_REMOVE(key_bindings, &table->key_bindings, bd);
|
||||
cmd_list_free(bd->cmdlist);
|
||||
free(__UNCONST(bd->note));
|
||||
free(bd);
|
||||
}
|
||||
|
||||
struct key_table *
|
||||
key_bindings_get_table(const char *name, int create)
|
||||
{
|
||||
@ -133,11 +135,8 @@ key_bindings_unref_table(struct key_table *table)
|
||||
if (--table->references != 0)
|
||||
return;
|
||||
|
||||
RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1) {
|
||||
RB_REMOVE(key_bindings, &table->key_bindings, bd);
|
||||
cmd_list_free(bd->cmdlist);
|
||||
free(bd);
|
||||
}
|
||||
RB_FOREACH_SAFE(bd, key_bindings, &table->key_bindings, bd1)
|
||||
key_bindings_free(table, bd);
|
||||
|
||||
free(__UNCONST(table->name));
|
||||
free(table);
|
||||
@ -165,24 +164,22 @@ key_bindings_next(__unused struct key_table *table, struct key_binding *bd)
|
||||
}
|
||||
|
||||
void
|
||||
key_bindings_add(const char *name, key_code key, int repeat,
|
||||
key_bindings_add(const char *name, key_code key, const char *note, int repeat,
|
||||
struct cmd_list *cmdlist)
|
||||
{
|
||||
struct key_table *table;
|
||||
struct key_binding bd_find, *bd;
|
||||
struct key_binding *bd;
|
||||
|
||||
table = key_bindings_get_table(name, 1);
|
||||
|
||||
bd_find.key = (key & ~KEYC_XTERM);
|
||||
bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find);
|
||||
if (bd != NULL) {
|
||||
RB_REMOVE(key_bindings, &table->key_bindings, bd);
|
||||
cmd_list_free(bd->cmdlist);
|
||||
free(bd);
|
||||
}
|
||||
bd = key_bindings_get(table, key & ~KEYC_XTERM);
|
||||
if (bd != NULL)
|
||||
key_bindings_free(table, bd);
|
||||
|
||||
bd = xcalloc(1, sizeof *bd);
|
||||
bd->key = key;
|
||||
if (note != NULL)
|
||||
bd->note = xstrdup(note);
|
||||
RB_INSERT(key_bindings, &table->key_bindings, bd);
|
||||
|
||||
if (repeat)
|
||||
@ -194,20 +191,16 @@ void
|
||||
key_bindings_remove(const char *name, key_code key)
|
||||
{
|
||||
struct key_table *table;
|
||||
struct key_binding bd_find, *bd;
|
||||
struct key_binding *bd;
|
||||
|
||||
table = key_bindings_get_table(name, 0);
|
||||
if (table == NULL)
|
||||
return;
|
||||
|
||||
bd_find.key = (key & ~KEYC_XTERM);
|
||||
bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find);
|
||||
bd = key_bindings_get(table, key & ~KEYC_XTERM);
|
||||
if (bd == NULL)
|
||||
return;
|
||||
|
||||
RB_REMOVE(key_bindings, &table->key_bindings, bd);
|
||||
cmd_list_free(bd->cmdlist);
|
||||
free(bd);
|
||||
key_bindings_free(table, bd);
|
||||
|
||||
if (RB_EMPTY(&table->key_bindings)) {
|
||||
RB_REMOVE(key_tables, &key_tables, table);
|
||||
@ -236,87 +229,88 @@ void
|
||||
key_bindings_init(void)
|
||||
{
|
||||
static const char *defaults[] = {
|
||||
"bind C-b send-prefix",
|
||||
"bind C-o rotate-window",
|
||||
"bind C-z suspend-client",
|
||||
"bind Space next-layout",
|
||||
"bind ! break-pane",
|
||||
"bind '\"' split-window",
|
||||
"bind '#' list-buffers",
|
||||
"bind '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
|
||||
"bind % split-window -h",
|
||||
"bind & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
|
||||
"bind \"'\" command-prompt -pindex \"select-window -t ':%%'\"",
|
||||
"bind ( switch-client -p",
|
||||
"bind ) switch-client -n",
|
||||
"bind , command-prompt -I'#W' \"rename-window -- '%%'\"",
|
||||
"bind - delete-buffer",
|
||||
"bind . command-prompt \"move-window -t '%%'\"",
|
||||
"bind 0 select-window -t:=0",
|
||||
"bind 1 select-window -t:=1",
|
||||
"bind 2 select-window -t:=2",
|
||||
"bind 3 select-window -t:=3",
|
||||
"bind 4 select-window -t:=4",
|
||||
"bind 5 select-window -t:=5",
|
||||
"bind 6 select-window -t:=6",
|
||||
"bind 7 select-window -t:=7",
|
||||
"bind 8 select-window -t:=8",
|
||||
"bind 9 select-window -t:=9",
|
||||
"bind : command-prompt",
|
||||
"bind \\; last-pane",
|
||||
"bind = choose-buffer -Z",
|
||||
"bind ? list-keys",
|
||||
"bind D choose-client -Z",
|
||||
"bind E select-layout -E",
|
||||
"bind L switch-client -l",
|
||||
"bind M select-pane -M",
|
||||
"bind [ copy-mode",
|
||||
"bind ] paste-buffer",
|
||||
"bind c new-window",
|
||||
"bind d detach-client",
|
||||
"bind f command-prompt \"find-window -Z -- '%%'\"",
|
||||
"bind i display-message",
|
||||
"bind l last-window",
|
||||
"bind m select-pane -m",
|
||||
"bind n next-window",
|
||||
"bind o select-pane -t:.+",
|
||||
"bind p previous-window",
|
||||
"bind q display-panes",
|
||||
"bind r refresh-client",
|
||||
"bind s choose-tree -Zs",
|
||||
"bind t clock-mode",
|
||||
"bind w choose-tree -Zw",
|
||||
"bind x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
|
||||
"bind z resize-pane -Z",
|
||||
"bind '{' swap-pane -U",
|
||||
"bind '}' swap-pane -D",
|
||||
"bind '~' show-messages",
|
||||
"bind PPage copy-mode -u",
|
||||
"bind -r Up select-pane -U",
|
||||
"bind -r Down select-pane -D",
|
||||
"bind -r Left select-pane -L",
|
||||
"bind -r Right select-pane -R",
|
||||
"bind M-1 select-layout even-horizontal",
|
||||
"bind M-2 select-layout even-vertical",
|
||||
"bind M-3 select-layout main-horizontal",
|
||||
"bind M-4 select-layout main-vertical",
|
||||
"bind M-5 select-layout tiled",
|
||||
"bind M-n next-window -a",
|
||||
"bind M-o rotate-window -D",
|
||||
"bind M-p previous-window -a",
|
||||
"bind -r S-Up refresh-client -U 10",
|
||||
"bind -r S-Down refresh-client -D 10",
|
||||
"bind -r S-Left refresh-client -L 10",
|
||||
"bind -r S-Right refresh-client -R 10",
|
||||
"bind -r DC refresh-client -c",
|
||||
"bind -r M-Up resize-pane -U 5",
|
||||
"bind -r M-Down resize-pane -D 5",
|
||||
"bind -r M-Left resize-pane -L 5",
|
||||
"bind -r M-Right resize-pane -R 5",
|
||||
"bind -r C-Up resize-pane -U",
|
||||
"bind -r C-Down resize-pane -D",
|
||||
"bind -r C-Left resize-pane -L",
|
||||
"bind -r C-Right resize-pane -R",
|
||||
"bind -N 'Send the prefix key' C-b send-prefix",
|
||||
"bind -N 'Rotate through the panes' C-o rotate-window",
|
||||
"bind -N 'Suspend the current client' C-z suspend-client",
|
||||
"bind -N 'Select next layout' Space next-layout",
|
||||
"bind -N 'Break pane to a new window' ! break-pane",
|
||||
"bind -N 'Split window vertically' '\"' split-window",
|
||||
"bind -N 'List all paste buffers' '#' list-buffers",
|
||||
"bind -N 'Rename current session' '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
|
||||
"bind -N 'Split window horizontally' % split-window -h",
|
||||
"bind -N 'Kill current window' & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
|
||||
"bind -N 'Prompt for window index to select' \"'\" command-prompt -pindex \"select-window -t ':%%'\"",
|
||||
"bind -N 'Switch to previous client' ( switch-client -p",
|
||||
"bind -N 'Switch to next client' ) switch-client -n",
|
||||
"bind -N 'Rename current window' , command-prompt -I'#W' \"rename-window -- '%%'\"",
|
||||
"bind -N 'Delete the most recent paste buffer' - delete-buffer",
|
||||
"bind -N 'Move the current window' . command-prompt \"move-window -t '%%'\"",
|
||||
"bind -N 'Describe key binding' '/' command-prompt -kpkey 'list-keys -1N \"%%%\"'",
|
||||
"bind -N 'Select window 0' 0 select-window -t:=0",
|
||||
"bind -N 'Select window 1' 1 select-window -t:=1",
|
||||
"bind -N 'Select window 2' 2 select-window -t:=2",
|
||||
"bind -N 'Select window 3' 3 select-window -t:=3",
|
||||
"bind -N 'Select window 4' 4 select-window -t:=4",
|
||||
"bind -N 'Select window 5' 5 select-window -t:=5",
|
||||
"bind -N 'Select window 6' 6 select-window -t:=6",
|
||||
"bind -N 'Select window 7' 7 select-window -t:=7",
|
||||
"bind -N 'Select window 8' 8 select-window -t:=8",
|
||||
"bind -N 'Select window 9' 9 select-window -t:=9",
|
||||
"bind -N 'Prompt for a command' : command-prompt",
|
||||
"bind -N 'Move to the previously active pane' \\; last-pane",
|
||||
"bind -N 'Choose a paste buffer from a list' = choose-buffer -Z",
|
||||
"bind -N 'List key bindings' ? list-keys -N",
|
||||
"bind -N 'Choose a client from a list' D choose-client -Z",
|
||||
"bind -N 'Spread panes out evenly' E select-layout -E",
|
||||
"bind -N 'Switch to the last client' L switch-client -l",
|
||||
"bind -N 'Clear the marked pane' M select-pane -M",
|
||||
"bind -N 'Enter copy mode' [ copy-mode",
|
||||
"bind -N 'Paste the most recent paste buffer' ] paste-buffer",
|
||||
"bind -N 'Create a new window' c new-window",
|
||||
"bind -N 'Detach the current client' d detach-client",
|
||||
"bind -N 'Search for a pane' f command-prompt \"find-window -Z -- '%%'\"",
|
||||
"bind -N 'Display window information' i display-message",
|
||||
"bind -N 'Select the previously current window' l last-window",
|
||||
"bind -N 'Toggle the marked pane' m select-pane -m",
|
||||
"bind -N 'Select the next window' n next-window",
|
||||
"bind -N 'Select the next pane' o select-pane -t:.+",
|
||||
"bind -N 'Select the previous pane' p previous-window",
|
||||
"bind -N 'Display pane numbers' q display-panes",
|
||||
"bind -N 'Redraw the current client' r refresh-client",
|
||||
"bind -N 'Choose a session from a list' s choose-tree -Zs",
|
||||
"bind -N 'Show a clock' t clock-mode",
|
||||
"bind -N 'Choose a window from a list' w choose-tree -Zw",
|
||||
"bind -N 'Kill the active pane' x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
|
||||
"bind -N 'Zoom the active pane' z resize-pane -Z",
|
||||
"bind -N 'Swap the active pane with the pane above' '{' swap-pane -U",
|
||||
"bind -N 'Swap the active pane with the pane below' '}' swap-pane -D",
|
||||
"bind -N 'Show messages' '~' show-messages",
|
||||
"bind -N 'Enter copy mode and scroll up' PPage copy-mode -u",
|
||||
"bind -N 'Select the pane above the active pane' -r Up select-pane -U",
|
||||
"bind -N 'Select the pane below the active pane' -r Down select-pane -D",
|
||||
"bind -N 'Select the pane to the left of the active pane' -r Left select-pane -L",
|
||||
"bind -N 'Select the pane to the right of the active pane' -r Right select-pane -R",
|
||||
"bind -N 'Set the even-horizontal layout' M-1 select-layout even-horizontal",
|
||||
"bind -N 'Set the even-vertical layout' M-2 select-layout even-vertical",
|
||||
"bind -N 'Set the main-horizontal layout' M-3 select-layout main-horizontal",
|
||||
"bind -N 'Set the main-vertical layout' M-4 select-layout main-vertical",
|
||||
"bind -N 'Select the tiled layout' M-5 select-layout tiled",
|
||||
"bind -N 'Select the next window with an alert' M-n next-window -a",
|
||||
"bind -N 'Rotate through the panes in reverse' M-o rotate-window -D",
|
||||
"bind -N 'Select the previous window with an alert' M-p previous-window -a",
|
||||
"bind -N 'Move the visible part of the window up' -r S-Up refresh-client -U 10",
|
||||
"bind -N 'Move the visible part of the window down' -r S-Down refresh-client -D 10",
|
||||
"bind -N 'Move the visible part of the window left' -r S-Left refresh-client -L 10",
|
||||
"bind -N 'Move the visible part of the window right' -r S-Right refresh-client -R 10",
|
||||
"bind -N 'Reset so the visible part of the window follows the cursor' -r DC refresh-client -c",
|
||||
"bind -N 'Resize the pane up by 5' -r M-Up resize-pane -U 5",
|
||||
"bind -N 'Resize the pane down by 5' -r M-Down resize-pane -D 5",
|
||||
"bind -N 'Resize the pane left by 5' -r M-Left resize-pane -L 5",
|
||||
"bind -N 'Resize the pane right by 5' -r M-Right resize-pane -R 5",
|
||||
"bind -N 'Resize the pane up' -r C-Up resize-pane -U",
|
||||
"bind -N 'Resize the pane down' -r C-Down resize-pane -D",
|
||||
"bind -N 'Resize the pane left' -r C-Left resize-pane -L",
|
||||
"bind -N 'Resize the pane right' -r C-Right resize-pane -R",
|
||||
|
||||
"bind -n MouseDown1Pane select-pane -t=\\; send-keys -M",
|
||||
"bind -n MouseDrag1Border resize-pane -M",
|
||||
@ -326,7 +320,6 @@ key_bindings_init(void)
|
||||
"bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'",
|
||||
"bind -n WheelUpPane if -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'",
|
||||
|
||||
"bind -n MouseDown3StatusRight display-menu -t= -xM -yS -T \"#[align=centre]#{client_name}\" " DEFAULT_CLIENT_MENU,
|
||||
"bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -T \"#[align=centre]#{session_name}\" " DEFAULT_SESSION_MENU,
|
||||
"bind -n MouseDown3Status display-menu -t= -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU,
|
||||
"bind < display-menu -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\" " DEFAULT_WINDOW_MENU,
|
||||
@ -403,6 +396,8 @@ key_bindings_init(void)
|
||||
"bind -Tcopy-mode C-Up send -X scroll-up",
|
||||
"bind -Tcopy-mode C-Down send -X scroll-down",
|
||||
|
||||
"bind -Tcopy-mode-vi '#' send -FX search-backward '#{copy_cursor_word}'",
|
||||
"bind -Tcopy-mode-vi * send -FX search-forward '#{copy_cursor_word}'",
|
||||
"bind -Tcopy-mode-vi C-c send -X cancel",
|
||||
"bind -Tcopy-mode-vi C-d send -X halfpage-down",
|
||||
"bind -Tcopy-mode-vi C-e send -X scroll-down",
|
||||
@ -509,12 +504,16 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
|
||||
struct cmdq_item *new_item;
|
||||
int readonly;
|
||||
|
||||
readonly = 1;
|
||||
TAILQ_FOREACH(cmd, &bd->cmdlist->list, qentry) {
|
||||
if (!(cmd->entry->flags & CMD_READONLY))
|
||||
readonly = 0;
|
||||
if (c == NULL || (~c->flags & CLIENT_READONLY))
|
||||
readonly = 1;
|
||||
else {
|
||||
readonly = 1;
|
||||
TAILQ_FOREACH(cmd, &bd->cmdlist->list, qentry) {
|
||||
if (~cmd->entry->flags & CMD_READONLY)
|
||||
readonly = 0;
|
||||
}
|
||||
}
|
||||
if (!readonly && (c->flags & CLIENT_READONLY))
|
||||
if (!readonly)
|
||||
new_item = cmdq_get_callback(key_bindings_read_only, NULL);
|
||||
else {
|
||||
new_item = cmdq_get_command(bd->cmdlist, fs, m, 0);
|
||||
@ -522,8 +521,8 @@ key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item,
|
||||
new_item->shared->flags |= CMDQ_SHARED_REPEAT;
|
||||
}
|
||||
if (item != NULL)
|
||||
cmdq_insert_after(item, new_item);
|
||||
new_item = cmdq_insert_after(item, new_item);
|
||||
else
|
||||
cmdq_append(c, new_item);
|
||||
new_item = cmdq_append(c, new_item);
|
||||
return (new_item);
|
||||
}
|
||||
|
3
external/bsd/tmux/dist/log.c
vendored
3
external/bsd/tmux/dist/log.c
vendored
@ -136,6 +136,9 @@ log_debug(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (log_file == NULL)
|
||||
return;
|
||||
|
||||
va_start(ap, msg);
|
||||
log_vwrite(msg, ap);
|
||||
va_end(ap);
|
||||
|
31
external/bsd/tmux/dist/mode-tree.c
vendored
31
external/bsd/tmux/dist/mode-tree.c
vendored
@ -39,7 +39,7 @@ struct mode_tree_data {
|
||||
|
||||
const char **sort_list;
|
||||
u_int sort_size;
|
||||
u_int sort_type;
|
||||
struct mode_tree_sort_criteria sort_crit;
|
||||
|
||||
mode_tree_build_cb buildcb;
|
||||
mode_tree_draw_cb drawcb;
|
||||
@ -334,7 +334,6 @@ mode_tree_start(struct window_pane *wp, struct args *args,
|
||||
|
||||
mtd->sort_list = sort_list;
|
||||
mtd->sort_size = sort_size;
|
||||
mtd->sort_type = 0;
|
||||
|
||||
mtd->preview = !args_has(args, 'N');
|
||||
|
||||
@ -342,9 +341,10 @@ mode_tree_start(struct window_pane *wp, struct args *args,
|
||||
if (sort != NULL) {
|
||||
for (i = 0; i < sort_size; i++) {
|
||||
if (strcasecmp(sort, sort_list[i]) == 0)
|
||||
mtd->sort_type = i;
|
||||
mtd->sort_crit.field = i;
|
||||
}
|
||||
}
|
||||
mtd->sort_crit.reversed = args_has(args, 'r');
|
||||
|
||||
if (args_has(args, 'f'))
|
||||
mtd->filter = xstrdup(args_get(args, 'f'));
|
||||
@ -392,10 +392,10 @@ mode_tree_build(struct mode_tree_data *mtd)
|
||||
TAILQ_CONCAT(&mtd->saved, &mtd->children, entry);
|
||||
TAILQ_INIT(&mtd->children);
|
||||
|
||||
mtd->buildcb(mtd->modedata, mtd->sort_type, &tag, mtd->filter);
|
||||
mtd->buildcb(mtd->modedata, &mtd->sort_crit, &tag, mtd->filter);
|
||||
mtd->no_matches = TAILQ_EMPTY(&mtd->children);
|
||||
if (mtd->no_matches)
|
||||
mtd->buildcb(mtd->modedata, mtd->sort_type, &tag, NULL);
|
||||
mtd->buildcb(mtd->modedata, &mtd->sort_crit, &tag, NULL);
|
||||
|
||||
mode_tree_free_items(&mtd->saved);
|
||||
TAILQ_INIT(&mtd->saved);
|
||||
@ -598,6 +598,8 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
||||
xasprintf(&text, "%-*s%s%s%s: ", keylen, key, start, mti->name,
|
||||
tag);
|
||||
width = utf8_cstrwidth(text);
|
||||
if (width > w)
|
||||
width = w;
|
||||
free(start);
|
||||
|
||||
if (mti->tagged) {
|
||||
@ -607,11 +609,11 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
||||
|
||||
if (i != mtd->current) {
|
||||
screen_write_clearendofline(&ctx, 8);
|
||||
screen_write_puts(&ctx, &gc0, "%s", text);
|
||||
screen_write_nputs(&ctx, w, &gc0, "%s", text);
|
||||
format_draw(&ctx, &gc0, w - width, mti->text, NULL);
|
||||
} else {
|
||||
screen_write_clearendofline(&ctx, gc.bg);
|
||||
screen_write_puts(&ctx, &gc, "%s", text);
|
||||
screen_write_nputs(&ctx, w, &gc, "%s", text);
|
||||
format_draw(&ctx, &gc, w - width, mti->text, NULL);
|
||||
}
|
||||
free(text);
|
||||
@ -634,8 +636,9 @@ mode_tree_draw(struct mode_tree_data *mtd)
|
||||
screen_write_cursormove(&ctx, 0, h, 0);
|
||||
screen_write_box(&ctx, w, sy - h);
|
||||
|
||||
xasprintf(&text, " %s (sort: %s)", mti->name,
|
||||
mtd->sort_list[mtd->sort_type]);
|
||||
xasprintf(&text, " %s (sort: %s%s)", mti->name,
|
||||
mtd->sort_list[mtd->sort_crit.field],
|
||||
mtd->sort_crit.reversed ? ", reversed" : "");
|
||||
if (w - 2 >= strlen(text)) {
|
||||
screen_write_cursormove(&ctx, 1, h, 0);
|
||||
screen_write_puts(&ctx, &gc0, "%s", text);
|
||||
@ -993,9 +996,13 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
mtd->sort_type++;
|
||||
if (mtd->sort_type == mtd->sort_size)
|
||||
mtd->sort_type = 0;
|
||||
mtd->sort_crit.field++;
|
||||
if (mtd->sort_crit.field == mtd->sort_size)
|
||||
mtd->sort_crit.field = 0;
|
||||
mode_tree_build(mtd);
|
||||
break;
|
||||
case 'r':
|
||||
mtd->sort_crit.reversed = !mtd->sort_crit.reversed;
|
||||
mode_tree_build(mtd);
|
||||
break;
|
||||
case KEYC_LEFT:
|
||||
|
4
external/bsd/tmux/dist/notify.c
vendored
4
external/bsd/tmux/dist/notify.c
vendored
@ -89,9 +89,7 @@ notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne)
|
||||
new_item = cmdq_get_command(cmdlist, &fs, NULL, CMDQ_NOHOOKS);
|
||||
cmdq_format(new_item, "hook", "%s", ne->name);
|
||||
notify_hook_formats(new_item, s, w, ne->pane);
|
||||
|
||||
cmdq_insert_after(item, new_item);
|
||||
item = new_item;
|
||||
item = cmdq_insert_after(item, new_item);
|
||||
|
||||
a = options_array_next(a);
|
||||
}
|
||||
|
56
external/bsd/tmux/dist/options.c
vendored
56
external/bsd/tmux/dist/options.c
vendored
@ -296,6 +296,7 @@ options_remove(struct options_entry *o)
|
||||
else
|
||||
options_value_free(o, &o->value);
|
||||
RB_REMOVE(options_tree, &oo->tree, o);
|
||||
free(__UNCONST(o->name));
|
||||
free(o);
|
||||
}
|
||||
|
||||
@ -320,6 +321,17 @@ options_array_item(struct options_entry *o, u_int idx)
|
||||
return (RB_FIND(options_array, &o->value.array, &a));
|
||||
}
|
||||
|
||||
static struct options_array_item *
|
||||
options_array_new(struct options_entry *o, u_int idx)
|
||||
{
|
||||
struct options_array_item *a;
|
||||
|
||||
a = xcalloc(1, sizeof *a);
|
||||
a->index = idx;
|
||||
RB_INSERT(options_array, &o->value.array, a);
|
||||
return (a);
|
||||
}
|
||||
|
||||
static void
|
||||
options_array_free(struct options_entry *o, struct options_array_item *a)
|
||||
{
|
||||
@ -367,7 +379,14 @@ options_array_set(struct options_entry *o, u_int idx, const char *value,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (OPTIONS_IS_COMMAND(o) && value != NULL) {
|
||||
if (value == NULL) {
|
||||
a = options_array_item(o, idx);
|
||||
if (a != NULL)
|
||||
options_array_free(o, a);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (OPTIONS_IS_COMMAND(o)) {
|
||||
pr = cmd_parse_from_string(value, NULL);
|
||||
switch (pr->status) {
|
||||
case CMD_PARSE_EMPTY:
|
||||
@ -383,34 +402,33 @@ options_array_set(struct options_entry *o, u_int idx, const char *value,
|
||||
case CMD_PARSE_SUCCESS:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
a = options_array_item(o, idx);
|
||||
if (value == NULL) {
|
||||
if (a != NULL)
|
||||
options_array_free(o, a);
|
||||
a = options_array_item(o, idx);
|
||||
if (a == NULL)
|
||||
a = options_array_new(o, idx);
|
||||
else
|
||||
options_value_free(o, &a->value);
|
||||
a->value.cmdlist = pr->cmdlist;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (OPTIONS_IS_STRING(o)) {
|
||||
a = options_array_item(o, idx);
|
||||
if (a != NULL && append)
|
||||
xasprintf(&new, "%s%s", a->value.string, value);
|
||||
else
|
||||
new = xstrdup(value);
|
||||
if (a == NULL)
|
||||
a = options_array_new(o, idx);
|
||||
else
|
||||
options_value_free(o, &a->value);
|
||||
a->value.string = new;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (a == NULL) {
|
||||
a = xcalloc(1, sizeof *a);
|
||||
a->index = idx;
|
||||
RB_INSERT(options_array, &o->value.array, a);
|
||||
} else
|
||||
options_value_free(o, &a->value);
|
||||
|
||||
if (OPTIONS_IS_STRING(o))
|
||||
a->value.string = new;
|
||||
else if (OPTIONS_IS_COMMAND(o))
|
||||
a->value.cmdlist = pr->cmdlist;
|
||||
return (0);
|
||||
if (cause != NULL)
|
||||
*cause = xstrdup("wrong array type");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -592,7 +610,7 @@ options_match(const char *s, int *idx, int *ambiguous)
|
||||
|
||||
struct options_entry *
|
||||
options_match_get(struct options *oo, const char *s, int *idx, int only,
|
||||
int* ambiguous)
|
||||
int *ambiguous)
|
||||
{
|
||||
char *name;
|
||||
struct options_entry *o;
|
||||
|
2
external/bsd/tmux/dist/proc.c
vendored
2
external/bsd/tmux/dist/proc.c
vendored
@ -181,7 +181,7 @@ proc_start(const char *name)
|
||||
memset(&u, 0, sizeof u);
|
||||
|
||||
log_debug("%s started (%ld): version %s, socket %s, protocol %d", name,
|
||||
(long)getpid(), VERSION, socket_path, PROTOCOL_VERSION);
|
||||
(long)getpid(), getversion(), socket_path, PROTOCOL_VERSION);
|
||||
log_debug("on %s %s %s; libevent %s (%s)", u.sysname, u.release,
|
||||
u.version, event_get_version(), event_get_method());
|
||||
|
||||
|
6
external/bsd/tmux/dist/regsub.c
vendored
6
external/bsd/tmux/dist/regsub.c
vendored
@ -107,6 +107,12 @@ regsub(const char *pattern, const char *with, const char *text, int flags)
|
||||
start += m[0].rm_eo + 1;
|
||||
empty = 1;
|
||||
}
|
||||
|
||||
/* Stop now if anchored to start. */
|
||||
if (*pattern == '^') {
|
||||
regsub_copy(&buf, &len, text, start, end);
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[len] = '\0';
|
||||
|
||||
|
2
external/bsd/tmux/dist/resize.c
vendored
2
external/bsd/tmux/dist/resize.c
vendored
@ -230,7 +230,7 @@ recalculate_size(struct window *w)
|
||||
{
|
||||
struct session *s;
|
||||
struct client *c;
|
||||
u_int sx, sy, cx, cy, xpixel = 0, ypixel = 0, n;
|
||||
u_int sx = 0, sy = 0, cx, cy, xpixel = 0, ypixel = 0, n;
|
||||
int type, current, has, changed;
|
||||
|
||||
if (w->active == NULL)
|
||||
|
26
external/bsd/tmux/dist/screen-write.c
vendored
26
external/bsd/tmux/dist/screen-write.c
vendored
@ -100,7 +100,6 @@ void
|
||||
screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
|
||||
struct screen *s)
|
||||
{
|
||||
char tmp[32];
|
||||
u_int y;
|
||||
|
||||
memset(ctx, 0, sizeof *ctx);
|
||||
@ -119,12 +118,17 @@ screen_write_start(struct screen_write_ctx *ctx, struct window_pane *wp,
|
||||
ctx->scrolled = 0;
|
||||
ctx->bg = 8;
|
||||
|
||||
if (wp != NULL) {
|
||||
snprintf(tmp, sizeof tmp, "pane %%%u (at %u,%u)", wp->id,
|
||||
wp->xoff, wp->yoff);
|
||||
if (log_get_level() != 0) {
|
||||
if (wp != NULL) {
|
||||
log_debug("%s: size %ux%u, pane %%%u (at %u,%u)",
|
||||
__func__, screen_size_x(ctx->s),
|
||||
screen_size_y(ctx->s), wp->id, wp->xoff, wp->yoff);
|
||||
} else {
|
||||
log_debug("%s: size %ux%u, no pane",
|
||||
__func__, screen_size_x(ctx->s),
|
||||
screen_size_y(ctx->s));
|
||||
}
|
||||
}
|
||||
log_debug("%s: size %ux%u, %s", __func__, screen_size_x(ctx->s),
|
||||
screen_size_y(ctx->s), wp == NULL ? "no pane" : tmp);
|
||||
}
|
||||
|
||||
/* Finish writing. */
|
||||
@ -1234,7 +1238,6 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx)
|
||||
for (y = s->rupper; y < s->rlower; y++) {
|
||||
cl = &ctx->list[y + 1];
|
||||
TAILQ_CONCAT(&ctx->list[y].items, &cl->items, entry);
|
||||
TAILQ_INIT(&cl->items);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1323,8 +1326,7 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&gc, &ci->gc, sizeof gc);
|
||||
grid_view_set_cells(s->grid, s->cx, s->cy, &gc, ci->data, ci->used);
|
||||
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, ci->data, ci->used);
|
||||
screen_write_set_cursor(ctx, s->cx + ci->used, -1);
|
||||
|
||||
for (xx = s->cx; xx < screen_size_x(s); xx++) {
|
||||
@ -1348,8 +1350,7 @@ screen_write_collect_add(struct screen_write_ctx *ctx,
|
||||
/*
|
||||
* Don't need to check that the attributes and whatnot are still the
|
||||
* same - input_parse will end the collection when anything that isn't
|
||||
* a plain character is encountered. Also nothing should make it here
|
||||
* that isn't a single ASCII character.
|
||||
* a plain character is encountered.
|
||||
*/
|
||||
|
||||
collect = 1;
|
||||
@ -1635,7 +1636,8 @@ screen_write_overwrite(struct screen_write_ctx *ctx, struct grid_cell *gc,
|
||||
grid_view_get_cell(gd, xx, s->cy, &tmp_gc);
|
||||
if (~tmp_gc.flags & GRID_FLAG_PADDING)
|
||||
break;
|
||||
log_debug("%s: overwrite at %u,%u", __func__, xx, s->cy);
|
||||
log_debug("%s: overwrite at %u,%u", __func__, xx,
|
||||
s->cy);
|
||||
grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
|
||||
done = 1;
|
||||
}
|
||||
|
15
external/bsd/tmux/dist/screen.c
vendored
15
external/bsd/tmux/dist/screen.c
vendored
@ -151,11 +151,22 @@ screen_set_cursor_colour(struct screen *s, const char *colour)
|
||||
}
|
||||
|
||||
/* Set screen title. */
|
||||
void
|
||||
int
|
||||
screen_set_title(struct screen *s, const char *title)
|
||||
{
|
||||
if (!utf8_isvalid(title))
|
||||
return (0);
|
||||
free(s->title);
|
||||
utf8_stravis(&s->title, title, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
|
||||
s->title = xstrdup(title);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Set screen path. */
|
||||
void
|
||||
screen_set_path(struct screen *s, const char *path)
|
||||
{
|
||||
free(s->path);
|
||||
utf8_stravis(&s->path, path, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
|
||||
}
|
||||
|
||||
/* Push the current title onto the stack. */
|
||||
|
397
external/bsd/tmux/dist/server-client.c
vendored
397
external/bsd/tmux/dist/server-client.c
vendored
@ -42,11 +42,18 @@ static void server_client_set_title(struct client *);
|
||||
static void server_client_reset_state(struct client *);
|
||||
static int server_client_assume_paste(struct session *);
|
||||
static void server_client_clear_overlay(struct client *);
|
||||
static void server_client_resize_event(int, short, void *);
|
||||
|
||||
static void server_client_dispatch(struct imsg *, void *);
|
||||
static void server_client_dispatch_command(struct client *, struct imsg *);
|
||||
static void server_client_dispatch_identify(struct client *, struct imsg *);
|
||||
static void server_client_dispatch_shell(struct client *);
|
||||
static void server_client_dispatch_write_ready(struct client *,
|
||||
struct imsg *);
|
||||
static void server_client_dispatch_read_data(struct client *,
|
||||
struct imsg *);
|
||||
static void server_client_dispatch_read_done(struct client *,
|
||||
struct imsg *);
|
||||
|
||||
/* Number of attached clients. */
|
||||
u_int
|
||||
@ -194,16 +201,6 @@ server_client_create(int fd)
|
||||
|
||||
TAILQ_INIT(&c->queue);
|
||||
|
||||
c->stdin_data = evbuffer_new();
|
||||
if (c->stdin_data == NULL)
|
||||
fatalx("out of memory");
|
||||
c->stdout_data = evbuffer_new();
|
||||
if (c->stdout_data == NULL)
|
||||
fatalx("out of memory");
|
||||
c->stderr_data = evbuffer_new();
|
||||
if (c->stderr_data == NULL)
|
||||
fatalx("out of memory");
|
||||
|
||||
c->tty.fd = -1;
|
||||
c->title = NULL;
|
||||
|
||||
@ -222,6 +219,8 @@ server_client_create(int fd)
|
||||
c->prompt_buffer = NULL;
|
||||
c->prompt_index = 0;
|
||||
|
||||
RB_INIT(&c->files);
|
||||
|
||||
c->flags |= CLIENT_FOCUSED;
|
||||
|
||||
c->keytable = key_bindings_get_table("root", 1);
|
||||
@ -263,6 +262,7 @@ void
|
||||
server_client_lost(struct client *c)
|
||||
{
|
||||
struct message_entry *msg, *msg1;
|
||||
struct client_file *cf;
|
||||
|
||||
c->flags |= CLIENT_DEAD;
|
||||
|
||||
@ -270,8 +270,10 @@ server_client_lost(struct client *c)
|
||||
status_prompt_clear(c);
|
||||
status_message_clear(c);
|
||||
|
||||
if (c->stdin_callback != NULL)
|
||||
c->stdin_callback(c, 1, c->stdin_callback_data);
|
||||
RB_FOREACH(cf, client_files, &c->files) {
|
||||
cf->error = EINTR;
|
||||
file_fire_done(cf);
|
||||
}
|
||||
|
||||
TAILQ_REMOVE(&clients, c, entry);
|
||||
log_debug("lost client %p", c);
|
||||
@ -285,11 +287,6 @@ server_client_lost(struct client *c)
|
||||
free(c->ttyname);
|
||||
free(c->term);
|
||||
|
||||
evbuffer_free(c->stdin_data);
|
||||
evbuffer_free(c->stdout_data);
|
||||
if (c->stderr_data != c->stdout_data)
|
||||
evbuffer_free(c->stderr_data);
|
||||
|
||||
status_free(c);
|
||||
|
||||
free(c->title);
|
||||
@ -540,7 +537,8 @@ have_event:
|
||||
where = STATUS_RIGHT;
|
||||
break;
|
||||
case STYLE_RANGE_WINDOW:
|
||||
wl = winlink_find_by_index(&s->windows, sr->argument);
|
||||
wl = winlink_find_by_index(&s->windows,
|
||||
sr->argument);
|
||||
if (wl == NULL)
|
||||
return (KEYC_UNKNOWN);
|
||||
m->w = wl->window->id;
|
||||
@ -662,8 +660,7 @@ have_event:
|
||||
break;
|
||||
}
|
||||
c->tty.mouse_drag_flag = 0;
|
||||
|
||||
return (key);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Convert to a key binding. */
|
||||
@ -958,6 +955,7 @@ have_event:
|
||||
if (key == KEYC_UNKNOWN)
|
||||
return (KEYC_UNKNOWN);
|
||||
|
||||
out:
|
||||
/* Apply modifiers if any. */
|
||||
if (b & MOUSE_MASK_META)
|
||||
key |= KEYC_ESCAPE;
|
||||
@ -966,6 +964,8 @@ have_event:
|
||||
if (b & MOUSE_MASK_SHIFT)
|
||||
key |= KEYC_SHIFT;
|
||||
|
||||
if (log_get_level() != 0)
|
||||
log_debug("mouse key is %s", key_string_lookup_key (key));
|
||||
return (key);
|
||||
}
|
||||
|
||||
@ -993,6 +993,24 @@ server_client_assume_paste(struct session *s)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Has the latest client changed? */
|
||||
static void
|
||||
server_client_update_latest(struct client *c)
|
||||
{
|
||||
struct window *w;
|
||||
|
||||
if (c->session == NULL)
|
||||
return;
|
||||
w = c->session->curw->window;
|
||||
|
||||
if (w->latest == c)
|
||||
return;
|
||||
w->latest = c;
|
||||
|
||||
if (options_get_number(w->options, "window-size") == WINDOW_SIZE_LATEST)
|
||||
recalculate_size(w);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle data key input from client. This owns and can modify the key event it
|
||||
* is given and is responsible for freeing it.
|
||||
@ -1016,7 +1034,7 @@ server_client_key_callback(struct cmdq_item *item, void *data)
|
||||
key_code key0;
|
||||
|
||||
/* Check the client is good to accept input. */
|
||||
if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
|
||||
if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
|
||||
goto out;
|
||||
wl = s->curw;
|
||||
|
||||
@ -1041,7 +1059,7 @@ server_client_key_callback(struct cmdq_item *item, void *data)
|
||||
* Mouse drag is in progress, so fire the callback (now that
|
||||
* the mouse event is valid).
|
||||
*/
|
||||
if (key == KEYC_DRAGGING) {
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_DRAGGING) {
|
||||
c->tty.mouse_drag_update(c, m);
|
||||
goto out;
|
||||
}
|
||||
@ -1189,6 +1207,8 @@ forward_key:
|
||||
window_pane_key(wp, c, s, wl, key, m);
|
||||
|
||||
out:
|
||||
if (s != NULL)
|
||||
server_client_update_latest(c);
|
||||
free(event);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
@ -1201,7 +1221,7 @@ server_client_handle_key(struct client *c, struct key_event *event)
|
||||
struct cmdq_item *item;
|
||||
|
||||
/* Check the client is good to accept input. */
|
||||
if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
|
||||
if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
@ -1245,7 +1265,7 @@ server_client_loop(void)
|
||||
struct window_pane *wp;
|
||||
struct winlink *wl;
|
||||
struct session *s;
|
||||
int focus;
|
||||
int focus, attached, resize;
|
||||
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
server_client_check_exit(c);
|
||||
@ -1258,19 +1278,33 @@ server_client_loop(void)
|
||||
/*
|
||||
* Any windows will have been redrawn as part of clients, so clear
|
||||
* their flags now. Also check pane focus and resize.
|
||||
*
|
||||
* As an optimization, panes in windows that are in an attached session
|
||||
* but not the current window are not resized (this reduces the amount
|
||||
* of work needed when, for example, resizing an X terminal a
|
||||
* lot). Windows in no attached session are resized immediately since
|
||||
* that is likely to have come from a command like split-window and be
|
||||
* what the user wanted.
|
||||
*/
|
||||
focus = options_get_number(global_options, "focus-events");
|
||||
RB_FOREACH(w, windows, &windows) {
|
||||
attached = resize = 0;
|
||||
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
|
||||
s = wl->session;
|
||||
if (s->attached != 0 && s->curw == wl)
|
||||
if (s->attached != 0)
|
||||
attached = 1;
|
||||
if (s->attached != 0 && s->curw == wl) {
|
||||
resize = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!attached)
|
||||
resize = 1;
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->fd != -1) {
|
||||
if (focus)
|
||||
server_client_check_focus(wp);
|
||||
if (wl != NULL)
|
||||
if (resize)
|
||||
server_client_check_resize(wp);
|
||||
}
|
||||
wp->flags &= ~PANE_REDRAW;
|
||||
@ -1284,7 +1318,6 @@ static int
|
||||
server_client_resize_force(struct window_pane *wp)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 100000 };
|
||||
struct winsize ws;
|
||||
|
||||
/*
|
||||
* If we are resizing to the same size as when we entered the loop
|
||||
@ -1305,50 +1338,20 @@ server_client_resize_force(struct window_pane *wp)
|
||||
wp->sy <= 1)
|
||||
return (0);
|
||||
|
||||
memset(&ws, 0, sizeof ws);
|
||||
ws.ws_col = wp->sx;
|
||||
ws.ws_row = wp->sy - 1;
|
||||
if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
|
||||
#ifdef __sun
|
||||
if (errno != EINVAL && errno != ENXIO)
|
||||
#endif
|
||||
fatal("ioctl failed");
|
||||
log_debug("%s: %%%u forcing resize", __func__, wp->id);
|
||||
window_pane_send_resize(wp, -1);
|
||||
|
||||
evtimer_add(&wp->resize_timer, &tv);
|
||||
wp->flags |= PANE_RESIZEFORCE;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Resize timer event. */
|
||||
/* Resize a pane. */
|
||||
static void
|
||||
server_client_resize_event(__unused int fd, __unused short events, void *data)
|
||||
server_client_resize_pane(struct window_pane *wp)
|
||||
{
|
||||
struct window_pane *wp = data;
|
||||
struct winsize ws;
|
||||
|
||||
evtimer_del(&wp->resize_timer);
|
||||
|
||||
if (!(wp->flags & PANE_RESIZE))
|
||||
return;
|
||||
if (server_client_resize_force(wp))
|
||||
return;
|
||||
|
||||
memset(&ws, 0, sizeof ws);
|
||||
ws.ws_col = wp->sx;
|
||||
ws.ws_row = wp->sy;
|
||||
if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
|
||||
#ifdef __sun
|
||||
/*
|
||||
* Some versions of Solaris apparently can return an error when
|
||||
* resizing; don't know why this happens, can't reproduce on
|
||||
* other platforms and ignoring it doesn't seem to cause any
|
||||
* issues.
|
||||
*/
|
||||
if (errno != EINVAL && errno != ENXIO)
|
||||
#endif
|
||||
fatal("ioctl failed");
|
||||
log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy);
|
||||
window_pane_send_resize(wp, 0);
|
||||
|
||||
wp->flags &= ~PANE_RESIZE;
|
||||
|
||||
@ -1356,35 +1359,55 @@ server_client_resize_event(__unused int fd, __unused short events, void *data)
|
||||
wp->osy = wp->sy;
|
||||
}
|
||||
|
||||
/* Start the resize timer. */
|
||||
static void
|
||||
server_client_start_resize_timer(struct window_pane *wp)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 250000 };
|
||||
|
||||
if (!evtimer_pending(&wp->resize_timer, NULL))
|
||||
evtimer_add(&wp->resize_timer, &tv);
|
||||
}
|
||||
|
||||
/* Resize timer event. */
|
||||
static void
|
||||
server_client_resize_event(__unused int fd, __unused short events, void *data)
|
||||
{
|
||||
struct window_pane *wp = data;
|
||||
|
||||
evtimer_del(&wp->resize_timer);
|
||||
|
||||
if (~wp->flags & PANE_RESIZE)
|
||||
return;
|
||||
log_debug("%s: %%%u timer fired (was%s resized)", __func__, wp->id,
|
||||
(wp->flags & PANE_RESIZED) ? "" : " not");
|
||||
|
||||
if (wp->saved_grid == NULL && (wp->flags & PANE_RESIZED)) {
|
||||
log_debug("%s: %%%u deferring timer", __func__, wp->id);
|
||||
server_client_start_resize_timer(wp);
|
||||
} else if (!server_client_resize_force(wp)) {
|
||||
log_debug("%s: %%%u resizing pane", __func__, wp->id);
|
||||
server_client_resize_pane(wp);
|
||||
}
|
||||
wp->flags &= ~PANE_RESIZED;
|
||||
}
|
||||
|
||||
/* Check if pane should be resized. */
|
||||
static void
|
||||
server_client_check_resize(struct window_pane *wp)
|
||||
{
|
||||
struct timeval tv = { .tv_usec = 250000 };
|
||||
|
||||
if (!(wp->flags & PANE_RESIZE))
|
||||
if (~wp->flags & PANE_RESIZE)
|
||||
return;
|
||||
log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy);
|
||||
|
||||
if (!event_initialized(&wp->resize_timer))
|
||||
evtimer_set(&wp->resize_timer, server_client_resize_event, wp);
|
||||
|
||||
/*
|
||||
* The first resize should happen immediately, so if the timer is not
|
||||
* running, do it now.
|
||||
*/
|
||||
if (!evtimer_pending(&wp->resize_timer, NULL))
|
||||
server_client_resize_event(-1, 0, wp);
|
||||
|
||||
/*
|
||||
* If the pane is in the alternate screen, let the timer expire and
|
||||
* resize to give the application a chance to redraw. If not, keep
|
||||
* pushing the timer back.
|
||||
*/
|
||||
if (wp->saved_grid != NULL && evtimer_pending(&wp->resize_timer, NULL))
|
||||
return;
|
||||
evtimer_del(&wp->resize_timer);
|
||||
evtimer_add(&wp->resize_timer, &tv);
|
||||
if (!evtimer_pending(&wp->resize_timer, NULL)) {
|
||||
log_debug("%s: %%%u starting timer", __func__, wp->id);
|
||||
server_client_resize_pane(wp);
|
||||
server_client_start_resize_timer(wp);
|
||||
} else
|
||||
log_debug("%s: %%%u timer running", __func__, wp->id);
|
||||
}
|
||||
|
||||
/* Check whether pane should be focused. */
|
||||
@ -1533,17 +1556,17 @@ server_client_click_timer(__unused int fd, __unused short events, void *data)
|
||||
static void
|
||||
server_client_check_exit(struct client *c)
|
||||
{
|
||||
struct client_file *cf;
|
||||
|
||||
if (~c->flags & CLIENT_EXIT)
|
||||
return;
|
||||
if (c->flags & CLIENT_EXITED)
|
||||
return;
|
||||
|
||||
if (EVBUFFER_LENGTH(c->stdin_data) != 0)
|
||||
return;
|
||||
if (EVBUFFER_LENGTH(c->stdout_data) != 0)
|
||||
return;
|
||||
if (EVBUFFER_LENGTH(c->stderr_data) != 0)
|
||||
return;
|
||||
RB_FOREACH(cf, client_files, &c->files) {
|
||||
if (EVBUFFER_LENGTH(cf->buffer) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->flags & CLIENT_ATTACHED)
|
||||
notify_client("client-detached", c);
|
||||
@ -1554,7 +1577,7 @@ server_client_check_exit(struct client *c)
|
||||
/* Redraw timer callback. */
|
||||
static void
|
||||
server_client_redraw_timer(__unused int fd, __unused short events,
|
||||
__unused void* data)
|
||||
__unused void *data)
|
||||
{
|
||||
log_debug("redraw timer fired");
|
||||
}
|
||||
@ -1682,11 +1705,9 @@ server_client_set_title(struct client *c)
|
||||
static void
|
||||
server_client_dispatch(struct imsg *imsg, void *arg)
|
||||
{
|
||||
struct client *c = arg;
|
||||
struct msg_stdin_data stdindata;
|
||||
const char *data;
|
||||
ssize_t datalen;
|
||||
struct session *s;
|
||||
struct client *c = arg;
|
||||
ssize_t datalen;
|
||||
struct session *s;
|
||||
|
||||
if (c->flags & CLIENT_DEAD)
|
||||
return;
|
||||
@ -1696,7 +1717,6 @@ server_client_dispatch(struct imsg *imsg, void *arg)
|
||||
return;
|
||||
}
|
||||
|
||||
data = imsg->data;
|
||||
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
|
||||
switch (imsg->hdr.type) {
|
||||
@ -1713,27 +1733,13 @@ server_client_dispatch(struct imsg *imsg, void *arg)
|
||||
case MSG_COMMAND:
|
||||
server_client_dispatch_command(c, imsg);
|
||||
break;
|
||||
case MSG_STDIN:
|
||||
if (datalen != sizeof stdindata)
|
||||
fatalx("bad MSG_STDIN size");
|
||||
memcpy(&stdindata, data, sizeof stdindata);
|
||||
|
||||
if (c->stdin_callback == NULL)
|
||||
break;
|
||||
if (stdindata.size <= 0)
|
||||
c->stdin_closed = 1;
|
||||
else {
|
||||
evbuffer_add(c->stdin_data, stdindata.data,
|
||||
stdindata.size);
|
||||
}
|
||||
c->stdin_callback(c, c->stdin_closed, c->stdin_callback_data);
|
||||
break;
|
||||
case MSG_RESIZE:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_RESIZE size");
|
||||
|
||||
if (c->flags & CLIENT_CONTROL)
|
||||
break;
|
||||
server_client_update_latest(c);
|
||||
server_client_clear_overlay(c);
|
||||
tty_resize(&c->tty);
|
||||
recalculate_sizes();
|
||||
@ -1778,6 +1784,15 @@ server_client_dispatch(struct imsg *imsg, void *arg)
|
||||
|
||||
server_client_dispatch_shell(c);
|
||||
break;
|
||||
case MSG_WRITE_READY:
|
||||
server_client_dispatch_write_ready(c, imsg);
|
||||
break;
|
||||
case MSG_READ:
|
||||
server_client_dispatch_read_data(c, imsg);
|
||||
break;
|
||||
case MSG_READ_DONE:
|
||||
server_client_dispatch_read_done(c, imsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1796,7 +1811,7 @@ server_client_command_done(struct cmdq_item *item, __unused void *data)
|
||||
static void
|
||||
server_client_dispatch_command(struct client *c, struct imsg *imsg)
|
||||
{
|
||||
struct msg_command_data data;
|
||||
struct msg_command data;
|
||||
char *buf;
|
||||
size_t len;
|
||||
int argc;
|
||||
@ -1940,19 +1955,11 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
||||
#endif
|
||||
|
||||
if (c->flags & CLIENT_CONTROL) {
|
||||
c->stdin_callback = control_callback;
|
||||
|
||||
evbuffer_free(c->stderr_data);
|
||||
c->stderr_data = c->stdout_data;
|
||||
|
||||
if (c->flags & CLIENT_CONTROLCONTROL)
|
||||
evbuffer_add_printf(c->stdout_data, "\033P1000p");
|
||||
proc_send(c->peer, MSG_STDIN, -1, NULL, 0);
|
||||
|
||||
c->tty.fd = -1;
|
||||
|
||||
close(c->fd);
|
||||
c->fd = -1;
|
||||
|
||||
control_start(c);
|
||||
c->tty.fd = -1;
|
||||
} else if (c->fd != -1) {
|
||||
if (tty_init(&c->tty, c, c->fd, c->term) != 0) {
|
||||
close(c->fd);
|
||||
@ -1992,93 +1999,71 @@ server_client_dispatch_shell(struct client *c)
|
||||
proc_kill_peer(c->peer);
|
||||
}
|
||||
|
||||
/* Event callback to push more stdout data if any left. */
|
||||
/* Handle write ready message. */
|
||||
static void
|
||||
server_client_stdout_cb(__unused int fd, __unused short events, void *arg)
|
||||
server_client_dispatch_write_ready(struct client *c, struct imsg *imsg)
|
||||
{
|
||||
struct client *c = arg;
|
||||
struct msg_write_ready *msg = imsg->data;
|
||||
size_t msglen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
struct client_file find, *cf;
|
||||
|
||||
if (~c->flags & CLIENT_DEAD)
|
||||
server_client_push_stdout(c);
|
||||
server_client_unref(c);
|
||||
}
|
||||
|
||||
/* Push stdout to client if possible. */
|
||||
void
|
||||
server_client_push_stdout(struct client *c)
|
||||
{
|
||||
struct msg_stdout_data data;
|
||||
size_t sent, left;
|
||||
|
||||
left = EVBUFFER_LENGTH(c->stdout_data);
|
||||
while (left != 0) {
|
||||
sent = left;
|
||||
if (sent > sizeof data.data)
|
||||
sent = sizeof data.data;
|
||||
memcpy(data.data, EVBUFFER_DATA(c->stdout_data), sent);
|
||||
data.size = sent;
|
||||
|
||||
if (proc_send(c->peer, MSG_STDOUT, -1, &data, sizeof data) != 0)
|
||||
break;
|
||||
evbuffer_drain(c->stdout_data, sent);
|
||||
|
||||
left = EVBUFFER_LENGTH(c->stdout_data);
|
||||
log_debug("%s: client %p, sent %zu, left %zu", __func__, c,
|
||||
sent, left);
|
||||
}
|
||||
if (left != 0) {
|
||||
c->references++;
|
||||
event_once(-1, EV_TIMEOUT, server_client_stdout_cb, c, NULL);
|
||||
log_debug("%s: client %p, queued", __func__, c);
|
||||
}
|
||||
}
|
||||
|
||||
/* Event callback to push more stderr data if any left. */
|
||||
static void
|
||||
server_client_stderr_cb(__unused int fd, __unused short events, void *arg)
|
||||
{
|
||||
struct client *c = arg;
|
||||
|
||||
if (~c->flags & CLIENT_DEAD)
|
||||
server_client_push_stderr(c);
|
||||
server_client_unref(c);
|
||||
}
|
||||
|
||||
/* Push stderr to client if possible. */
|
||||
void
|
||||
server_client_push_stderr(struct client *c)
|
||||
{
|
||||
struct msg_stderr_data data;
|
||||
size_t sent, left;
|
||||
|
||||
if (c->stderr_data == c->stdout_data) {
|
||||
server_client_push_stdout(c);
|
||||
if (msglen != sizeof *msg)
|
||||
fatalx("bad MSG_WRITE_READY size");
|
||||
find.stream = msg->stream;
|
||||
if ((cf = RB_FIND(client_files, &c->files, &find)) == NULL)
|
||||
return;
|
||||
}
|
||||
if (msg->error != 0) {
|
||||
cf->error = msg->error;
|
||||
file_fire_done(cf);
|
||||
} else
|
||||
file_push(cf);
|
||||
}
|
||||
|
||||
left = EVBUFFER_LENGTH(c->stderr_data);
|
||||
while (left != 0) {
|
||||
sent = left;
|
||||
if (sent > sizeof data.data)
|
||||
sent = sizeof data.data;
|
||||
memcpy(data.data, EVBUFFER_DATA(c->stderr_data), sent);
|
||||
data.size = sent;
|
||||
/* Handle read data message. */
|
||||
static void
|
||||
server_client_dispatch_read_data(struct client *c, struct imsg *imsg)
|
||||
{
|
||||
struct msg_read_data *msg = imsg->data;
|
||||
size_t msglen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
struct client_file find, *cf;
|
||||
void *bdata = msg + 1;
|
||||
size_t bsize = msglen - sizeof *msg;
|
||||
|
||||
if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) != 0)
|
||||
break;
|
||||
evbuffer_drain(c->stderr_data, sent);
|
||||
if (msglen < sizeof *msg)
|
||||
fatalx("bad MSG_READ_DATA size");
|
||||
find.stream = msg->stream;
|
||||
if ((cf = RB_FIND(client_files, &c->files, &find)) == NULL)
|
||||
return;
|
||||
|
||||
left = EVBUFFER_LENGTH(c->stderr_data);
|
||||
log_debug("%s: client %p, sent %zu, left %zu", __func__, c,
|
||||
sent, left);
|
||||
}
|
||||
if (left != 0) {
|
||||
c->references++;
|
||||
event_once(-1, EV_TIMEOUT, server_client_stderr_cb, c, NULL);
|
||||
log_debug("%s: client %p, queued", __func__, c);
|
||||
log_debug("%s: file %d read %zu bytes", c->name, cf->stream, bsize);
|
||||
if (cf->error == 0) {
|
||||
if (evbuffer_add(cf->buffer, bdata, bsize) != 0) {
|
||||
cf->error = ENOMEM;
|
||||
file_fire_done(cf);
|
||||
} else
|
||||
file_fire_read(cf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle read done message. */
|
||||
static void
|
||||
server_client_dispatch_read_done(struct client *c, struct imsg *imsg)
|
||||
{
|
||||
struct msg_read_done *msg = imsg->data;
|
||||
size_t msglen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
struct client_file find, *cf;
|
||||
|
||||
if (msglen != sizeof *msg)
|
||||
fatalx("bad MSG_READ_DONE size");
|
||||
find.stream = msg->stream;
|
||||
if ((cf = RB_FIND(client_files, &c->files, &find)) == NULL)
|
||||
return;
|
||||
|
||||
log_debug("%s: file %d read done", c->name, cf->stream);
|
||||
cf->error = msg->error;
|
||||
file_fire_done(cf);
|
||||
}
|
||||
|
||||
/* Add to client message log. */
|
||||
void
|
||||
server_client_add_message(struct client *c, const char *fmt, ...)
|
||||
@ -2128,19 +2113,3 @@ server_client_get_cwd(struct client *c, struct session *s)
|
||||
return (home);
|
||||
return ("/");
|
||||
}
|
||||
|
||||
/* Resolve an absolute path or relative to client working directory. */
|
||||
char *
|
||||
server_client_get_path(struct client *c, const char *file)
|
||||
{
|
||||
char *path, resolved[PATH_MAX];
|
||||
|
||||
if (*file == '/')
|
||||
path = xstrdup(file);
|
||||
else
|
||||
xasprintf(&path, "%s/%s", server_client_get_cwd(c, NULL), file);
|
||||
if (realpath(path, resolved) == NULL)
|
||||
return (path);
|
||||
free(path);
|
||||
return (xstrdup(resolved));
|
||||
}
|
||||
|
30
external/bsd/tmux/dist/server-fn.c
vendored
30
external/bsd/tmux/dist/server-fn.c
vendored
@ -440,36 +440,6 @@ server_check_unattached(void)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
server_set_stdin_callback(struct client *c, void (*cb)(struct client *, int,
|
||||
void *), void *cb_data, char **cause)
|
||||
{
|
||||
if (c == NULL || c->session != NULL) {
|
||||
*cause = xstrdup("no client with stdin");
|
||||
return (-1);
|
||||
}
|
||||
if (c->flags & CLIENT_TERMINAL) {
|
||||
*cause = xstrdup("stdin is a tty");
|
||||
return (-1);
|
||||
}
|
||||
if (c->stdin_callback != NULL) {
|
||||
*cause = xstrdup("stdin is in use");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
c->stdin_callback_data = cb_data;
|
||||
c->stdin_callback = cb;
|
||||
|
||||
c->references++;
|
||||
|
||||
if (c->stdin_closed)
|
||||
c->stdin_callback(c, 1, c->stdin_callback_data);
|
||||
|
||||
proc_send(c->peer, MSG_STDIN, -1, NULL, 0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
server_unzoom_window(struct window *w)
|
||||
{
|
||||
|
15
external/bsd/tmux/dist/session.c
vendored
15
external/bsd/tmux/dist/session.c
vendored
@ -568,7 +568,20 @@ session_group_count(struct session_group *sg)
|
||||
|
||||
n = 0;
|
||||
TAILQ_FOREACH(s, &sg->sessions, gentry)
|
||||
n++;
|
||||
n++;
|
||||
return (n);
|
||||
}
|
||||
|
||||
/* Count number of clients attached to sessions in session group. */
|
||||
u_int
|
||||
session_group_attached_count(struct session_group *sg)
|
||||
{
|
||||
struct session *s;
|
||||
u_int n;
|
||||
|
||||
n = 0;
|
||||
TAILQ_FOREACH(s, &sg->sessions, gentry)
|
||||
n += s->attached;
|
||||
return (n);
|
||||
}
|
||||
|
||||
|
68
external/bsd/tmux/dist/spawn.c
vendored
68
external/bsd/tmux/dist/spawn.c
vendored
@ -78,12 +78,14 @@ spawn_log(const char *from, struct spawn_context *sc)
|
||||
struct winlink *
|
||||
spawn_window(struct spawn_context *sc, char **cause)
|
||||
{
|
||||
struct cmdq_item *item = sc->item;
|
||||
struct client *c = item->client;
|
||||
struct session *s = sc->s;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
struct winlink *wl;
|
||||
int idx = sc->idx;
|
||||
u_int sx, sy;
|
||||
u_int sx, sy, xpixel, ypixel;
|
||||
|
||||
spawn_log(__func__, sc);
|
||||
|
||||
@ -153,8 +155,9 @@ spawn_window(struct spawn_context *sc, char **cause)
|
||||
xasprintf(cause, "couldn't add window %d", idx);
|
||||
return (NULL);
|
||||
}
|
||||
default_window_size(s, NULL, &sx, &sy, -1);
|
||||
if ((w = window_create(sx, sy)) == NULL) {
|
||||
default_window_size(sc->c, s, NULL, &sx, &sy, &xpixel, &ypixel,
|
||||
-1);
|
||||
if ((w = window_create(sx, sy, xpixel, ypixel)) == NULL) {
|
||||
winlink_remove(&s->windows, sc->wl);
|
||||
xasprintf(cause, "couldn't create window %d", idx);
|
||||
return (NULL);
|
||||
@ -162,6 +165,7 @@ spawn_window(struct spawn_context *sc, char **cause)
|
||||
if (s->curw == NULL)
|
||||
s->curw = sc->wl;
|
||||
sc->wl->session = s;
|
||||
w->latest = sc->c;
|
||||
winlink_set_window(sc->wl, w);
|
||||
} else
|
||||
w = NULL;
|
||||
@ -178,7 +182,8 @@ spawn_window(struct spawn_context *sc, char **cause)
|
||||
/* Set the name of the new window. */
|
||||
if (~sc->flags & SPAWN_RESPAWN) {
|
||||
if (sc->name != NULL) {
|
||||
w->name = xstrdup(sc->name);
|
||||
w->name = format_single(item, sc->name, c, s, NULL,
|
||||
NULL);
|
||||
options_set_number(w->options, "automatic-rename", 0);
|
||||
} else
|
||||
w->name = xstrdup(default_window_name(w));
|
||||
@ -214,9 +219,21 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
u_int hlimit;
|
||||
struct winsize ws;
|
||||
sigset_t set, oldset;
|
||||
key_code key;
|
||||
|
||||
spawn_log(__func__, sc);
|
||||
|
||||
/*
|
||||
* Work out the current working directory. If respawning, use
|
||||
* the pane's stored one unless specified.
|
||||
*/
|
||||
if (sc->cwd != NULL)
|
||||
cwd = format_single(item, sc->cwd, c, item->target.s, NULL, NULL);
|
||||
else if (~sc->flags & SPAWN_RESPAWN)
|
||||
cwd = xstrdup(server_client_get_cwd(c, item->target.s));
|
||||
else
|
||||
cwd = NULL;
|
||||
|
||||
/*
|
||||
* If we are respawning then get rid of the old process. Otherwise
|
||||
* either create a new cell or assign to the one we are given.
|
||||
@ -227,6 +244,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
window_pane_index(sc->wp0, &idx);
|
||||
xasprintf(cause, "pane %s:%d.%u still active",
|
||||
s->name, sc->wl->idx, idx);
|
||||
free(cwd);
|
||||
return (NULL);
|
||||
}
|
||||
if (sc->wp0->fd != -1) {
|
||||
@ -247,8 +265,8 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we have a pane with nothing running in it ready for the new
|
||||
* process. Work out the command and arguments.
|
||||
* Now we have a pane with nothing running in it ready for the new process.
|
||||
* Work out the command and arguments and store the working directory.
|
||||
*/
|
||||
if (sc->argc == 0 && (~sc->flags & SPAWN_RESPAWN)) {
|
||||
cmd = options_get_string(s->options, "default-command");
|
||||
@ -263,6 +281,10 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
argc = sc->argc;
|
||||
argv = sc->argv;
|
||||
}
|
||||
if (cwd != NULL) {
|
||||
free(new_wp->cwd);
|
||||
new_wp->cwd = cwd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace the stored arguments if there are new ones. If not, the
|
||||
@ -274,21 +296,6 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
new_wp->argv = cmd_copy_argv(argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Work out the current working directory. If respawning, use
|
||||
* the pane's stored one unless specified.
|
||||
*/
|
||||
if (sc->cwd != NULL)
|
||||
cwd = format_single(item, sc->cwd, c, s, NULL, NULL);
|
||||
else if (~sc->flags & SPAWN_RESPAWN)
|
||||
cwd = xstrdup(server_client_get_cwd(c, s));
|
||||
else
|
||||
cwd = NULL;
|
||||
if (cwd != NULL) {
|
||||
free(new_wp->cwd);
|
||||
new_wp->cwd = cwd;
|
||||
}
|
||||
|
||||
/* Create an environment for this pane. */
|
||||
child = environ_for_session(s, 0);
|
||||
if (sc->environ != NULL)
|
||||
@ -334,6 +341,8 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
memset(&ws, 0, sizeof ws);
|
||||
ws.ws_col = screen_size_x(&new_wp->base);
|
||||
ws.ws_row = screen_size_y(&new_wp->base);
|
||||
ws.ws_xpixel = w->xpixel * ws.ws_col;
|
||||
ws.ws_ypixel = w->ypixel * ws.ws_row;
|
||||
|
||||
/* Block signals until fork has completed. */
|
||||
sigfillset(&set);
|
||||
@ -375,13 +384,17 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
|
||||
/*
|
||||
* Update terminal escape characters from the session if available and
|
||||
* force VERASE to tmux's \177.
|
||||
* force VERASE to tmux's backspace.
|
||||
*/
|
||||
if (tcgetattr(STDIN_FILENO, &now) != 0)
|
||||
_exit(1);
|
||||
if (s->tio != NULL)
|
||||
memcpy(now.c_cc, s->tio->c_cc, sizeof now.c_cc);
|
||||
now.c_cc[VERASE] = '\177';
|
||||
key = options_get_number(global_options, "backspace");
|
||||
if (key >= 0x7f)
|
||||
now.c_cc[VERASE] = '\177';
|
||||
else
|
||||
now.c_cc[VERASE] = key;
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &now) != 0)
|
||||
_exit(1);
|
||||
|
||||
@ -424,6 +437,15 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
_exit(1);
|
||||
|
||||
complete:
|
||||
#ifdef HAVE_UTEMPTER
|
||||
if (~new_wp->flags & PANE_EMPTY) {
|
||||
xasprintf(&cp, "tmux(%lu).%%%u", (long)getpid(), new_wp->id);
|
||||
utempter_add_record(new_wp->fd, cp);
|
||||
kill(getpid(), SIGCHLD);
|
||||
free(cp);
|
||||
}
|
||||
#endif
|
||||
|
||||
new_wp->pipe_off = 0;
|
||||
new_wp->flags &= ~PANE_EXITED;
|
||||
|
||||
|
8
external/bsd/tmux/dist/status.c
vendored
8
external/bsd/tmux/dist/status.c
vendored
@ -915,11 +915,17 @@ status_prompt_key(struct client *c, key_code key)
|
||||
{
|
||||
struct options *oo = c->session->options;
|
||||
char *s, *cp, word[64], prefix = '=';
|
||||
const char *histstr, *ws = NULL;
|
||||
const char *histstr, *ws = NULL, *keystring;
|
||||
size_t size, n, off, idx, used;
|
||||
struct utf8_data tmp, *first, *last, *ud;
|
||||
int keys;
|
||||
|
||||
if (c->prompt_flags & PROMPT_KEY) {
|
||||
keystring = key_string_lookup_key(key);
|
||||
c->prompt_inputcb(c, c->prompt_data, keystring, 1);
|
||||
status_prompt_clear(c);
|
||||
return (0);
|
||||
}
|
||||
size = utf8_strlen(c->prompt_buffer);
|
||||
|
||||
if (c->prompt_flags & PROMPT_NUMERIC) {
|
||||
|
39
external/bsd/tmux/dist/style.c
vendored
39
external/bsd/tmux/dist/style.c
vendored
@ -36,13 +36,15 @@ static struct style style_default = {
|
||||
STYLE_ALIGN_DEFAULT,
|
||||
STYLE_LIST_OFF,
|
||||
|
||||
STYLE_RANGE_NONE, 0
|
||||
STYLE_RANGE_NONE, 0,
|
||||
|
||||
STYLE_DEFAULT_BASE
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse an embedded style of the form "fg=colour,bg=colour,bright,...".
|
||||
* Note that this adds onto the given style, so it must have been initialized
|
||||
* alredy.
|
||||
* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". Note
|
||||
* that this adds onto the given style, so it must have been initialized
|
||||
* already.
|
||||
*/
|
||||
int
|
||||
style_parse(struct style *sy, const struct grid_cell *base, const char *in)
|
||||
@ -74,7 +76,11 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in)
|
||||
sy->gc.bg = base->bg;
|
||||
sy->gc.attr = base->attr;
|
||||
sy->gc.flags = base->flags;
|
||||
} else if (strcasecmp(tmp, "nolist") == 0)
|
||||
} else if (strcasecmp(tmp, "push-default") == 0)
|
||||
sy->default_type = STYLE_DEFAULT_PUSH;
|
||||
else if (strcasecmp(tmp, "pop-default") == 0)
|
||||
sy->default_type = STYLE_DEFAULT_POP;
|
||||
else if (strcasecmp(tmp, "nolist") == 0)
|
||||
sy->list = STYLE_LIST_OFF;
|
||||
else if (strncasecmp(tmp, "list=", 5) == 0) {
|
||||
if (strcasecmp(tmp + 5, "on") == 0)
|
||||
@ -223,6 +229,14 @@ style_tostring(struct style *sy)
|
||||
tmp);
|
||||
comma = ",";
|
||||
}
|
||||
if (sy->default_type != STYLE_DEFAULT_BASE) {
|
||||
if (sy->default_type == STYLE_DEFAULT_PUSH)
|
||||
tmp = "push-default";
|
||||
else if (sy->default_type == STYLE_DEFAULT_POP)
|
||||
tmp = "pop-default";
|
||||
off += xsnprintf(s + off, sizeof s - off, "%s%s", comma, tmp);
|
||||
comma = ",";
|
||||
}
|
||||
if (sy->fill != 8) {
|
||||
off += xsnprintf(s + off, sizeof s - off, "%sfill=%s", comma,
|
||||
colour_tostring(sy->fill));
|
||||
@ -262,21 +276,6 @@ style_apply(struct grid_cell *gc, struct options *oo, const char *name)
|
||||
gc->attr |= sy->gc.attr;
|
||||
}
|
||||
|
||||
/* Apply a style, updating if default. */
|
||||
void
|
||||
style_apply_update(struct grid_cell *gc, struct options *oo, const char *name)
|
||||
{
|
||||
struct style *sy;
|
||||
|
||||
sy = options_get_style(oo, name);
|
||||
if (sy->gc.fg != 8)
|
||||
gc->fg = sy->gc.fg;
|
||||
if (sy->gc.bg != 8)
|
||||
gc->bg = sy->gc.bg;
|
||||
if (sy->gc.attr != 0)
|
||||
gc->attr |= sy->gc.attr;
|
||||
}
|
||||
|
||||
/* Initialize style from cell. */
|
||||
void
|
||||
style_set(struct style *sy, const struct grid_cell *gc)
|
||||
|
448
external/bsd/tmux/dist/tmux.1
vendored
448
external/bsd/tmux/dist/tmux.1
vendored
@ -214,7 +214,6 @@ was given) and off.
|
||||
Report the
|
||||
.Nm
|
||||
version.
|
||||
.Pp
|
||||
.It Ar command Op Ar flags
|
||||
This specifies one of a set of commands used to control
|
||||
.Nm ,
|
||||
@ -296,6 +295,12 @@ Prompt to search for text in open windows.
|
||||
Display some information about the current window.
|
||||
.It l
|
||||
Move to the previously selected window.
|
||||
.It m
|
||||
Mark the current pane (see
|
||||
.Ic select-pane
|
||||
.Fl m ) .
|
||||
.It M
|
||||
Clear the marked pane.
|
||||
.It n
|
||||
Change to the next window.
|
||||
.It o
|
||||
@ -306,12 +311,6 @@ Change to the previous window.
|
||||
Briefly display pane indexes.
|
||||
.It r
|
||||
Force redraw of the attached client.
|
||||
.It m
|
||||
Mark the current pane (see
|
||||
.Ic select-pane
|
||||
.Fl m ) .
|
||||
.It M
|
||||
Clear the marked pane.
|
||||
.It s
|
||||
Select a new session for the attached client interactively.
|
||||
.It t
|
||||
@ -556,7 +555,7 @@ Braces may be enclosed inside braces, for example:
|
||||
.Bd -literal -offset indent
|
||||
bind x if-shell "true" {
|
||||
if-shell "true" {
|
||||
display "true!"
|
||||
display "true!"
|
||||
}
|
||||
}
|
||||
.Ed
|
||||
@ -938,7 +937,9 @@ If
|
||||
is specified, any other clients attached to the session are detached.
|
||||
If
|
||||
.Fl x
|
||||
is given, send SIGHUP to the parent process of the client as well as
|
||||
is given, send
|
||||
.Dv SIGHUP
|
||||
to the parent process of the client as well as
|
||||
detaching the client, typically causing it to exit.
|
||||
.Fl r
|
||||
signifies the client is read-only (only keys bound to the
|
||||
@ -989,7 +990,9 @@ option kills all but the client given with
|
||||
.Fl t .
|
||||
If
|
||||
.Fl P
|
||||
is given, send SIGHUP to the parent process of the client, typically causing it
|
||||
is given, send
|
||||
.Dv SIGHUP
|
||||
to the parent process of the client, typically causing it
|
||||
to exit.
|
||||
With
|
||||
.Fl E ,
|
||||
@ -1033,9 +1036,12 @@ If
|
||||
is specified, list only clients connected to that session.
|
||||
.It Xo Ic list-commands
|
||||
.Op Fl F Ar format
|
||||
.Op Ar command
|
||||
.Xc
|
||||
.D1 (alias: Ic lscm )
|
||||
List the syntax of all commands supported by
|
||||
List the syntax of
|
||||
.Ar command
|
||||
or - if omitted - of all commands supported by
|
||||
.Nm .
|
||||
.It Ic list-sessions Op Fl F Ar format
|
||||
.D1 (alias: Ic ls )
|
||||
@ -1156,7 +1162,7 @@ The
|
||||
.Fl P
|
||||
option prints information about the new session after it has been created.
|
||||
By default, it uses the format
|
||||
.Ql #{session_name}:
|
||||
.Ql #{session_name}:\&
|
||||
but a different format may be specified with
|
||||
.Fl F .
|
||||
.Pp
|
||||
@ -1288,6 +1294,17 @@ shows the parsed commands and line numbers if possible.
|
||||
Start the
|
||||
.Nm
|
||||
server, if not already running, without creating any sessions.
|
||||
.Pp
|
||||
Note that as by default the
|
||||
.Nm
|
||||
server will exit with no sessions, this is only useful if a session is created in
|
||||
.Pa ~/.tmux.conf ,
|
||||
.Ic exit-empty
|
||||
is turned off, or another command is run as part of the same command sequence.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
$ tmux start \\; show -g
|
||||
.Ed
|
||||
.It Xo Ic suspend-client
|
||||
.Op Fl t Ar target-client
|
||||
.Xc
|
||||
@ -1296,7 +1313,7 @@ Suspend a client by sending
|
||||
.Dv SIGTSTP
|
||||
(tty stop).
|
||||
.It Xo Ic switch-client
|
||||
.Op Fl Elnpr
|
||||
.Op Fl ElnprZ
|
||||
.Op Fl c Ar target-client
|
||||
.Op Fl t Ar target-session
|
||||
.Op Fl T Ar key-table
|
||||
@ -1313,7 +1330,10 @@ may refer to a pane (a target that contains
|
||||
.Ql \&.
|
||||
or
|
||||
.Ql % ) ,
|
||||
in which case the session, window and pane are all changed.
|
||||
to change session, window and pane.
|
||||
In that case,
|
||||
.Fl Z
|
||||
keeps the window zoomed if it was zoomed.
|
||||
If
|
||||
.Fl l ,
|
||||
.Fl n
|
||||
@ -1333,7 +1353,8 @@ is used,
|
||||
option will not be applied.
|
||||
.Pp
|
||||
.Fl T
|
||||
sets the client's key table; the next key from the client will be interpreted from
|
||||
sets the client's key table; the next key from the client will be interpreted
|
||||
from
|
||||
.Ar key-table .
|
||||
This may be used to configure multiple prefix keys, or to bind commands to
|
||||
sequences of keys.
|
||||
@ -1349,11 +1370,41 @@ bind-key -Troot a switch-client -Ttable1
|
||||
.Ed
|
||||
.El
|
||||
.Sh WINDOWS AND PANES
|
||||
A
|
||||
Each window displayed by
|
||||
.Nm
|
||||
window may be in one of two modes.
|
||||
The default permits direct access to the terminal attached to the window.
|
||||
The other is copy mode, which permits a section of a window or its
|
||||
may be split into one or more
|
||||
.Em panes ;
|
||||
each pane takes up a certain area of the display and is a separate terminal.
|
||||
A window may be split into panes using the
|
||||
.Ic split-window
|
||||
command.
|
||||
Windows may be split horizontally (with the
|
||||
.Fl h
|
||||
flag) or vertically.
|
||||
Panes may be resized with the
|
||||
.Ic resize-pane
|
||||
command (bound to
|
||||
.Ql C-Up ,
|
||||
.Ql C-Down
|
||||
.Ql C-Left
|
||||
and
|
||||
.Ql C-Right
|
||||
by default), the current pane may be changed with the
|
||||
.Ic select-pane
|
||||
command and the
|
||||
.Ic rotate-window
|
||||
and
|
||||
.Ic swap-pane
|
||||
commands may be used to swap panes without changing their position.
|
||||
Panes are numbered beginning from zero in the order they are created.
|
||||
.Pp
|
||||
By default, a
|
||||
.Nm
|
||||
pane permits direct access to the terminal contained in the pane.
|
||||
A pane may also be put into one of several modes:
|
||||
.Bl -dash -offset indent
|
||||
.It
|
||||
Copy mode, which permits a section of a window or its
|
||||
history to be copied to a
|
||||
.Em paste buffer
|
||||
for later insertion into another window.
|
||||
@ -1362,9 +1413,21 @@ This mode is entered with the
|
||||
command, bound to
|
||||
.Ql \&[
|
||||
by default.
|
||||
It is also entered when a command that produces output, such as
|
||||
.It
|
||||
View mode, which is like copy mode but is entered when a command that produces
|
||||
output, such as
|
||||
.Ic list-keys ,
|
||||
is executed from a key binding.
|
||||
.It
|
||||
Choose mode, which allows an item to be chosen from a list.
|
||||
This may be a client, a session or window or pane, or a buffer.
|
||||
This mode is entered with the
|
||||
.Ic choose-buffer ,
|
||||
.Ic choose-client
|
||||
and
|
||||
.Ic choose-tree
|
||||
commands.
|
||||
.El
|
||||
.Pp
|
||||
In copy mode an indicator is displayed in the top-right corner of the pane with
|
||||
the current position and the number of lines in the history.
|
||||
@ -1405,6 +1468,7 @@ The following commands are supported in copy mode:
|
||||
.It Li "copy-selection-no-clear [<prefix>]" Ta "" Ta ""
|
||||
.It Li "copy-selection-and-cancel [<prefix>]" Ta "Enter" Ta "M-w"
|
||||
.It Li "cursor-down" Ta "j" Ta "Down"
|
||||
.It Li "cursor-down-and-cancel" Ta "" Ta ""
|
||||
.It Li "cursor-left" Ta "h" Ta "Left"
|
||||
.It Li "cursor-right" Ta "l" Ta "Right"
|
||||
.It Li "cursor-up" Ta "k" Ta "Up"
|
||||
@ -1442,9 +1506,11 @@ The following commands are supported in copy mode:
|
||||
.It Li "scroll-up" Ta "C-y" Ta "C-Up"
|
||||
.It Li "search-again" Ta "n" Ta "n"
|
||||
.It Li "search-backward <for>" Ta "?" Ta ""
|
||||
.It Li "search-forward <for>" Ta "/" Ta ""
|
||||
.It Li "search-backward-incremental <for>" Ta "" Ta "C-r"
|
||||
.It Li "search-backward-text <for>" Ta "" Ta ""
|
||||
.It Li "search-forward <for>" Ta "/" Ta ""
|
||||
.It Li "search-forward-incremental <for>" Ta "" Ta "C-s"
|
||||
.It Li "search-forward-text <for>" Ta "" Ta ""
|
||||
.It Li "search-reverse" Ta "N" Ta "N"
|
||||
.It Li "select-line" Ta "V" Ta ""
|
||||
.It Li "select-word" Ta "" Ta ""
|
||||
@ -1453,6 +1519,26 @@ The following commands are supported in copy mode:
|
||||
.It Li "top-line" Ta "H" Ta "M-R"
|
||||
.El
|
||||
.Pp
|
||||
The search commands come in several varieties:
|
||||
.Ql search-forward
|
||||
and
|
||||
.Ql search-backward
|
||||
search for a regular expression;
|
||||
the
|
||||
.Ql -text
|
||||
variants search for a plain text string rather than a regular expression;
|
||||
.Ql -incremental
|
||||
perform an incremental search and expect to be used with the
|
||||
.Fl i
|
||||
flag to the
|
||||
.Ic command-prompt
|
||||
command.
|
||||
.Ql search-again
|
||||
repeats the last search and
|
||||
.Ql search-reverse
|
||||
does the same but reverses the direction (forward becomes backward and backward
|
||||
becomes forward).
|
||||
.Pp
|
||||
Copy commands may take an optional buffer prefix argument which is used
|
||||
to generate the buffer name (the default is
|
||||
.Ql buffer
|
||||
@ -1504,7 +1590,7 @@ The synopsis for the
|
||||
command is:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo Ic copy-mode
|
||||
.Op Fl Meu
|
||||
.Op Fl eHMqu
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
Enter copy mode.
|
||||
@ -1514,6 +1600,11 @@ option scrolls one page up.
|
||||
.Fl M
|
||||
begins a mouse drag (only valid if bound to a mouse key binding, see
|
||||
.Sx MOUSE SUPPORT ) .
|
||||
.Fl H
|
||||
hides the position indicator in the top right.
|
||||
.Fl q
|
||||
cancels copy mode and any other modes.
|
||||
.Pp
|
||||
.Fl e
|
||||
specifies that scrolling to the bottom of the history (to the visible screen)
|
||||
should exit copy mode.
|
||||
@ -1526,37 +1617,7 @@ bind PageUp copy-mode -eu
|
||||
.Ed
|
||||
.El
|
||||
.Pp
|
||||
Each window displayed by
|
||||
.Nm
|
||||
may be split into one or more
|
||||
.Em panes ;
|
||||
each pane takes up a certain area of the display and is a separate terminal.
|
||||
A window may be split into panes using the
|
||||
.Ic split-window
|
||||
command.
|
||||
Windows may be split horizontally (with the
|
||||
.Fl h
|
||||
flag) or vertically.
|
||||
Panes may be resized with the
|
||||
.Ic resize-pane
|
||||
command (bound to
|
||||
.Ql C-Up ,
|
||||
.Ql C-Down
|
||||
.Ql C-Left
|
||||
and
|
||||
.Ql C-Right
|
||||
by default), the current pane may be changed with the
|
||||
.Ic select-pane
|
||||
command and the
|
||||
.Ic rotate-window
|
||||
and
|
||||
.Ic swap-pane
|
||||
commands may be used to swap panes without changing their position.
|
||||
Panes are numbered beginning from zero in the order they are created.
|
||||
.Pp
|
||||
A number of preset
|
||||
.Em layouts
|
||||
are available.
|
||||
A number of preset arrangements of panes are available, these are called layouts.
|
||||
These may be selected with the
|
||||
.Ic select-layout
|
||||
command or cycled with
|
||||
@ -1635,7 +1696,7 @@ By default, it uses the format
|
||||
but a different format may be specified with
|
||||
.Fl F .
|
||||
.It Xo Ic capture-pane
|
||||
.Op Fl aepPqCJ
|
||||
.Op Fl aepPqCJN
|
||||
.Op Fl b Ar buffer-name
|
||||
.Op Fl E Ar end-line
|
||||
.Op Fl S Ar start-line
|
||||
@ -1660,8 +1721,10 @@ is given, the output includes escape sequences for text and background
|
||||
attributes.
|
||||
.Fl C
|
||||
also escapes non-printable characters as octal \exxx.
|
||||
.Fl N
|
||||
preserves trailing spaces at each line's end and
|
||||
.Fl J
|
||||
joins wrapped lines and preserves trailing spaces at each line's end.
|
||||
preserves trailing spaces and joins any wrapped lines.
|
||||
.Fl P
|
||||
captures only any output that the pane has received that is the beginning of an
|
||||
as-yet incomplete escape sequence.
|
||||
@ -1680,7 +1743,7 @@ the end of the visible pane.
|
||||
The default is to capture only the visible contents of the pane.
|
||||
.It Xo
|
||||
.Ic choose-client
|
||||
.Op Fl NZ
|
||||
.Op Fl NrZ
|
||||
.Op Fl F Ar format
|
||||
.Op Fl f Ar filter
|
||||
.Op Fl O Ar sort-order
|
||||
@ -1709,7 +1772,8 @@ The following keys may be used in client mode:
|
||||
.It Li "z" Ta "Suspend selected client"
|
||||
.It Li "Z" Ta "Suspend tagged clients"
|
||||
.It Li "f" Ta "Enter a format to filter items"
|
||||
.It Li "O" Ta "Change sort order"
|
||||
.It Li "O" Ta "Change sort field"
|
||||
.It Li "r" Ta "Reverse sort order"
|
||||
.It Li "v" Ta "Toggle preview"
|
||||
.It Li "q" Ta "Exit mode"
|
||||
.El
|
||||
@ -1724,12 +1788,14 @@ If
|
||||
is not given, "detach-client -t '%%'" is used.
|
||||
.Pp
|
||||
.Fl O
|
||||
specifies the initial sort order: one of
|
||||
specifies the initial sort field: one of
|
||||
.Ql name ,
|
||||
.Ql size ,
|
||||
.Ql creation ,
|
||||
or
|
||||
.Ql activity .
|
||||
.Fl r
|
||||
reverses the sort order.
|
||||
.Fl f
|
||||
specifies an initial filter: the filter is a format - if it evaluates to zero,
|
||||
the item in the list is not shown, otherwise it is shown.
|
||||
@ -1741,7 +1807,7 @@ starts without the preview.
|
||||
This command works only if at least one client is attached.
|
||||
.It Xo
|
||||
.Ic choose-tree
|
||||
.Op Fl GNswZ
|
||||
.Op Fl GNrswZ
|
||||
.Op Fl F Ar format
|
||||
.Op Fl f Ar filter
|
||||
.Op Fl O Ar sort-order
|
||||
@ -1773,7 +1839,8 @@ The following keys may be used in tree mode:
|
||||
.It Li "C-t" Ta "Tag all items"
|
||||
.It Li "\&:" Ta "Run a command for each tagged item"
|
||||
.It Li "f" Ta "Enter a format to filter items"
|
||||
.It Li "O" Ta "Change sort order"
|
||||
.It Li "O" Ta "Change sort field"
|
||||
.It Li "r" Ta "Reverse sort order"
|
||||
.It Li "v" Ta "Toggle preview"
|
||||
.It Li "q" Ta "Exit mode"
|
||||
.El
|
||||
@ -1788,11 +1855,13 @@ If
|
||||
is not given, "switch-client -t '%%'" is used.
|
||||
.Pp
|
||||
.Fl O
|
||||
specifies the initial sort order: one of
|
||||
specifies the initial sort field: one of
|
||||
.Ql index ,
|
||||
.Ql name ,
|
||||
or
|
||||
.Ql time .
|
||||
.Fl r
|
||||
reverses the sort order.
|
||||
.Fl f
|
||||
specifies an initial filter: the filter is a format - if it evaluates to zero,
|
||||
the item in the list is not shown, otherwise it is shown.
|
||||
@ -1871,10 +1940,8 @@ zooms the pane.
|
||||
.Pp
|
||||
This command works only if at least one client is attached.
|
||||
.It Xo Ic join-pane
|
||||
.Op Fl bdhv
|
||||
.Oo Fl l
|
||||
.Ar size |
|
||||
.Fl p Ar percentage Oc
|
||||
.Op Fl bdfhv
|
||||
.Op Fl l Ar size
|
||||
.Op Fl s Ar src-pane
|
||||
.Op Fl t Ar dst-pane
|
||||
.Xc
|
||||
@ -1925,11 +1992,13 @@ The
|
||||
option kills all but the window given with
|
||||
.Fl t .
|
||||
.It Xo Ic last-pane
|
||||
.Op Fl de
|
||||
.Op Fl deZ
|
||||
.Op Fl t Ar target-window
|
||||
.Xc
|
||||
.D1 (alias: Ic lastp )
|
||||
Select the last (previously selected) pane.
|
||||
.Fl Z
|
||||
keeps the window zoomed if it was zoomed.
|
||||
.Fl e
|
||||
enables or
|
||||
.Fl d
|
||||
@ -2009,9 +2078,7 @@ flag, see the
|
||||
section.
|
||||
.It Xo Ic move-pane
|
||||
.Op Fl bdhv
|
||||
.Oo Fl l
|
||||
.Ar size |
|
||||
.Fl p Ar percentage Oc
|
||||
.Op Fl l Ar size
|
||||
.Op Fl s Ar src-pane
|
||||
.Op Fl t Ar dst-pane
|
||||
.Xc
|
||||
@ -2220,8 +2287,14 @@ or
|
||||
.Fl y .
|
||||
The
|
||||
.Ar adjustment
|
||||
is given in lines or cells (the default is 1).
|
||||
.Pp
|
||||
is given in lines or columns (the default is 1);
|
||||
.Fl x
|
||||
and
|
||||
.Fl y
|
||||
may be a given as a number of lines or columns or followed by
|
||||
.Ql %
|
||||
for a percentage of the window size (for example
|
||||
.Ql -x 10% ) .
|
||||
With
|
||||
.Fl Z ,
|
||||
the active pane is toggled between zoomed (occupying the whole of the window)
|
||||
@ -2311,7 +2384,7 @@ option has the same meaning as for the
|
||||
.Ic new-window
|
||||
command.
|
||||
.It Xo Ic rotate-window
|
||||
.Op Fl DU
|
||||
.Op Fl DUZ
|
||||
.Op Fl t Ar target-window
|
||||
.Xc
|
||||
.D1 (alias: Ic rotatew )
|
||||
@ -2319,6 +2392,8 @@ Rotate the positions of the panes within a window, either upward (numerically
|
||||
lower) with
|
||||
.Fl U
|
||||
or downward (numerically higher).
|
||||
.Fl Z
|
||||
keeps the window zoomed if it was zoomed.
|
||||
.It Xo Ic select-layout
|
||||
.Op Fl Enop
|
||||
.Op Fl t Ar target-pane
|
||||
@ -2342,7 +2417,7 @@ applies the last set layout if possible (undoes the most recent layout change).
|
||||
.Fl E
|
||||
spreads the current pane and any panes next to it out evenly.
|
||||
.It Xo Ic select-pane
|
||||
.Op Fl DdeLlMmRU
|
||||
.Op Fl DdeLlMmRUZ
|
||||
.Op Fl T Ar title
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
@ -2359,6 +2434,8 @@ or
|
||||
.Fl U
|
||||
is used, respectively the pane below, to the left, to the right, or above the
|
||||
target pane is used.
|
||||
.Fl Z
|
||||
keeps the window zoomed if it was zoomed.
|
||||
.Fl l
|
||||
is the same as using the
|
||||
.Ic last-pane
|
||||
@ -2409,9 +2486,7 @@ the command behaves like
|
||||
.Op Fl bdfhIvP
|
||||
.Op Fl c Ar start-directory
|
||||
.Op Fl e Ar environment
|
||||
.Oo Fl l
|
||||
.Ar size |
|
||||
.Fl p Ar percentage Oc
|
||||
.Op Fl l Ar size
|
||||
.Op Fl t Ar target-pane
|
||||
.Op Ar shell-command
|
||||
.Op Fl F Ar format
|
||||
@ -2427,10 +2502,12 @@ a vertical split; if neither is specified,
|
||||
is assumed.
|
||||
The
|
||||
.Fl l
|
||||
and
|
||||
.Fl p
|
||||
options specify the size of the new pane in lines (for vertical split) or in
|
||||
cells (for horizontal split), or as a percentage, respectively.
|
||||
option specifies the size of the new pane in lines (for vertical split) or in
|
||||
columns (for horizontal split);
|
||||
.Ar size
|
||||
may be followed by
|
||||
.Ql %
|
||||
to specify a percentage of the available space.
|
||||
The
|
||||
.Fl b
|
||||
option causes the new pane to be created to the left of or above
|
||||
@ -2464,7 +2541,7 @@ All other options have the same meaning as for the
|
||||
.Ic new-window
|
||||
command.
|
||||
.It Xo Ic swap-pane
|
||||
.Op Fl dDU
|
||||
.Op Fl dDUZ
|
||||
.Op Fl s Ar src-pane
|
||||
.Op Fl t Ar dst-pane
|
||||
.Xc
|
||||
@ -2481,7 +2558,9 @@ swaps with the next pane (after it numerically).
|
||||
.Fl d
|
||||
instructs
|
||||
.Nm
|
||||
not to change the active pane.
|
||||
not to change the active pane and
|
||||
.Fl Z
|
||||
keeps the window zoomed if it was zoomed.
|
||||
.Pp
|
||||
If
|
||||
.Fl s
|
||||
@ -2500,10 +2579,11 @@ This is similar to
|
||||
except the source and destination windows are swapped.
|
||||
It is an error if no window exists at
|
||||
.Ar src-window .
|
||||
If
|
||||
.Fl d
|
||||
is given, the new window does not become the current window.
|
||||
.Pp
|
||||
Like
|
||||
.Ic swap-pane ,
|
||||
if
|
||||
If
|
||||
.Fl s
|
||||
is omitted and a marked pane is present (see
|
||||
.Ic select-pane
|
||||
@ -2571,10 +2651,15 @@ bind-key '"' split-window
|
||||
bind-key "'" new-window
|
||||
.Ed
|
||||
.Pp
|
||||
A command bound to the
|
||||
.Em Any
|
||||
key will execute for all keys which do not have a more specific binding.
|
||||
.Pp
|
||||
Commands related to key bindings are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo Ic bind-key
|
||||
.Op Fl nr
|
||||
.Op Fl N Ar note
|
||||
.Op Fl T Ar key-table
|
||||
.Ar key Ar command Op Ar arguments
|
||||
.Xc
|
||||
@ -2622,24 +2707,51 @@ The
|
||||
flag indicates this key may repeat, see the
|
||||
.Ic repeat-time
|
||||
option.
|
||||
.Fl N
|
||||
attaches a note to the key (shown with
|
||||
.Ic list-keys
|
||||
.Fl N ) .
|
||||
.Pp
|
||||
To view the default bindings and possible commands, see the
|
||||
.Ic list-keys
|
||||
command.
|
||||
.It Xo Ic list-keys
|
||||
.Op Fl T Ar key-table
|
||||
.Op Fl 1aN
|
||||
.Op Fl P Ar prefix-string Fl T Ar key-table
|
||||
.Op Ar key
|
||||
.Xc
|
||||
.D1 (alias: Ic lsk )
|
||||
List all key bindings.
|
||||
Without
|
||||
List key bindings.
|
||||
There are two forms: the default lists keys as
|
||||
.Ic bind-key
|
||||
commands;
|
||||
.Fl N
|
||||
lists only keys with attached notes and shows only the key and note for each
|
||||
key.
|
||||
.Pp
|
||||
With the default form, all key tables are listed by default.
|
||||
.Fl T
|
||||
all key tables are printed.
|
||||
With
|
||||
.Fl T
|
||||
only
|
||||
lists only keys in
|
||||
.Ar key-table .
|
||||
.Pp
|
||||
With the
|
||||
.Fl N
|
||||
form, only keys in the
|
||||
.Em root
|
||||
and
|
||||
.Em prefix
|
||||
key tables are listed by default;
|
||||
.Fl T
|
||||
also lists only keys in
|
||||
.Ar key-table .
|
||||
.Fl P
|
||||
specifies a prefix to print before each key and
|
||||
.Fl 1
|
||||
lists only the first matching key.
|
||||
.Fl a
|
||||
lists the command for keys that do have a note rather than skipping them.
|
||||
.It Xo Ic send-keys
|
||||
.Op Fl HlMRX
|
||||
.Op Fl FHlMRX
|
||||
.Op Fl N Ar repeat-count
|
||||
.Op Fl t Ar target-pane
|
||||
.Ar key Ar ...
|
||||
@ -2678,7 +2790,9 @@ the
|
||||
.Sx WINDOWS AND PANES
|
||||
section.
|
||||
.Fl N
|
||||
specifies a repeat count.
|
||||
specifies a repeat count and
|
||||
.Fl F
|
||||
expands formats in arguments where appropriate.
|
||||
.It Xo Ic send-prefix
|
||||
.Op Fl 2
|
||||
.Op Fl t Ar target-pane
|
||||
@ -2716,7 +2830,7 @@ and
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
server has a set of global options which do not apply to any particular
|
||||
server has a set of global server options which do not apply to any particular
|
||||
window or session or pane.
|
||||
These are altered with the
|
||||
.Ic set-option
|
||||
@ -2890,6 +3004,10 @@ omitted to toggle).
|
||||
.Pp
|
||||
Available server options are:
|
||||
.Bl -tag -width Ds
|
||||
.It Ic backspace Ar key
|
||||
Set the key sent by
|
||||
.Nm
|
||||
for backspace.
|
||||
.It Ic buffer-limit Ar number
|
||||
Set the number of buffers; as new buffers are added to the top of the stack,
|
||||
old ones are removed from the bottom if necessary to maintain this maximum
|
||||
@ -3632,7 +3750,7 @@ see the
|
||||
section.
|
||||
.Pp
|
||||
.It Xo Ic window-size
|
||||
.Ar largest | Ar smallest | Ar manual
|
||||
.Ar largest | Ar smallest | Ar manual | Ar latest
|
||||
.Xc
|
||||
Configure how
|
||||
.Nm
|
||||
@ -3647,6 +3765,10 @@ If
|
||||
the size of a new window is set from the
|
||||
.Ic default-size
|
||||
option and windows are resized automatically.
|
||||
With
|
||||
.Ar latest ,
|
||||
.Nm
|
||||
uses the size of the client that had the most recent activity.
|
||||
See also the
|
||||
.Ic resize-window
|
||||
command and the
|
||||
@ -4058,9 +4180,15 @@ appended or prepended to the string if the length has been trimmed, for example
|
||||
will append
|
||||
.Ql ...
|
||||
if the pane title is more than five characters.
|
||||
Similarly,
|
||||
.Ql p
|
||||
pads the string to a given width, for example
|
||||
.Ql #{p10:pane_title}
|
||||
will result in a width of at least 10 characters.
|
||||
A positive width pads on the left, a negative on the right.
|
||||
.Pp
|
||||
Prefixing a time variable with
|
||||
.Ql t:
|
||||
.Ql t:\&
|
||||
will convert it to a string, so if
|
||||
.Ql #{window_activity}
|
||||
gives
|
||||
@ -4069,34 +4197,34 @@ gives
|
||||
gives
|
||||
.Ql Sun Oct 25 09:25:02 2015 .
|
||||
The
|
||||
.Ql b:
|
||||
.Ql b:\&
|
||||
and
|
||||
.Ql d:
|
||||
.Ql d:\&
|
||||
prefixes are
|
||||
.Xr basename 3
|
||||
and
|
||||
.Xr dirname 3
|
||||
of the variable respectively.
|
||||
.Ql q:
|
||||
.Ql q:\&
|
||||
will escape
|
||||
.Xr sh 1
|
||||
special characters.
|
||||
.Ql E:
|
||||
.Ql E:\&
|
||||
will expand the format twice, for example
|
||||
.Ql #{E:status-left}
|
||||
is the result of expanding the content of the
|
||||
.Ic status-left
|
||||
option rather than the option itself.
|
||||
.Ql T:
|
||||
.Ql T:\&
|
||||
is like
|
||||
.Ql E:
|
||||
.Ql E:\&
|
||||
but also expands
|
||||
.Xr strftime 3
|
||||
specifiers.
|
||||
.Ql S: ,
|
||||
.Ql W:
|
||||
.Ql S:\& ,
|
||||
.Ql W:\&
|
||||
or
|
||||
.Ql P:
|
||||
.Ql P:\&
|
||||
will loop over each session, window or pane and insert the format once
|
||||
for each.
|
||||
For windows and panes, two comma-separated formats may be given:
|
||||
@ -4107,7 +4235,7 @@ For example, to get a list of windows formatted like the status line:
|
||||
.Ed
|
||||
.Pp
|
||||
A prefix of the form
|
||||
.Ql s/foo/bar/:
|
||||
.Ql s/foo/bar/:\&
|
||||
will substitute
|
||||
.Ql foo
|
||||
with
|
||||
@ -4116,7 +4244,7 @@ throughout.
|
||||
The first argument may be an extended regular expression and a final argument may be
|
||||
.Ql i
|
||||
to ignore case, for example
|
||||
.Ql s/a(.)/\e1x/i:
|
||||
.Ql s/a(.)/\e1x/i:\&
|
||||
would change
|
||||
.Ql abABab
|
||||
into
|
||||
@ -4160,6 +4288,8 @@ The following variables are available, where appropriate:
|
||||
.It Li "buffer_sample" Ta "" Ta "Sample of start of buffer"
|
||||
.It Li "buffer_size" Ta "" Ta "Size of the specified buffer in bytes"
|
||||
.It Li "client_activity" Ta "" Ta "Time client last had activity"
|
||||
.It Li "client_cell_height" Ta "" Ta "Height of each client cell in pixels"
|
||||
.It Li "client_cell_width" Ta "" Ta "Width of each client cell in pixels"
|
||||
.It Li "client_control_mode" Ta "" Ta "1 if client is in control mode"
|
||||
.It Li "client_created" Ta "" Ta "Time client created"
|
||||
.It Li "client_discarded" Ta "" Ta "Bytes discarded when client behind"
|
||||
@ -4172,15 +4302,18 @@ The following variables are available, where appropriate:
|
||||
.It Li "client_readonly" Ta "" Ta "1 if client is readonly"
|
||||
.It Li "client_session" Ta "" Ta "Name of the client's session"
|
||||
.It Li "client_termname" Ta "" Ta "Terminal name of client"
|
||||
.It Li "client_termtype" Ta "" Ta "Terminal type of client"
|
||||
.It Li "client_tty" Ta "" Ta "Pseudo terminal of client"
|
||||
.It Li "client_utf8" Ta "" Ta "1 if client supports utf8"
|
||||
.It Li "client_utf8" Ta "" Ta "1 if client supports UTF-8"
|
||||
.It Li "client_width" Ta "" Ta "Width of client"
|
||||
.It Li "client_written" Ta "" Ta "Bytes written to client"
|
||||
.It Li "command" Ta "" Ta "Name of command in use, if any"
|
||||
.It Li "command_list_alias" Ta "" Ta "Command alias if listing commands"
|
||||
.It Li "command_list_name" Ta "" Ta "Command name if listing commands"
|
||||
.It Li "command_list_usage" Ta "" Ta "Command usage if listing commands"
|
||||
.It Li "copy_cursor_line" Ta "" Ta "Line the cursor is on in copy mode"
|
||||
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
||||
.It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode"
|
||||
.It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode"
|
||||
.It Li "cursor_character" Ta "" Ta "Character at cursor in pane"
|
||||
.It Li "cursor_flag" Ta "" Ta "Pane cursor flag"
|
||||
.It Li "cursor_x" Ta "" Ta "Cursor X position in pane"
|
||||
@ -4221,7 +4354,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "pane_current_path" Ta "" Ta "Current path if available"
|
||||
.It Li "pane_dead" Ta "" Ta "1 if pane is dead"
|
||||
.It Li "pane_dead_status" Ta "" Ta "Exit status of process in dead pane"
|
||||
.It Li "pane_format" Ta "" Ta "1 if format is for a pane (not assuming the current)"
|
||||
.It Li "pane_format" Ta "" Ta "1 if format is for a pane"
|
||||
.It Li "pane_height" Ta "" Ta "Height of pane"
|
||||
.It Li "pane_id" Ta "#D" Ta "Unique pane ID"
|
||||
.It Li "pane_in_mode" Ta "" Ta "1 if pane is in a mode"
|
||||
@ -4231,6 +4364,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
||||
.It Li "pane_marked_set" Ta "" Ta "1 if a marked pane is set"
|
||||
.It Li "pane_mode" Ta "" Ta "Name of pane mode, if any"
|
||||
.It Li "pane_path" Ta "#T" Ta "Path of pane (can be set by application)"
|
||||
.It Li "pane_pid" Ta "" Ta "PID of first process in pane"
|
||||
.It Li "pane_pipe" Ta "" Ta "1 if pane is being piped"
|
||||
.It Li "pane_right" Ta "" Ta "Right of pane"
|
||||
@ -4238,7 +4372,7 @@ The following variables are available, where appropriate:
|
||||
.It Li "pane_start_command" Ta "" Ta "Command pane started with"
|
||||
.It Li "pane_synchronized" Ta "" Ta "1 if pane is synchronized"
|
||||
.It Li "pane_tabs" Ta "" Ta "Pane tab positions"
|
||||
.It Li "pane_title" Ta "#T" Ta "Title of pane"
|
||||
.It Li "pane_title" Ta "#T" Ta "Title of pane (can be set by application)"
|
||||
.It Li "pane_top" Ta "" Ta "Top of pane"
|
||||
.It Li "pane_tty" Ta "" Ta "Pseudo terminal of pane"
|
||||
.It Li "pane_width" Ta "" Ta "Width of pane"
|
||||
@ -4247,14 +4381,23 @@ The following variables are available, where appropriate:
|
||||
.It Li "scroll_position" Ta "" Ta "Scroll position in copy mode"
|
||||
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
|
||||
.It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
|
||||
.It Li "selection_active" Ta "" Ta "1 if selection started and changes with the cursor in copy mode"
|
||||
.It Li "selection_end_x" Ta "" Ta "X position of the end of the selection"
|
||||
.It Li "selection_end_y" Ta "" Ta "Y position of the end of the selection"
|
||||
.It Li "selection_present" Ta "" Ta "1 if selection started in copy mode"
|
||||
.It Li "selection_start_x" Ta "" Ta "X position of the start of the selection"
|
||||
.It Li "selection_start_y" Ta "" Ta "Y position of the start of the selection"
|
||||
.It Li "session_activity" Ta "" Ta "Time of session last activity"
|
||||
.It Li "session_alerts" Ta "" Ta "List of window indexes with alerts"
|
||||
.It Li "session_attached" Ta "" Ta "Number of clients session is attached to"
|
||||
.It Li "session_attached_list" Ta "" Ta "List of clients session is attached to"
|
||||
.It Li "session_created" Ta "" Ta "Time session created"
|
||||
.It Li "session_format" Ta "" Ta "1 if format is for a session (not assuming the current)"
|
||||
.It Li "session_format" Ta "" Ta "1 if format is for a session"
|
||||
.It Li "session_group" Ta "" Ta "Name of session group"
|
||||
.It Li "session_group_attached" Ta "" Ta "Number of clients sessions in group are attached to"
|
||||
.It Li "session_group_attached_list" Ta "" Ta "List of clients sessions in group are attached to"
|
||||
.It Li "session_group_list" Ta "" Ta "List of sessions in group"
|
||||
.It Li "session_group_many_attached" Ta "" Ta "1 if multiple clients attached to sessions in group"
|
||||
.It Li "session_group_size" Ta "" Ta "Size of session group"
|
||||
.It Li "session_grouped" Ta "" Ta "1 if session in a group"
|
||||
.It Li "session_id" Ta "" Ta "Unique session ID"
|
||||
@ -4267,19 +4410,28 @@ The following variables are available, where appropriate:
|
||||
.It Li "start_time" Ta "" Ta "Server start time"
|
||||
.It Li "version" Ta "" Ta "Server version"
|
||||
.It Li "window_active" Ta "" Ta "1 if window active"
|
||||
.It Li "window_active_clients" Ta "" Ta "Number of clients viewing this window"
|
||||
.It Li "window_active_clients_list" Ta "" Ta "List of clients viewing this window"
|
||||
.It Li "window_active_sessions" Ta "" Ta "Number of sessions on which this window is active"
|
||||
.It Li "window_active_sessions_list" Ta "" Ta "List of sessions on which this window is active"
|
||||
.It Li "window_activity" Ta "" Ta "Time of window last activity"
|
||||
.It Li "window_activity_flag" Ta "" Ta "1 if window has activity"
|
||||
.It Li "window_bell_flag" Ta "" Ta "1 if window has bell"
|
||||
.It Li "window_bigger" Ta "" Ta "1 if window is larger than client"
|
||||
.It Li "window_cell_height" Ta "" Ta "Height of each cell in pixels"
|
||||
.It Li "window_cell_width" Ta "" Ta "Width of each cell in pixels"
|
||||
.It Li "window_end_flag" Ta "" Ta "1 if window has the highest index"
|
||||
.It Li "window_flags" Ta "#F" Ta "Window flags"
|
||||
.It Li "window_format" Ta "" Ta "1 if format is for a window (not assuming the current)"
|
||||
.It Li "window_format" Ta "" Ta "1 if format is for a window"
|
||||
.It Li "window_height" Ta "" Ta "Height of window"
|
||||
.It Li "window_id" Ta "" Ta "Unique window ID"
|
||||
.It Li "window_index" Ta "#I" Ta "Index of window"
|
||||
.It Li "window_last_flag" Ta "" Ta "1 if window is the last used"
|
||||
.It Li "window_layout" Ta "" Ta "Window layout description, ignoring zoomed window panes"
|
||||
.It Li "window_linked" Ta "" Ta "1 if window is linked across sessions"
|
||||
.It Li "window_linked_sessions" Ta "" Ta "Number of sessions this window is linked to"
|
||||
.It Li "window_linked_sessions_list" Ta "" Ta "List of sessions this window is linked to"
|
||||
.It Li "window_marked_flag" Ta "" Ta "1 if window contains the marked pane"
|
||||
.It Li "window_name" Ta "#W" Ta "Name of window"
|
||||
.It Li "window_offset_x" Ta "" Ta "X offset into window if larger than client"
|
||||
.It Li "window_offset_y" Ta "" Ta "Y offset into window if larger than client"
|
||||
@ -4299,7 +4451,7 @@ interface, for example
|
||||
.Ic status-style
|
||||
for the status line.
|
||||
In addition, embedded styles may be specified in format options, such as
|
||||
.Ic status-left-format ,
|
||||
.Ic status-left ,
|
||||
by enclosing them in
|
||||
.Ql #[
|
||||
and
|
||||
@ -4307,7 +4459,9 @@ and
|
||||
.Pp
|
||||
A style may be the single term
|
||||
.Ql default
|
||||
to specify the default style (which may inherit from another option) or a space
|
||||
to specify the default style (which may come from an option, for example
|
||||
.Ic status-style
|
||||
in the status line) or a space
|
||||
or comma separated list of the following:
|
||||
.Bl -tag -width Ds
|
||||
.It Ic fg=colour
|
||||
@ -4386,6 +4540,20 @@ and
|
||||
.Ic list=right-marker
|
||||
mark the text to be used to mark that text has been trimmed from the left or
|
||||
right of the list if there is not enough space.
|
||||
.It Xo Ic push-default ,
|
||||
.Ic pop-default
|
||||
.Xc
|
||||
Store the current colours and attributes as the default or reset to the previous
|
||||
default.
|
||||
A
|
||||
.Ic push-default
|
||||
affects any subsequent use of the
|
||||
.Ic default
|
||||
term until a
|
||||
.Ic pop-default .
|
||||
Only one default may be pushed (each
|
||||
.Ic push-default
|
||||
replaces the previous saved default).
|
||||
.It Xo Ic range=left ,
|
||||
.Ic range=right ,
|
||||
.Ic range=window|X ,
|
||||
@ -4602,7 +4770,7 @@ session option.
|
||||
Commands related to the status line are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo Ic command-prompt
|
||||
.Op Fl 1Ni
|
||||
.Op Fl 1ikN
|
||||
.Op Fl I Ar inputs
|
||||
.Op Fl p Ar prompts
|
||||
.Op Fl t Ar target-client
|
||||
@ -4652,6 +4820,10 @@ but any quotation marks are escaped.
|
||||
.Fl 1
|
||||
makes the prompt only accept one key press, in this case the resulting input
|
||||
is a single character.
|
||||
.Fl k
|
||||
is like
|
||||
.Fl 1
|
||||
but the key press is translated to a key name.
|
||||
.Fl N
|
||||
makes the prompt only accept numeric key presses.
|
||||
.Fl i
|
||||
@ -4815,7 +4987,7 @@ When the
|
||||
option is reached, the oldest automatically named buffer is deleted.
|
||||
Explicitly named buffers are not subject to
|
||||
.Ic buffer-limit
|
||||
and may be deleted with
|
||||
and may be deleted with the
|
||||
.Ic delete-buffer
|
||||
command.
|
||||
.Pp
|
||||
@ -4842,7 +5014,7 @@ The buffer commands are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Ic choose-buffer
|
||||
.Op Fl NZ
|
||||
.Op Fl NZr
|
||||
.Op Fl F Ar format
|
||||
.Op Fl f Ar filter
|
||||
.Op Fl O Ar sort-order
|
||||
@ -4869,7 +5041,8 @@ The following keys may be used in buffer mode:
|
||||
.It Li "d" Ta "Delete selected buffer"
|
||||
.It Li "D" Ta "Delete tagged buffers"
|
||||
.It Li "f" Ta "Enter a format to filter items"
|
||||
.It Li "O" Ta "Change sort order"
|
||||
.It Li "O" Ta "Change sort field"
|
||||
.It Li "r" Ta "Reverse sort order"
|
||||
.It Li "v" Ta "Toggle preview"
|
||||
.It Li "q" Ta "Exit mode"
|
||||
.El
|
||||
@ -4884,11 +5057,13 @@ If
|
||||
is not given, "paste-buffer -b '%%'" is used.
|
||||
.Pp
|
||||
.Fl O
|
||||
specifies the initial sort order: one of
|
||||
specifies the initial sort field: one of
|
||||
.Ql time ,
|
||||
.Ql name
|
||||
or
|
||||
.Ql size .
|
||||
.Fl r
|
||||
reverses the sort order.
|
||||
.Fl f
|
||||
specifies an initial filter: the filter is a format - if it evaluates to zero,
|
||||
the item in the list is not shown, otherwise it is shown.
|
||||
@ -5058,6 +5233,37 @@ channel are made to wait until the channel is unlocked with
|
||||
.Ic wait-for
|
||||
.Fl U .
|
||||
.El
|
||||
.Sh EXIT MESSAGES
|
||||
When a
|
||||
.Nm
|
||||
client detaches, it prints a message.
|
||||
This may be one of:
|
||||
.Bl -tag -width Ds
|
||||
.It [detached (from session ...)]
|
||||
The client was detached normally.
|
||||
.It [detached and SIGHUP]
|
||||
The client was detached and its parent sent the
|
||||
.Dv SIGHUP
|
||||
signal (for example with
|
||||
.Ic detach-client
|
||||
.Fl P ) .
|
||||
.It [lost tty]
|
||||
The client's
|
||||
.Xr tty 4
|
||||
or
|
||||
.Xr pty 4
|
||||
was unexpectedly destroyed.
|
||||
.It [terminated]
|
||||
The client was killed with
|
||||
.Dv SIGTERM .
|
||||
.It [exited]
|
||||
The server exited when it had no sessions.
|
||||
.It [server exited]
|
||||
The server exited when it received
|
||||
.Dv SIGTERM .
|
||||
.It [server exited unexpectedly]
|
||||
The server crashed or otherwise exited without telling the client the reason.
|
||||
.El
|
||||
.Sh TERMINFO EXTENSIONS
|
||||
.Nm
|
||||
understands some unofficial extensions to
|
||||
|
16
external/bsd/tmux/dist/tmux.c
vendored
16
external/bsd/tmux/dist/tmux.c
vendored
@ -18,6 +18,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <event.h>
|
||||
@ -127,6 +128,7 @@ make_label(const char *label, char **cause)
|
||||
free(base);
|
||||
goto fail;
|
||||
}
|
||||
free(base);
|
||||
|
||||
if (mkdir(resolved, S_IRWXU) != 0 && errno != EEXIST)
|
||||
goto fail;
|
||||
@ -208,6 +210,12 @@ find_home(void)
|
||||
return (home);
|
||||
}
|
||||
|
||||
const char *
|
||||
getversion(void)
|
||||
{
|
||||
return TMUX_VERSION;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -234,7 +242,7 @@ main(int argc, char **argv)
|
||||
flags = 0;
|
||||
|
||||
label = path = NULL;
|
||||
while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUVv")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUvV")) != -1) {
|
||||
switch (opt) {
|
||||
case '2':
|
||||
flags |= CLIENT_256COLOURS;
|
||||
@ -248,12 +256,12 @@ main(int argc, char **argv)
|
||||
else
|
||||
flags |= CLIENT_CONTROL;
|
||||
break;
|
||||
case 'V':
|
||||
printf("%s %s\n", getprogname(), VERSION);
|
||||
exit(0);
|
||||
case 'f':
|
||||
set_cfg_file(optarg);
|
||||
break;
|
||||
case 'V':
|
||||
printf("%s %s\n", getprogname(), getversion());
|
||||
exit(0);
|
||||
case 'l':
|
||||
flags |= CLIENT_LOGIN;
|
||||
break;
|
||||
|
217
external/bsd/tmux/dist/tmux.h
vendored
217
external/bsd/tmux/dist/tmux.h
vendored
@ -62,9 +62,9 @@ struct winlink;
|
||||
/* Client-server protocol version. */
|
||||
#define PROTOCOL_VERSION 8
|
||||
|
||||
/* Default global configuration file. */
|
||||
/* Default configuration files. */
|
||||
#ifndef TMUX_CONF
|
||||
#define TMUX_CONF "/etc/tmux.conf"
|
||||
#define TMUX_CONF "/etc/tmux.conf:~/.tmux.conf"
|
||||
#endif
|
||||
|
||||
/* Minimum layout cell size, NOT including border lines. */
|
||||
@ -80,6 +80,10 @@ struct winlink;
|
||||
/* Maximum size of data to hold from a pane. */
|
||||
#define READ_SIZE 4096
|
||||
|
||||
/* Default pixel cell sizes. */
|
||||
#define DEFAULT_XPIXEL 16
|
||||
#define DEFAULT_YPIXEL 32
|
||||
|
||||
/* Attribute to make GCC check printf-like arguments. */
|
||||
#define printflike(a, b) __attribute__ ((format (printf, a, b)))
|
||||
|
||||
@ -476,13 +480,21 @@ enum msgtype {
|
||||
MSG_RESIZE,
|
||||
MSG_SHELL,
|
||||
MSG_SHUTDOWN,
|
||||
MSG_STDERR,
|
||||
MSG_STDIN,
|
||||
MSG_STDOUT,
|
||||
MSG_OLDSTDERR, /* unused */
|
||||
MSG_OLDSTDIN, /* unused */
|
||||
MSG_OLDSTDOUT, /* unused */
|
||||
MSG_SUSPEND,
|
||||
MSG_UNLOCK,
|
||||
MSG_WAKEUP,
|
||||
MSG_EXEC,
|
||||
|
||||
MSG_READ_OPEN = 300,
|
||||
MSG_READ,
|
||||
MSG_READ_DONE,
|
||||
MSG_WRITE_OPEN,
|
||||
MSG_WRITE,
|
||||
MSG_WRITE_READY,
|
||||
MSG_WRITE_CLOSE
|
||||
};
|
||||
|
||||
/*
|
||||
@ -490,23 +502,41 @@ enum msgtype {
|
||||
*
|
||||
* Don't forget to bump PROTOCOL_VERSION if any of these change!
|
||||
*/
|
||||
struct msg_command_data {
|
||||
struct msg_command {
|
||||
int argc;
|
||||
}; /* followed by packed argv */
|
||||
|
||||
struct msg_stdin_data {
|
||||
ssize_t size;
|
||||
char data[BUFSIZ];
|
||||
struct msg_read_open {
|
||||
int stream;
|
||||
int fd;
|
||||
}; /* followed by path */
|
||||
|
||||
struct msg_read_data {
|
||||
int stream;
|
||||
};
|
||||
|
||||
struct msg_stdout_data {
|
||||
ssize_t size;
|
||||
char data[BUFSIZ];
|
||||
struct msg_read_done {
|
||||
int stream;
|
||||
int error;
|
||||
};
|
||||
|
||||
struct msg_stderr_data {
|
||||
ssize_t size;
|
||||
char data[BUFSIZ];
|
||||
struct msg_write_open {
|
||||
int stream;
|
||||
int fd;
|
||||
int flags;
|
||||
}; /* followed by path */
|
||||
|
||||
struct msg_write_data {
|
||||
int stream;
|
||||
}; /* followed by data */
|
||||
|
||||
struct msg_write_ready {
|
||||
int stream;
|
||||
int error;
|
||||
};
|
||||
|
||||
struct msg_write_close {
|
||||
int stream;
|
||||
};
|
||||
|
||||
/* Mode keys. */
|
||||
@ -682,6 +712,13 @@ struct style_range {
|
||||
};
|
||||
TAILQ_HEAD(style_ranges, style_range);
|
||||
|
||||
/* Style default. */
|
||||
enum style_default_type {
|
||||
STYLE_DEFAULT_BASE,
|
||||
STYLE_DEFAULT_PUSH,
|
||||
STYLE_DEFAULT_POP
|
||||
};
|
||||
|
||||
/* Style option. */
|
||||
struct style {
|
||||
struct grid_cell gc;
|
||||
@ -692,6 +729,8 @@ struct style {
|
||||
|
||||
enum style_range_type range_type;
|
||||
u_int range_argument;
|
||||
|
||||
enum style_default_type default_type;
|
||||
};
|
||||
|
||||
/* Virtual screen. */
|
||||
@ -699,6 +738,7 @@ struct screen_sel;
|
||||
struct screen_titles;
|
||||
struct screen {
|
||||
char *title;
|
||||
char *path;
|
||||
struct screen_titles *titles;
|
||||
|
||||
struct grid *grid; /* grid data */
|
||||
@ -845,6 +885,7 @@ struct window_pane {
|
||||
#define PANE_STATUSDRAWN 0x400
|
||||
#define PANE_EMPTY 0x800
|
||||
#define PANE_STYLECHANGED 0x1000
|
||||
#define PANE_RESIZED 0x2000
|
||||
|
||||
int argc;
|
||||
char **argv;
|
||||
@ -886,7 +927,9 @@ struct window_pane {
|
||||
TAILQ_HEAD (, window_mode_entry) modes;
|
||||
struct event modetimer;
|
||||
time_t modelast;
|
||||
|
||||
char *searchstr;
|
||||
int searchregex;
|
||||
|
||||
TAILQ_ENTRY(window_pane) entry;
|
||||
RB_ENTRY(window_pane) tree_entry;
|
||||
@ -897,6 +940,7 @@ RB_HEAD(window_pane_tree, window_pane);
|
||||
/* Window structure. */
|
||||
struct window {
|
||||
u_int id;
|
||||
void *latest;
|
||||
|
||||
char *name;
|
||||
struct event name_event;
|
||||
@ -918,12 +962,15 @@ struct window {
|
||||
|
||||
u_int sx;
|
||||
u_int sy;
|
||||
u_int xpixel;
|
||||
u_int ypixel;
|
||||
|
||||
int flags;
|
||||
#define WINDOW_BELL 0x1
|
||||
#define WINDOW_ACTIVITY 0x2
|
||||
#define WINDOW_SILENCE 0x4
|
||||
#define WINDOW_ZOOMED 0x8
|
||||
#define WINDOW_WASZOOMED 0x10
|
||||
#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE)
|
||||
|
||||
int alerts_queued;
|
||||
@ -961,6 +1008,7 @@ TAILQ_HEAD(winlink_stack, winlink);
|
||||
#define WINDOW_SIZE_LARGEST 0
|
||||
#define WINDOW_SIZE_SMALLEST 1
|
||||
#define WINDOW_SIZE_MANUAL 2
|
||||
#define WINDOW_SIZE_LATEST 3
|
||||
|
||||
/* Pane border status option. */
|
||||
#define PANE_STATUS_OFF 0
|
||||
@ -1124,7 +1172,10 @@ struct tty_term {
|
||||
struct tty_code *codes;
|
||||
|
||||
#define TERM_256COLOURS 0x1
|
||||
#define TERM_EARLYWRAP 0x2
|
||||
#define TERM_NOXENL 0x2
|
||||
#define TERM_DECSLRM 0x4
|
||||
#define TERM_DECFRA 0x8
|
||||
#define TERM_RGBCOLOURS 0x10
|
||||
int flags;
|
||||
|
||||
LIST_ENTRY(tty_term) entry;
|
||||
@ -1133,9 +1184,12 @@ LIST_HEAD(tty_terms, tty_term);
|
||||
|
||||
struct tty {
|
||||
struct client *client;
|
||||
struct event start_timer;
|
||||
|
||||
u_int sx;
|
||||
u_int sy;
|
||||
u_int xpixel;
|
||||
u_int ypixel;
|
||||
|
||||
u_int cx;
|
||||
u_int cy;
|
||||
@ -1179,20 +1233,13 @@ struct tty {
|
||||
#define TTY_OPENED 0x20
|
||||
#define TTY_FOCUS 0x40
|
||||
#define TTY_BLOCK 0x80
|
||||
#define TTY_HAVEDA 0x100
|
||||
#define TTY_HAVEDSR 0x200
|
||||
int flags;
|
||||
|
||||
struct tty_term *term;
|
||||
char *term_name;
|
||||
int term_flags;
|
||||
enum {
|
||||
TTY_VT100,
|
||||
TTY_VT101,
|
||||
TTY_VT102,
|
||||
TTY_VT220,
|
||||
TTY_VT320,
|
||||
TTY_VT420,
|
||||
TTY_UNKNOWN
|
||||
} term_type;
|
||||
|
||||
u_int mouse_last_x;
|
||||
u_int mouse_last_y;
|
||||
@ -1206,8 +1253,6 @@ struct tty {
|
||||
struct event key_timer;
|
||||
struct tty_key *key_tree;
|
||||
};
|
||||
#define TTY_TYPES \
|
||||
{ "VT100", "VT101", "VT102", "VT220", "VT320", "VT420", "Unknown" }
|
||||
|
||||
/* TTY command context. */
|
||||
struct tty_ctx {
|
||||
@ -1216,8 +1261,8 @@ struct tty_ctx {
|
||||
const struct grid_cell *cell;
|
||||
int wrapped;
|
||||
|
||||
u_int num;
|
||||
void *ptr;
|
||||
u_int num;
|
||||
void *ptr;
|
||||
|
||||
/*
|
||||
* Cursor and region position before the screen was updated - this is
|
||||
@ -1446,6 +1491,29 @@ struct status_line {
|
||||
struct status_line_entry entries[STATUS_LINES_LIMIT];
|
||||
};
|
||||
|
||||
/* File in client. */
|
||||
typedef void (*client_file_cb) (struct client *, const char *, int, int,
|
||||
struct evbuffer *, void *);
|
||||
struct client_file {
|
||||
struct client *c;
|
||||
int references;
|
||||
int stream;
|
||||
|
||||
char *path;
|
||||
struct evbuffer *buffer;
|
||||
struct bufferevent *event;
|
||||
|
||||
int fd;
|
||||
int error;
|
||||
int closed;
|
||||
|
||||
client_file_cb cb;
|
||||
void *data;
|
||||
|
||||
RB_ENTRY (client_file) entry;
|
||||
};
|
||||
RB_HEAD(client_files, client_file);
|
||||
|
||||
/* Client connection. */
|
||||
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
|
||||
typedef void (*prompt_free_cb)(void *);
|
||||
@ -1479,13 +1547,6 @@ struct client {
|
||||
size_t discarded;
|
||||
size_t redraw;
|
||||
|
||||
void (*stdin_callback)(struct client *, int, void *);
|
||||
void *stdin_callback_data;
|
||||
struct evbuffer *stdin_data;
|
||||
int stdin_closed;
|
||||
struct evbuffer *stdout_data;
|
||||
struct evbuffer *stderr_data;
|
||||
|
||||
struct event repeat_timer;
|
||||
|
||||
struct event click_timer;
|
||||
@ -1526,6 +1587,10 @@ struct client {
|
||||
CLIENT_REDRAWSTATUSALWAYS| \
|
||||
CLIENT_REDRAWBORDERS| \
|
||||
CLIENT_REDRAWOVERLAY)
|
||||
#define CLIENT_UNATTACHEDFLAGS \
|
||||
(CLIENT_DEAD| \
|
||||
CLIENT_SUSPENDED| \
|
||||
CLIENT_DETACHING)
|
||||
#define CLIENT_NOSIZEFLAGS \
|
||||
(CLIENT_DEAD| \
|
||||
CLIENT_SUSPENDED| \
|
||||
@ -1552,6 +1617,7 @@ struct client {
|
||||
#define PROMPT_NUMERIC 0x2
|
||||
#define PROMPT_INCREMENTAL 0x4
|
||||
#define PROMPT_NOFORMAT 0x8
|
||||
#define PROMPT_KEY 0x10
|
||||
int prompt_flags;
|
||||
|
||||
struct session *session;
|
||||
@ -1569,6 +1635,8 @@ struct client {
|
||||
void *overlay_data;
|
||||
struct event overlay_timer;
|
||||
|
||||
struct client_files files;
|
||||
|
||||
TAILQ_ENTRY(client) entry;
|
||||
};
|
||||
TAILQ_HEAD(clients, client);
|
||||
@ -1577,6 +1645,7 @@ TAILQ_HEAD(clients, client);
|
||||
struct key_binding {
|
||||
key_code key;
|
||||
struct cmd_list *cmdlist;
|
||||
const char *note;
|
||||
|
||||
int flags;
|
||||
#define KEY_BINDING_REPEAT 0x1
|
||||
@ -1661,6 +1730,7 @@ struct spawn_context {
|
||||
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct client *c;
|
||||
|
||||
struct window_pane *wp0;
|
||||
struct layout_cell *lc;
|
||||
@ -1683,6 +1753,12 @@ struct spawn_context {
|
||||
#define SPAWN_EMPTY 0x40
|
||||
};
|
||||
|
||||
/* Mode tree sort order. */
|
||||
struct mode_tree_sort_criteria {
|
||||
u_int field;
|
||||
int reversed;
|
||||
};
|
||||
|
||||
/* tmux.c */
|
||||
extern struct options *global_options;
|
||||
extern struct options *global_s_options;
|
||||
@ -1697,6 +1773,7 @@ int areshell(const char *);
|
||||
void setblocking(int, int);
|
||||
const char *find_cwd(void);
|
||||
const char *find_home(void);
|
||||
const char *getversion(void);
|
||||
|
||||
/* proc.c */
|
||||
struct imsg;
|
||||
@ -1718,6 +1795,8 @@ extern struct client *cfg_client;
|
||||
void start_cfg(void);
|
||||
int load_cfg(const char *, struct client *, struct cmdq_item *, int,
|
||||
struct cmdq_item **);
|
||||
int load_cfg_from_buffer(const void *, size_t, const char *,
|
||||
struct client *, struct cmdq_item *, int, struct cmdq_item **);
|
||||
void set_cfg_file(const char *);
|
||||
void printflike(1, 2) cfg_add_cause(const char *, ...);
|
||||
void cfg_print_causes(struct cmdq_item *);
|
||||
@ -1769,6 +1848,8 @@ void format_defaults_pane(struct format_tree *,
|
||||
void format_defaults_paste_buffer(struct format_tree *,
|
||||
struct paste_buffer *);
|
||||
void format_lost_client(struct client *);
|
||||
char *format_grid_word(struct grid *, u_int, u_int);
|
||||
char *format_grid_line(struct grid *, u_int);
|
||||
|
||||
/* format-draw.c */
|
||||
void format_draw(struct screen_write_ctx *,
|
||||
@ -1898,7 +1979,7 @@ void tty_putc(struct tty *, u_char);
|
||||
void tty_putn(struct tty *, const void *, size_t, u_int);
|
||||
int tty_init(struct tty *, struct client *, int, char *);
|
||||
void tty_resize(struct tty *);
|
||||
void tty_set_size(struct tty *, u_int, u_int);
|
||||
void tty_set_size(struct tty *, u_int, u_int, u_int, u_int);
|
||||
void tty_start_tty(struct tty *);
|
||||
void tty_stop_tty(struct tty *);
|
||||
void tty_set_title(struct tty *, const char *);
|
||||
@ -1908,7 +1989,7 @@ void tty_draw_line(struct tty *, struct window_pane *, struct screen *,
|
||||
int tty_open(struct tty *, char **);
|
||||
void tty_close(struct tty *);
|
||||
void tty_free(struct tty *);
|
||||
void tty_set_type(struct tty *, int);
|
||||
void tty_set_flags(struct tty *, int);
|
||||
void tty_write(void (*)(struct tty *, const struct tty_ctx *),
|
||||
struct tty_ctx *);
|
||||
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
|
||||
@ -2033,6 +2114,8 @@ void cmd_parse_empty(struct cmd_parse_input *);
|
||||
struct cmd_parse_result *cmd_parse_from_file(FILE *, struct cmd_parse_input *);
|
||||
struct cmd_parse_result *cmd_parse_from_string(const char *,
|
||||
struct cmd_parse_input *);
|
||||
struct cmd_parse_result *cmd_parse_from_buffer(const void *, size_t,
|
||||
struct cmd_parse_input *);
|
||||
struct cmd_parse_result *cmd_parse_from_arguments(int, char **,
|
||||
struct cmd_parse_input *);
|
||||
|
||||
@ -2049,8 +2132,8 @@ struct cmdq_item *cmdq_get_command(struct cmd_list *, struct cmd_find_state *,
|
||||
#define cmdq_get_callback(cb, data) cmdq_get_callback1(#cb, cb, data)
|
||||
struct cmdq_item *cmdq_get_callback1(const char *, cmdq_cb, void *);
|
||||
struct cmdq_item *cmdq_get_error(const char *);
|
||||
void cmdq_insert_after(struct cmdq_item *, struct cmdq_item *);
|
||||
void cmdq_append(struct client *, struct cmdq_item *);
|
||||
struct cmdq_item *cmdq_insert_after(struct cmdq_item *, struct cmdq_item *);
|
||||
struct cmdq_item *cmdq_append(struct client *, struct cmdq_item *);
|
||||
void printflike(4, 5) cmdq_insert_hook(struct session *, struct cmdq_item *,
|
||||
struct cmd_find_state *, const char *, ...);
|
||||
void cmdq_continue(struct cmdq_item *);
|
||||
@ -2075,7 +2158,8 @@ void key_bindings_unref_table(struct key_table *);
|
||||
struct key_binding *key_bindings_get(struct key_table *, key_code);
|
||||
struct key_binding *key_bindings_first(struct key_table *);
|
||||
struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
|
||||
void key_bindings_add(const char *, key_code, int, struct cmd_list *);
|
||||
void key_bindings_add(const char *, key_code, const char *, int,
|
||||
struct cmd_list *);
|
||||
void key_bindings_remove(const char *, key_code);
|
||||
void key_bindings_remove_table(const char *);
|
||||
void key_bindings_init(void);
|
||||
@ -2092,6 +2176,23 @@ void alerts_reset_all(void);
|
||||
void alerts_queue(struct window *, int);
|
||||
void alerts_check_session(struct session *);
|
||||
|
||||
/* file.c */
|
||||
int file_cmp(struct client_file *, struct client_file *);
|
||||
RB_PROTOTYPE(client_files, client_file, entry, file_cmp);
|
||||
struct client_file *file_create(struct client *, int, client_file_cb, void *);
|
||||
void file_free(struct client_file *);
|
||||
void file_fire_done(struct client_file *);
|
||||
void file_fire_read(struct client_file *);
|
||||
int file_can_print(struct client *);
|
||||
void printflike(2, 3) file_print(struct client *, const char *, ...);
|
||||
void file_vprint(struct client *, const char *, va_list);
|
||||
void file_print_buffer(struct client *, void *, size_t);
|
||||
void printflike(2, 3) file_error(struct client *, const char *, ...);
|
||||
void file_write(struct client *, const char *, int, const void *, size_t,
|
||||
client_file_cb, void *);
|
||||
void file_read(struct client *, const char *, client_file_cb, void *);
|
||||
void file_push(struct client_file *);
|
||||
|
||||
/* server.c */
|
||||
extern struct tmuxproc *server_proc;
|
||||
extern struct clients clients;
|
||||
@ -2126,7 +2227,6 @@ void server_client_push_stdout(struct client *);
|
||||
void server_client_push_stderr(struct client *);
|
||||
void printflike(2, 3) server_client_add_message(struct client *, const char *,
|
||||
...);
|
||||
char *server_client_get_path(struct client *, const char *);
|
||||
const char *server_client_get_cwd(struct client *, struct session *);
|
||||
|
||||
/* server-fn.c */
|
||||
@ -2150,8 +2250,6 @@ void server_unlink_window(struct session *, struct winlink *);
|
||||
void server_destroy_pane(struct window_pane *, int);
|
||||
void server_destroy_session(struct session *);
|
||||
void server_check_unattached(void);
|
||||
int server_set_stdin_callback(struct client *, void (*)(struct client *,
|
||||
int, void *), void *, char **);
|
||||
void server_unzoom_window(struct window *);
|
||||
|
||||
/* status.c */
|
||||
@ -2177,9 +2275,10 @@ void status_prompt_load_history(void);
|
||||
void status_prompt_save_history(void);
|
||||
|
||||
/* resize.c */
|
||||
void resize_window(struct window *, u_int, u_int);
|
||||
void default_window_size(struct session *, struct window *, u_int *,
|
||||
u_int *, int);
|
||||
void resize_window(struct window *, u_int, u_int, int, int);
|
||||
void default_window_size(struct client *, struct session *, struct window *,
|
||||
u_int *, u_int *, u_int *, u_int *, int);
|
||||
void recalculate_size(struct window *);
|
||||
void recalculate_sizes(void);
|
||||
|
||||
/* input.c */
|
||||
@ -2191,7 +2290,7 @@ void input_parse(struct window_pane *);
|
||||
void input_parse_buffer(struct window_pane *, u_char *, size_t);
|
||||
|
||||
/* input-key.c */
|
||||
void input_key(struct window_pane *, key_code, struct mouse_event *);
|
||||
int input_key(struct window_pane *, key_code, struct mouse_event *);
|
||||
|
||||
/* xterm-keys.c */
|
||||
char *xterm_keys_lookup(key_code);
|
||||
@ -2329,7 +2428,8 @@ void screen_free(struct screen *);
|
||||
void screen_reset_tabs(struct screen *);
|
||||
void screen_set_cursor_style(struct screen *, u_int);
|
||||
void screen_set_cursor_colour(struct screen *, const char *);
|
||||
void screen_set_title(struct screen *, const char *);
|
||||
int screen_set_title(struct screen *, const char *);
|
||||
void screen_set_path(struct screen *, const char *);
|
||||
void screen_push_title(struct screen *);
|
||||
void screen_pop_title(struct screen *);
|
||||
void screen_resize(struct screen *, u_int, u_int, int);
|
||||
@ -2369,7 +2469,7 @@ void winlink_stack_remove(struct winlink_stack *, struct winlink *);
|
||||
struct window *window_find_by_id_str(const char *);
|
||||
struct window *window_find_by_id(u_int);
|
||||
void window_update_activity(struct window *);
|
||||
struct window *window_create(u_int, u_int);
|
||||
struct window *window_create(u_int, u_int, u_int, u_int);
|
||||
void window_pane_set_event(struct window_pane *);
|
||||
struct window_pane *window_get_active_at(struct window *, u_int, u_int);
|
||||
struct window_pane *window_find_string(struct window *, const char *);
|
||||
@ -2380,9 +2480,12 @@ void window_redraw_active_switch(struct window *,
|
||||
struct window_pane *);
|
||||
struct window_pane *window_add_pane(struct window *, struct window_pane *,
|
||||
u_int, int);
|
||||
void window_resize(struct window *, u_int, u_int);
|
||||
void window_resize(struct window *, u_int, u_int, int, int);
|
||||
void window_pane_send_resize(struct window_pane *, int);
|
||||
int window_zoom(struct window_pane *);
|
||||
int window_unzoom(struct window *);
|
||||
int window_push_zoom(struct window *, int);
|
||||
int window_pop_zoom(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);
|
||||
@ -2410,7 +2513,7 @@ int window_pane_set_mode(struct window_pane *,
|
||||
struct args *);
|
||||
void window_pane_reset_mode(struct window_pane *);
|
||||
void window_pane_reset_mode_all(struct window_pane *);
|
||||
void window_pane_key(struct window_pane *, struct client *,
|
||||
int window_pane_key(struct window_pane *, struct client *,
|
||||
struct session *, struct winlink *, key_code,
|
||||
struct mouse_event *);
|
||||
int window_pane_visible(struct window_pane *);
|
||||
@ -2472,7 +2575,8 @@ u_int layout_set_next(struct window *);
|
||||
u_int layout_set_previous(struct window *);
|
||||
|
||||
/* mode-tree.c */
|
||||
typedef void (*mode_tree_build_cb)(void *, u_int, uint64_t *, const char *);
|
||||
typedef void (*mode_tree_build_cb)(void *, struct mode_tree_sort_criteria *,
|
||||
uint64_t *, const char *);
|
||||
typedef void (*mode_tree_draw_cb)(void *, void *, struct screen_write_ctx *,
|
||||
u_int, u_int);
|
||||
typedef int (*mode_tree_search_cb)(void *, void *, const char *);
|
||||
@ -2530,9 +2634,8 @@ char *default_window_name(struct window *);
|
||||
char *parse_window_name(const char *);
|
||||
|
||||
/* control.c */
|
||||
void control_callback(struct client *, int, void *);
|
||||
void control_start(struct client *);
|
||||
void printflike(2, 3) control_write(struct client *, const char *, ...);
|
||||
void control_write_buffer(struct client *, struct evbuffer *);
|
||||
|
||||
/* control-notify.c */
|
||||
void control_notify_input(struct client *, struct window_pane *,
|
||||
@ -2585,6 +2688,7 @@ void session_group_add(struct session_group *, struct session *);
|
||||
void session_group_synchronize_to(struct session *);
|
||||
void session_group_synchronize_from(struct session *);
|
||||
u_int session_group_count(struct session_group *);
|
||||
u_int session_group_attached_count(struct session_group *);
|
||||
void session_renumber_windows(struct session *);
|
||||
|
||||
/* utf8.c */
|
||||
@ -2604,6 +2708,7 @@ struct utf8_data *utf8_fromcstr(const char *);
|
||||
char *utf8_tocstr(struct utf8_data *);
|
||||
u_int utf8_cstrwidth(const char *);
|
||||
char *utf8_padcstr(const char *, u_int);
|
||||
char *utf8_rpadcstr(const char *, u_int);
|
||||
int utf8_cstrhas(const char *, const struct utf8_data *);
|
||||
|
||||
/* osdep-*.c */
|
||||
@ -2641,8 +2746,6 @@ int style_parse(struct style *,const struct grid_cell *,
|
||||
const char *style_tostring(struct style *);
|
||||
void style_apply(struct grid_cell *, struct options *,
|
||||
const char *);
|
||||
void style_apply_update(struct grid_cell *, struct options *,
|
||||
const char *);
|
||||
int style_equal(struct style *, struct style *);
|
||||
void style_set(struct style *, const struct grid_cell *);
|
||||
void style_copy(struct style *, struct style *);
|
||||
|
126
external/bsd/tmux/dist/tty-keys.c
vendored
126
external/bsd/tmux/dist/tty-keys.c
vendored
@ -52,6 +52,8 @@ static int tty_keys_clipboard(struct tty *, const char *, size_t,
|
||||
size_t *);
|
||||
static int tty_keys_device_attributes(struct tty *, const char *, size_t,
|
||||
size_t *);
|
||||
static int tty_keys_device_status_report(struct tty *, const char *,
|
||||
size_t, size_t *);
|
||||
|
||||
/* Default raw keys. */
|
||||
struct tty_default_key_raw {
|
||||
@ -607,6 +609,17 @@ tty_keys_next(struct tty *tty)
|
||||
goto partial_key;
|
||||
}
|
||||
|
||||
/* Is this a device status report response? */
|
||||
switch (tty_keys_device_status_report(tty, buf, len, &size)) {
|
||||
case 0: /* yes */
|
||||
key = KEYC_UNKNOWN;
|
||||
goto complete_key;
|
||||
case -1: /* no, or not valid */
|
||||
break;
|
||||
case 1: /* partial */
|
||||
goto partial_key;
|
||||
}
|
||||
|
||||
/* Is this a mouse key press? */
|
||||
switch (tty_keys_mouse(tty, buf, len, &size, &m)) {
|
||||
case 0: /* yes */
|
||||
@ -1002,13 +1015,14 @@ static int
|
||||
tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
|
||||
size_t *size)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
u_int i, a, b;
|
||||
char tmp[64], *endptr;
|
||||
static const char *types[] = TTY_TYPES;
|
||||
int type;
|
||||
struct client *c = tty->client;
|
||||
u_int i, n = 0;
|
||||
char tmp[64], *endptr, p[32] = { 0 }, *cp, *next;
|
||||
int flags = 0;
|
||||
|
||||
*size = 0;
|
||||
if (tty->flags & TTY_HAVEDA)
|
||||
return (-1);
|
||||
|
||||
/* First three bytes are always \033[?. */
|
||||
if (buf[0] != '\033')
|
||||
@ -1036,39 +1050,81 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
|
||||
*size = 4 + i;
|
||||
|
||||
/* Convert version numbers. */
|
||||
a = strtoul(tmp, &endptr, 10);
|
||||
if (*endptr == ';') {
|
||||
b = strtoul(endptr + 1, &endptr, 10);
|
||||
if (*endptr != '\0' && *endptr != ';')
|
||||
b = 0;
|
||||
} else
|
||||
a = b = 0;
|
||||
cp = tmp;
|
||||
while ((next = strsep(&cp, ";")) != NULL) {
|
||||
p[n] = strtoul(next, &endptr, 10);
|
||||
if (*endptr != '\0')
|
||||
p[n] = 0;
|
||||
n++;
|
||||
}
|
||||
|
||||
/* Store terminal type. */
|
||||
type = TTY_UNKNOWN;
|
||||
switch (a) {
|
||||
case 1:
|
||||
if (b == 2)
|
||||
type = TTY_VT100;
|
||||
else if (b == 0)
|
||||
type = TTY_VT101;
|
||||
break;
|
||||
case 6:
|
||||
type = TTY_VT102;
|
||||
break;
|
||||
case 62:
|
||||
type = TTY_VT220;
|
||||
break;
|
||||
case 63:
|
||||
type = TTY_VT320;
|
||||
break;
|
||||
case 64:
|
||||
type = TTY_VT420;
|
||||
/* Set terminal flags. */
|
||||
switch (p[0]) {
|
||||
case 64: /* VT420 */
|
||||
flags |= (TERM_DECFRA|TERM_DECSLRM);
|
||||
break;
|
||||
}
|
||||
tty_set_type(tty, type);
|
||||
for (i = 1; i < n; i++)
|
||||
log_debug("%s: DA feature: %d", c->name, p[i]);
|
||||
log_debug("%s: received DA %.*s", c->name, (int)*size, buf);
|
||||
|
||||
tty_set_flags(tty, flags);
|
||||
tty->flags |= TTY_HAVEDA;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle device status report input. Returns 0 for success, -1 for failure, 1
|
||||
* for partial.
|
||||
*/
|
||||
static int
|
||||
tty_keys_device_status_report(struct tty *tty, const char *buf, size_t len,
|
||||
size_t *size)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
u_int i;
|
||||
char tmp[64];
|
||||
int flags = 0;
|
||||
|
||||
*size = 0;
|
||||
if (tty->flags & TTY_HAVEDSR)
|
||||
return (-1);
|
||||
|
||||
/* First three bytes are always \033[. */
|
||||
if (buf[0] != '\033')
|
||||
return (-1);
|
||||
if (len == 1)
|
||||
return (1);
|
||||
if (buf[1] != '[')
|
||||
return (-1);
|
||||
if (len == 2)
|
||||
return (1);
|
||||
if (buf[2] != 'I' && buf[2] != 'T')
|
||||
return (-1);
|
||||
if (len == 3)
|
||||
return (1);
|
||||
|
||||
/* Copy the rest up to a 'n'. */
|
||||
for (i = 0; i < (sizeof tmp) - 1 && buf[2 + i] != 'n'; i++) {
|
||||
if (2 + i == len)
|
||||
return (1);
|
||||
tmp[i] = buf[2 + i];
|
||||
}
|
||||
if (i == (sizeof tmp) - 1)
|
||||
return (-1);
|
||||
tmp[i] = '\0';
|
||||
*size = 3 + i;
|
||||
|
||||
/* Set terminal flags. */
|
||||
if (strncmp(tmp, "ITERM2 ", 7) == 0)
|
||||
flags |= (TERM_DECSLRM|TERM_256COLOURS|TERM_RGBCOLOURS);
|
||||
if (strncmp(tmp, "TMUX ", 5) == 0)
|
||||
flags |= (TERM_256COLOURS|TERM_RGBCOLOURS);
|
||||
log_debug("%s: received DSR %.*s", c->name, (int)*size, buf);
|
||||
|
||||
tty_set_flags(tty, flags);
|
||||
tty->flags |= TTY_HAVEDSR;
|
||||
|
||||
log_debug("%s: received DA %.*s (%s)", c->name, (int)*size, buf,
|
||||
types[type]);
|
||||
return (0);
|
||||
}
|
||||
|
33
external/bsd/tmux/dist/tty-term.c
vendored
33
external/bsd/tmux/dist/tty-term.c
vendored
@ -528,11 +528,16 @@ tty_term_find(char *name, int fd, char **cause)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Figure out if we have 256 colours (or more). */
|
||||
if (tty_term_number(term, TTYC_COLORS) >= 256 ||
|
||||
tty_term_has(term, TTYC_RGB))
|
||||
/* Set flag if terminal has 256 colours. */
|
||||
if (tty_term_number(term, TTYC_COLORS) >= 256)
|
||||
term->flags |= TERM_256COLOURS;
|
||||
|
||||
/* Set flag if terminal has RGB colours. */
|
||||
if ((tty_term_flag(term, TTYC_TC) || tty_term_has(term, TTYC_RGB)) ||
|
||||
(tty_term_has(term, TTYC_SETRGBF) &&
|
||||
tty_term_has(term, TTYC_SETRGBB)))
|
||||
term->flags |= TERM_RGBCOLOURS;
|
||||
|
||||
/*
|
||||
* Terminals without xenl (eat newline glitch) wrap at at $COLUMNS - 1
|
||||
* rather than $COLUMNS (the cursor can never be beyond $COLUMNS - 1).
|
||||
@ -544,7 +549,7 @@ tty_term_find(char *name, int fd, char **cause)
|
||||
* do the best possible.
|
||||
*/
|
||||
if (!tty_term_flag(term, TTYC_XENL))
|
||||
term->flags |= TERM_EARLYWRAP;
|
||||
term->flags |= TERM_NOXENL;
|
||||
|
||||
/* Generate ACS table. If none is present, use nearest ASCII. */
|
||||
memset(term->acs, 0, sizeof term->acs);
|
||||
@ -567,22 +572,7 @@ tty_term_find(char *name, int fd, char **cause)
|
||||
code->type = TTYCODE_STRING;
|
||||
}
|
||||
|
||||
/*
|
||||
* On terminals with RGB colour (Tc or RGB), fill in setrgbf and
|
||||
* setrgbb if they are missing.
|
||||
*/
|
||||
if ((tty_term_flag(term, TTYC_TC) || tty_term_flag(term, TTYC_RGB)) &&
|
||||
!tty_term_has(term, TTYC_SETRGBF) &&
|
||||
!tty_term_has(term, TTYC_SETRGBB)) {
|
||||
code = &term->codes[TTYC_SETRGBF];
|
||||
code->value.string = xstrdup("\033[38;2;%p1%d;%p2%d;%p3%dm");
|
||||
code->type = TTYCODE_STRING;
|
||||
code = &term->codes[TTYC_SETRGBB];
|
||||
code->value.string = xstrdup("\033[48;2;%p1%d;%p2%d;%p3%dm");
|
||||
code->type = TTYCODE_STRING;
|
||||
}
|
||||
|
||||
/* Log it. */
|
||||
/* Log the capabilities. */
|
||||
for (i = 0; i < tty_term_ncodes(); i++)
|
||||
log_debug("%s%s", name, tty_term_describe(term, i));
|
||||
|
||||
@ -642,7 +632,8 @@ tty_term_string2(struct tty_term *term, enum tty_code_code code, int a, int b)
|
||||
}
|
||||
|
||||
const char *
|
||||
tty_term_string3(struct tty_term *term, enum tty_code_code code, int a, int b, int c)
|
||||
tty_term_string3(struct tty_term *term, enum tty_code_code code, int a, int b,
|
||||
int c)
|
||||
{
|
||||
return (tparm(tty_term_string(term, code), a, b, c, 0, 0, 0, 0, 0, 0));
|
||||
}
|
||||
|
131
external/bsd/tmux/dist/tty.c
vendored
131
external/bsd/tmux/dist/tty.c
vendored
@ -74,7 +74,7 @@ static void tty_default_attributes(struct tty *, struct window_pane *,
|
||||
u_int);
|
||||
|
||||
#define tty_use_margin(tty) \
|
||||
((tty)->term_type == TTY_VT420)
|
||||
((tty->term->flags|tty->term_flags) & TERM_DECSLRM)
|
||||
|
||||
#define tty_pane_full_width(tty, ctx) \
|
||||
((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx)
|
||||
@ -115,9 +115,7 @@ tty_init(struct tty *tty, struct client *c, int fd, char *term)
|
||||
tty->ccolour = xstrdup("");
|
||||
|
||||
tty->flags = 0;
|
||||
|
||||
tty->term_flags = 0;
|
||||
tty->term_type = TTY_UNKNOWN;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -127,29 +125,40 @@ tty_resize(struct tty *tty)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
struct winsize ws;
|
||||
u_int sx, sy;
|
||||
u_int sx, sy, xpixel, ypixel;
|
||||
|
||||
if (ioctl(tty->fd, TIOCGWINSZ, &ws) != -1) {
|
||||
sx = ws.ws_col;
|
||||
if (sx == 0)
|
||||
if (sx == 0) {
|
||||
sx = 80;
|
||||
xpixel = 0;
|
||||
} else
|
||||
xpixel = ws.ws_xpixel / sx;
|
||||
sy = ws.ws_row;
|
||||
if (sy == 0)
|
||||
if (sy == 0) {
|
||||
sy = 24;
|
||||
ypixel = 0;
|
||||
} else
|
||||
ypixel = ws.ws_ypixel / sy;
|
||||
} else {
|
||||
sx = 80;
|
||||
sy = 24;
|
||||
xpixel = 0;
|
||||
ypixel = 0;
|
||||
}
|
||||
log_debug("%s: %s now %ux%u", __func__, c->name, sx, sy);
|
||||
tty_set_size(tty, sx, sy);
|
||||
log_debug("%s: %s now %ux%u (%ux%u)", __func__, c->name, sx, sy,
|
||||
xpixel, ypixel);
|
||||
tty_set_size(tty, sx, sy, xpixel, ypixel);
|
||||
tty_invalidate(tty);
|
||||
}
|
||||
|
||||
void
|
||||
tty_set_size(struct tty *tty, u_int sx, u_int sy)
|
||||
tty_set_size(struct tty *tty, u_int sx, u_int sy, u_int xpixel, u_int ypixel)
|
||||
{
|
||||
tty->sx = sx;
|
||||
tty->sy = sy;
|
||||
tty->xpixel = xpixel;
|
||||
tty->ypixel = ypixel;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -276,11 +285,22 @@ tty_open(struct tty *tty, char **cause)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_start_timer_callback(__unused int fd, __unused short events, void *data)
|
||||
{
|
||||
struct tty *tty = data;
|
||||
struct client *c = tty->client;
|
||||
|
||||
log_debug("%s: start timer fired", c->name);
|
||||
tty->flags |= (TTY_HAVEDA|TTY_HAVEDSR);
|
||||
}
|
||||
|
||||
void
|
||||
tty_start_tty(struct tty *tty)
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
struct termios tio;
|
||||
struct timeval tv = { .tv_sec = 1 };
|
||||
|
||||
if (tty->fd != -1 && tcgetattr(tty->fd, &tty->tio) == 0) {
|
||||
setblocking(tty->fd, 0);
|
||||
@ -310,21 +330,31 @@ tty_start_tty(struct tty *tty)
|
||||
log_debug("%s: using UTF-8 for ACS", c->name);
|
||||
|
||||
tty_putcode(tty, TTYC_CNORM);
|
||||
if (tty_term_has(tty->term, TTYC_KMOUS))
|
||||
tty_puts(tty, "\033[?1000l\033[?1002l\033[?1006l\033[?1005l");
|
||||
if (tty_term_has(tty->term, TTYC_KMOUS)) {
|
||||
tty_puts(tty, "\033[?1000l\033[?1002l\033[?1003l");
|
||||
tty_puts(tty, "\033[?1006l\033[?1005l");
|
||||
}
|
||||
|
||||
if (tty_term_flag(tty->term, TTYC_XT)) {
|
||||
if (options_get_number(global_options, "focus-events")) {
|
||||
tty->flags |= TTY_FOCUS;
|
||||
tty_puts(tty, "\033[?1004h");
|
||||
}
|
||||
tty_puts(tty, "\033[c");
|
||||
}
|
||||
if (~tty->flags & TTY_HAVEDA)
|
||||
tty_puts(tty, "\033[c");
|
||||
if (~tty->flags & TTY_HAVEDSR)
|
||||
tty_puts(tty, "\033[1337n");
|
||||
} else
|
||||
tty->flags |= (TTY_HAVEDA|TTY_HAVEDSR);
|
||||
|
||||
evtimer_set(&tty->start_timer, tty_start_timer_callback, tty);
|
||||
evtimer_add(&tty->start_timer, &tv);
|
||||
|
||||
tty->flags |= TTY_STARTED;
|
||||
tty_invalidate(tty);
|
||||
|
||||
tty_force_cursor_colour(tty, "");
|
||||
if (*tty->ccolour != '\0')
|
||||
tty_force_cursor_colour(tty, "");
|
||||
|
||||
tty->mouse_drag_flag = 0;
|
||||
tty->mouse_drag_update = NULL;
|
||||
@ -340,6 +370,8 @@ tty_stop_tty(struct tty *tty)
|
||||
return;
|
||||
tty->flags &= ~TTY_STARTED;
|
||||
|
||||
evtimer_del(&tty->start_timer);
|
||||
|
||||
event_del(&tty->timer);
|
||||
tty->flags &= ~TTY_BLOCK;
|
||||
|
||||
@ -370,11 +402,14 @@ tty_stop_tty(struct tty *tty)
|
||||
}
|
||||
if (tty->mode & MODE_BRACKETPASTE)
|
||||
tty_raw(tty, "\033[?2004l");
|
||||
tty_raw(tty, tty_term_string(tty->term, TTYC_CR));
|
||||
if (*tty->ccolour != '\0')
|
||||
tty_raw(tty, tty_term_string(tty->term, TTYC_CR));
|
||||
|
||||
tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
|
||||
if (tty_term_has(tty->term, TTYC_KMOUS))
|
||||
tty_raw(tty, "\033[?1000l\033[?1002l\033[?1006l\033[?1005l");
|
||||
if (tty_term_has(tty->term, TTYC_KMOUS)) {
|
||||
tty_raw(tty, "\033[?1000l\033[?1002l\033[?1003l");
|
||||
tty_raw(tty, "\033[?1006l\033[?1005l");
|
||||
}
|
||||
|
||||
if (tty_term_flag(tty->term, TTYC_XT)) {
|
||||
if (tty->flags & TTY_FOCUS) {
|
||||
@ -425,9 +460,9 @@ tty_free(struct tty *tty)
|
||||
}
|
||||
|
||||
void
|
||||
tty_set_type(struct tty *tty, int type)
|
||||
tty_set_flags(struct tty *tty, int flags)
|
||||
{
|
||||
tty->term_type = type;
|
||||
tty->term_flags |= flags;
|
||||
|
||||
if (tty_use_margin(tty))
|
||||
tty_puts(tty, "\033[?69h"); /* DECLRMM */
|
||||
@ -530,7 +565,7 @@ tty_putc(struct tty *tty, u_char ch)
|
||||
{
|
||||
const char *acs;
|
||||
|
||||
if ((tty->term->flags & TERM_EARLYWRAP) &&
|
||||
if ((tty->term->flags & TERM_NOXENL) &&
|
||||
ch >= 0x20 && ch != 0x7f &&
|
||||
tty->cy == tty->sy - 1 &&
|
||||
tty->cx + 1 >= tty->sx)
|
||||
@ -556,7 +591,7 @@ tty_putc(struct tty *tty, u_char ch)
|
||||
* where we think it should be after a line wrap - this
|
||||
* means it works on sensible terminals as well.
|
||||
*/
|
||||
if (tty->term->flags & TERM_EARLYWRAP)
|
||||
if (tty->term->flags & TERM_NOXENL)
|
||||
tty_putcode2(tty, TTYC_CUP, tty->cy, tty->cx);
|
||||
} else
|
||||
tty->cx++;
|
||||
@ -566,7 +601,7 @@ tty_putc(struct tty *tty, u_char ch)
|
||||
void
|
||||
tty_putn(struct tty *tty, const void *buf, size_t len, u_int width)
|
||||
{
|
||||
if ((tty->term->flags & TERM_EARLYWRAP) &&
|
||||
if ((tty->term->flags & TERM_NOXENL) &&
|
||||
tty->cy == tty->sy - 1 &&
|
||||
tty->cx + len >= tty->sx)
|
||||
len = tty->sx - tty->cx - 1;
|
||||
@ -1116,7 +1151,8 @@ tty_clear_area(struct tty *tty, struct window_pane *wp, u_int py, u_int ny,
|
||||
* background colour isn't default (because it doesn't work
|
||||
* after SGR 0).
|
||||
*/
|
||||
if (tty->term_type == TTY_VT420 && !COLOUR_DEFAULT(bg)) {
|
||||
if (((tty->term->flags|tty->term_flags) & TERM_DECFRA) &&
|
||||
!COLOUR_DEFAULT(bg)) {
|
||||
xsnprintf(tmp, sizeof tmp, "\033[32;%u;%u;%u;%u$x",
|
||||
py + 1, px + 1, py + ny, px + nx);
|
||||
tty_puts(tty, tmp);
|
||||
@ -1811,7 +1847,7 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
|
||||
ctx->xoff + ctx->ocx + ctx->num > ctx->ox + ctx->sx)) {
|
||||
if (!ctx->wrapped ||
|
||||
!tty_pane_full_width(tty, ctx) ||
|
||||
(tty->term->flags & TERM_EARLYWRAP) ||
|
||||
(tty->term->flags & TERM_NOXENL) ||
|
||||
ctx->xoff + ctx->ocx != 0 ||
|
||||
ctx->yoff + ctx->ocy != tty->cy + 1 ||
|
||||
tty->cx < tty->sx ||
|
||||
@ -1860,7 +1896,7 @@ tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp)
|
||||
const struct grid_cell *gcp;
|
||||
|
||||
/* Skip last character if terminal is stupid. */
|
||||
if ((tty->term->flags & TERM_EARLYWRAP) &&
|
||||
if ((tty->term->flags & TERM_NOXENL) &&
|
||||
tty->cy == tty->sy - 1 &&
|
||||
tty->cx == tty->sx - 1)
|
||||
return;
|
||||
@ -2019,7 +2055,7 @@ tty_cursor_pane_unless_wrap(struct tty *tty, const struct tty_ctx *ctx,
|
||||
{
|
||||
if (!ctx->wrapped ||
|
||||
!tty_pane_full_width(tty, ctx) ||
|
||||
(tty->term->flags & TERM_EARLYWRAP) ||
|
||||
(tty->term->flags & TERM_NOXENL) ||
|
||||
ctx->xoff + cx != 0 ||
|
||||
ctx->yoff + cy != tty->cy + 1 ||
|
||||
tty->cx < tty->sx ||
|
||||
@ -2106,7 +2142,9 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy)
|
||||
if ((u_int) abs(change) > cx && tty_term_has(term, TTYC_HPA)) {
|
||||
tty_putcode1(tty, TTYC_HPA, cx);
|
||||
goto out;
|
||||
} else if (change > 0 && tty_term_has(term, TTYC_CUB)) {
|
||||
} else if (change > 0 &&
|
||||
tty_term_has(term, TTYC_CUB) &&
|
||||
!tty_use_margin(tty)) {
|
||||
if (change == 2 && tty_term_has(term, TTYC_CUB1)) {
|
||||
tty_putcode(tty, TTYC_CUB1);
|
||||
tty_putcode(tty, TTYC_CUB1);
|
||||
@ -2114,7 +2152,9 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy)
|
||||
}
|
||||
tty_putcode1(tty, TTYC_CUB, change);
|
||||
goto out;
|
||||
} else if (change < 0 && tty_term_has(term, TTYC_CUF)) {
|
||||
} else if (change < 0 &&
|
||||
tty_term_has(term, TTYC_CUF) &&
|
||||
!tty_use_margin(tty)) {
|
||||
tty_putcode1(tty, TTYC_CUF, -change);
|
||||
goto out;
|
||||
}
|
||||
@ -2352,11 +2392,10 @@ tty_check_fg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
|
||||
/* Is this a 24-bit colour? */
|
||||
if (gc->fg & COLOUR_FLAG_RGB) {
|
||||
/* Not a 24-bit terminal? Translate to 256-colour palette. */
|
||||
if (!tty_term_has(tty->term, TTYC_SETRGBF)) {
|
||||
colour_split_rgb(gc->fg, &r, &g, &b);
|
||||
gc->fg = colour_find_rgb(r, g, b);
|
||||
} else
|
||||
if ((tty->term->flags|tty->term_flags) & TERM_RGBCOLOURS)
|
||||
return;
|
||||
colour_split_rgb(gc->fg, &r, &g, &b);
|
||||
gc->fg = colour_find_rgb(r, g, b);
|
||||
}
|
||||
|
||||
/* How many colours does this terminal have? */
|
||||
@ -2374,10 +2413,7 @@ tty_check_fg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
|
||||
gc->fg &= 7;
|
||||
if (colours >= 16)
|
||||
gc->fg += 90;
|
||||
else
|
||||
gc->attr |= GRID_ATTR_BRIGHT;
|
||||
} else
|
||||
gc->attr &= ~GRID_ATTR_BRIGHT;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2405,11 +2441,10 @@ tty_check_bg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
|
||||
/* Is this a 24-bit colour? */
|
||||
if (gc->bg & COLOUR_FLAG_RGB) {
|
||||
/* Not a 24-bit terminal? Translate to 256-colour palette. */
|
||||
if (!tty_term_has(tty->term, TTYC_SETRGBB)) {
|
||||
colour_split_rgb(gc->bg, &r, &g, &b);
|
||||
gc->bg = colour_find_rgb(r, g, b);
|
||||
} else
|
||||
if ((tty->term->flags|tty->term_flags) & TERM_RGBCOLOURS)
|
||||
return;
|
||||
colour_split_rgb(gc->bg, &r, &g, &b);
|
||||
gc->bg = colour_find_rgb(r, g, b);
|
||||
}
|
||||
|
||||
/* How many colours does this terminal have? */
|
||||
@ -2442,7 +2477,8 @@ tty_check_bg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
|
||||
}
|
||||
|
||||
static void
|
||||
tty_check_us(__unused struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
|
||||
tty_check_us(__unused struct tty *tty, struct window_pane *wp,
|
||||
struct grid_cell *gc)
|
||||
{
|
||||
int c;
|
||||
|
||||
@ -2585,15 +2621,14 @@ tty_try_colour(struct tty *tty, int colour, const char *type)
|
||||
}
|
||||
|
||||
if (colour & COLOUR_FLAG_RGB) {
|
||||
colour_split_rgb(colour & 0xffffff, &r, &g, &b);
|
||||
if (*type == '3') {
|
||||
if (!tty_term_has(tty->term, TTYC_SETRGBF))
|
||||
return (-1);
|
||||
colour_split_rgb(colour & 0xffffff, &r, &g, &b);
|
||||
goto fallback_rgb;
|
||||
tty_putcode3(tty, TTYC_SETRGBF, r, g, b);
|
||||
} else {
|
||||
if (!tty_term_has(tty->term, TTYC_SETRGBB))
|
||||
return (-1);
|
||||
colour_split_rgb(colour & 0xffffff, &r, &g, &b);
|
||||
goto fallback_rgb;
|
||||
tty_putcode3(tty, TTYC_SETRGBB, r, g, b);
|
||||
}
|
||||
return (0);
|
||||
@ -2606,6 +2641,12 @@ fallback_256:
|
||||
log_debug("%s: 256 colour fallback: %s", tty->client->name, s);
|
||||
tty_puts(tty, s);
|
||||
return (0);
|
||||
|
||||
fallback_rgb:
|
||||
xsnprintf(s, sizeof s, "\033[%s;2;%d;%d;%dm", type, r, g, b);
|
||||
log_debug("%s: RGB colour fallback: %s", tty->client->name, s);
|
||||
tty_puts(tty, s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
23
external/bsd/tmux/dist/utf8.c
vendored
23
external/bsd/tmux/dist/utf8.c
vendored
@ -415,7 +415,7 @@ utf8_cstrwidth(const char *s)
|
||||
return (width);
|
||||
}
|
||||
|
||||
/* Pad UTF-8 string to width. Caller frees. */
|
||||
/* Pad UTF-8 string to width on the left. Caller frees. */
|
||||
char *
|
||||
utf8_padcstr(const char *s, u_int width)
|
||||
{
|
||||
@ -436,6 +436,27 @@ utf8_padcstr(const char *s, u_int width)
|
||||
return (out);
|
||||
}
|
||||
|
||||
/* Pad UTF-8 string to width on the right. Caller frees. */
|
||||
char *
|
||||
utf8_rpadcstr(const char *s, u_int width)
|
||||
{
|
||||
size_t slen;
|
||||
char *out;
|
||||
u_int n, i;
|
||||
|
||||
n = utf8_cstrwidth(s);
|
||||
if (n >= width)
|
||||
return (xstrdup(s));
|
||||
|
||||
slen = strlen(s);
|
||||
out = xmalloc(slen + 1 + (width - n));
|
||||
for (i = 0; i < width - n; i++)
|
||||
out[i] = ' ';
|
||||
memcpy(out + i, s, slen);
|
||||
out[i + slen] = '\0';
|
||||
return (out);
|
||||
}
|
||||
|
||||
int
|
||||
utf8_cstrhas(const char *s, const struct utf8_data *ud)
|
||||
{
|
||||
|
95
external/bsd/tmux/dist/window-buffer.c
vendored
95
external/bsd/tmux/dist/window-buffer.c
vendored
@ -74,6 +74,7 @@ static const char *window_buffer_sort_list[] = {
|
||||
"name",
|
||||
"size"
|
||||
};
|
||||
static struct mode_tree_sort_criteria *window_buffer_sort;
|
||||
|
||||
struct window_buffer_itemdata {
|
||||
const char *name;
|
||||
@ -112,43 +113,29 @@ window_buffer_free_item(struct window_buffer_itemdata *item)
|
||||
}
|
||||
|
||||
static int
|
||||
window_buffer_cmp_name(const void *a0, const void *b0)
|
||||
window_buffer_cmp(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_buffer_itemdata *const *a = a0;
|
||||
const struct window_buffer_itemdata *const *b = b0;
|
||||
const struct window_buffer_itemdata *const *a = a0;
|
||||
const struct window_buffer_itemdata *const *b = b0;
|
||||
int result = 0;
|
||||
|
||||
return (strcmp((*a)->name, (*b)->name));
|
||||
}
|
||||
if (window_buffer_sort->field == WINDOW_BUFFER_BY_TIME)
|
||||
result = (*b)->order - (*a)->order;
|
||||
else if (window_buffer_sort->field == WINDOW_BUFFER_BY_SIZE)
|
||||
result = (*b)->size - (*a)->size;
|
||||
|
||||
static int
|
||||
window_buffer_cmp_time(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_buffer_itemdata *const *a = a0;
|
||||
const struct window_buffer_itemdata *const *b = b0;
|
||||
/* Use WINDOW_BUFFER_BY_NAME as default order and tie breaker. */
|
||||
if (result == 0)
|
||||
result = strcmp((*a)->name, (*b)->name);
|
||||
|
||||
if ((*a)->order > (*b)->order)
|
||||
return (-1);
|
||||
if ((*a)->order < (*b)->order)
|
||||
return (1);
|
||||
return (strcmp((*a)->name, (*b)->name));
|
||||
}
|
||||
|
||||
static int
|
||||
window_buffer_cmp_size(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_buffer_itemdata *const *a = a0;
|
||||
const struct window_buffer_itemdata *const *b = b0;
|
||||
|
||||
if ((*a)->size > (*b)->size)
|
||||
return (-1);
|
||||
if ((*a)->size < (*b)->size)
|
||||
return (1);
|
||||
return (strcmp((*a)->name, (*b)->name));
|
||||
if (window_buffer_sort->reversed)
|
||||
result = -result;
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
|
||||
const char *filter)
|
||||
window_buffer_build(void *modedata, struct mode_tree_sort_criteria *sort_crit,
|
||||
__unused uint64_t *tag, const char *filter)
|
||||
{
|
||||
struct window_buffer_modedata *data = modedata;
|
||||
struct window_buffer_itemdata *item;
|
||||
@ -174,20 +161,9 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
|
||||
item->order = paste_buffer_order(pb);
|
||||
}
|
||||
|
||||
switch (sort_type) {
|
||||
case WINDOW_BUFFER_BY_NAME:
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_buffer_cmp_name);
|
||||
break;
|
||||
case WINDOW_BUFFER_BY_TIME:
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_buffer_cmp_time);
|
||||
break;
|
||||
case WINDOW_BUFFER_BY_SIZE:
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_buffer_cmp_size);
|
||||
break;
|
||||
}
|
||||
window_buffer_sort = sort_crit;
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_buffer_cmp);
|
||||
|
||||
if (cmd_find_valid_state(&data->fs)) {
|
||||
s = data->fs.s;
|
||||
@ -231,9 +207,9 @@ window_buffer_draw(__unused void *modedata, void *itemdata,
|
||||
{
|
||||
struct window_buffer_itemdata *item = itemdata;
|
||||
struct paste_buffer *pb;
|
||||
char line[1024];
|
||||
const char *pdata, *end, *cp;
|
||||
size_t psize, at;
|
||||
const char *pdata, *start, *end;
|
||||
char *buf = NULL;
|
||||
size_t psize;
|
||||
u_int i, cx = ctx->s->cx, cy = ctx->s->cy;
|
||||
|
||||
pb = paste_get_name(item->name);
|
||||
@ -242,27 +218,22 @@ window_buffer_draw(__unused void *modedata, void *itemdata,
|
||||
|
||||
pdata = end = paste_buffer_data(pb, &psize);
|
||||
for (i = 0; i < sy; i++) {
|
||||
at = 0;
|
||||
while (end != pdata + psize && *end != '\n') {
|
||||
if ((sizeof line) - at > 5) {
|
||||
cp = vis(line + at, *end, VIS_OCTAL|VIS_TAB, 0);
|
||||
at = cp - line;
|
||||
}
|
||||
start = end;
|
||||
while (end != pdata + psize && *end != '\n')
|
||||
end++;
|
||||
}
|
||||
if (at > sx)
|
||||
at = sx;
|
||||
line[at] = '\0';
|
||||
|
||||
if (*line != '\0') {
|
||||
buf = xreallocarray(buf, 4, end - start + 1);
|
||||
utf8_strvis(buf, start, end - start, VIS_OCTAL|VIS_TAB);
|
||||
if (*buf != '\0') {
|
||||
screen_write_cursormove(ctx, cx, cy + i, 0);
|
||||
screen_write_puts(ctx, &grid_default_cell, "%s", line);
|
||||
screen_write_nputs(ctx, sx, &grid_default_cell, "%s",
|
||||
buf);
|
||||
}
|
||||
|
||||
if (end == pdata + psize)
|
||||
break;
|
||||
end++;
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -357,7 +328,7 @@ window_buffer_resize(struct window_mode_entry *wme, u_int sx, u_int sy)
|
||||
}
|
||||
|
||||
static void
|
||||
window_buffer_do_delete(void* modedata, void *itemdata,
|
||||
window_buffer_do_delete(void *modedata, void *itemdata,
|
||||
__unused struct client *c, __unused key_code key)
|
||||
{
|
||||
struct window_buffer_modedata *data = modedata;
|
||||
@ -371,7 +342,7 @@ window_buffer_do_delete(void* modedata, void *itemdata,
|
||||
}
|
||||
|
||||
static void
|
||||
window_buffer_do_paste(void* modedata, void *itemdata, struct client *c,
|
||||
window_buffer_do_paste(void *modedata, void *itemdata, struct client *c,
|
||||
__unused key_code key)
|
||||
{
|
||||
struct window_buffer_modedata *data = modedata;
|
||||
|
108
external/bsd/tmux/dist/window-client.c
vendored
108
external/bsd/tmux/dist/window-client.c
vendored
@ -75,6 +75,7 @@ static const char *window_client_sort_list[] = {
|
||||
"creation",
|
||||
"activity"
|
||||
};
|
||||
static struct mode_tree_sort_criteria *window_client_sort;
|
||||
|
||||
struct window_client_itemdata {
|
||||
struct client *c;
|
||||
@ -110,60 +111,48 @@ window_client_free_item(struct window_client_itemdata *item)
|
||||
}
|
||||
|
||||
static int
|
||||
window_client_cmp_name(const void *a0, const void *b0)
|
||||
window_client_cmp(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_client_itemdata *const *a = a0;
|
||||
const struct window_client_itemdata *const *b = b0;
|
||||
const struct window_client_itemdata *const *a = a0;
|
||||
const struct window_client_itemdata *const *b = b0;
|
||||
const struct window_client_itemdata *itema = *a;
|
||||
const struct window_client_itemdata *itemb = *b;
|
||||
struct client *ca = itema->c;
|
||||
struct client *cb = itemb->c;
|
||||
int result = 0;
|
||||
|
||||
return (strcmp((*a)->c->name, (*b)->c->name));
|
||||
}
|
||||
switch (window_client_sort->field) {
|
||||
case WINDOW_CLIENT_BY_SIZE:
|
||||
result = ca->tty.sx - cb->tty.sx;
|
||||
if (result == 0)
|
||||
result = ca->tty.sy - cb->tty.sy;
|
||||
break;
|
||||
case WINDOW_CLIENT_BY_CREATION_TIME:
|
||||
if (timercmp(&ca->creation_time, &cb->creation_time, >))
|
||||
result = -1;
|
||||
else if (timercmp(&ca->creation_time, &cb->creation_time, <))
|
||||
result = 1;
|
||||
break;
|
||||
case WINDOW_CLIENT_BY_ACTIVITY_TIME:
|
||||
if (timercmp(&ca->activity_time, &cb->activity_time, >))
|
||||
result = -1;
|
||||
else if (timercmp(&ca->activity_time, &cb->activity_time, <))
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
static int
|
||||
window_client_cmp_size(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_client_itemdata *const *a = a0;
|
||||
const struct window_client_itemdata *const *b = b0;
|
||||
/* Use WINDOW_CLIENT_BY_NAME as default order and tie breaker. */
|
||||
if (result == 0)
|
||||
result = strcmp(ca->name, cb->name);
|
||||
|
||||
if ((*a)->c->tty.sx < (*b)->c->tty.sx)
|
||||
return (-1);
|
||||
if ((*a)->c->tty.sx > (*b)->c->tty.sx)
|
||||
return (1);
|
||||
if ((*a)->c->tty.sy < (*b)->c->tty.sy)
|
||||
return (-1);
|
||||
if ((*a)->c->tty.sy > (*b)->c->tty.sy)
|
||||
return (1);
|
||||
return (strcmp((*a)->c->name, (*b)->c->name));
|
||||
}
|
||||
|
||||
static int
|
||||
window_client_cmp_creation_time(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_client_itemdata *const *a = a0;
|
||||
const struct window_client_itemdata *const *b = b0;
|
||||
|
||||
if (timercmp(&(*a)->c->creation_time, &(*b)->c->creation_time, >))
|
||||
return (-1);
|
||||
if (timercmp(&(*a)->c->creation_time, &(*b)->c->creation_time, <))
|
||||
return (1);
|
||||
return (strcmp((*a)->c->name, (*b)->c->name));
|
||||
}
|
||||
|
||||
static int
|
||||
window_client_cmp_activity_time(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_client_itemdata *const *a = a0;
|
||||
const struct window_client_itemdata *const *b = b0;
|
||||
|
||||
if (timercmp(&(*a)->c->activity_time, &(*b)->c->activity_time, >))
|
||||
return (-1);
|
||||
if (timercmp(&(*a)->c->activity_time, &(*b)->c->activity_time, <))
|
||||
return (1);
|
||||
return (strcmp((*a)->c->name, (*b)->c->name));
|
||||
if (window_client_sort->reversed)
|
||||
result = -result;
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
|
||||
const char *filter)
|
||||
window_client_build(void *modedata, struct mode_tree_sort_criteria *sort_crit,
|
||||
__unused uint64_t *tag, const char *filter)
|
||||
{
|
||||
struct window_client_modedata *data = modedata;
|
||||
struct window_client_itemdata *item;
|
||||
@ -187,24 +176,9 @@ window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
|
||||
c->references++;
|
||||
}
|
||||
|
||||
switch (sort_type) {
|
||||
case WINDOW_CLIENT_BY_NAME:
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_client_cmp_name);
|
||||
break;
|
||||
case WINDOW_CLIENT_BY_SIZE:
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_client_cmp_size);
|
||||
break;
|
||||
case WINDOW_CLIENT_BY_CREATION_TIME:
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_client_cmp_creation_time);
|
||||
break;
|
||||
case WINDOW_CLIENT_BY_ACTIVITY_TIME:
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_client_cmp_activity_time);
|
||||
break;
|
||||
}
|
||||
window_client_sort = sort_crit;
|
||||
qsort(data->item_list, data->item_size, sizeof *data->item_list,
|
||||
window_client_cmp);
|
||||
|
||||
for (i = 0; i < data->item_size; i++) {
|
||||
item = data->item_list[i];
|
||||
@ -236,7 +210,7 @@ window_client_draw(__unused void *modedata, void *itemdata,
|
||||
struct window_pane *wp;
|
||||
u_int cx = s->cx, cy = s->cy, lines, at;
|
||||
|
||||
if (c->session == NULL || (c->flags & (CLIENT_DEAD|CLIENT_DETACHING)))
|
||||
if (c->session == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
|
||||
return;
|
||||
wp = c->session->curw->window->active;
|
||||
|
||||
@ -339,7 +313,7 @@ window_client_resize(struct window_mode_entry *wme, u_int sx, u_int sy)
|
||||
}
|
||||
|
||||
static void
|
||||
window_client_do_detach(void* modedata, void *itemdata,
|
||||
window_client_do_detach(void *modedata, void *itemdata,
|
||||
__unused struct client *c, key_code key)
|
||||
{
|
||||
struct window_client_modedata *data = modedata;
|
||||
|
1326
external/bsd/tmux/dist/window-copy.c
vendored
1326
external/bsd/tmux/dist/window-copy.c
vendored
File diff suppressed because it is too large
Load Diff
178
external/bsd/tmux/dist/window-tree.c
vendored
178
external/bsd/tmux/dist/window-tree.c
vendored
@ -33,7 +33,7 @@ static void window_tree_key(struct window_mode_entry *,
|
||||
struct client *, struct session *,
|
||||
struct winlink *, key_code, struct mouse_event *);
|
||||
|
||||
#define WINDOW_TREE_DEFAULT_COMMAND "switch-client -t '%%'"
|
||||
#define WINDOW_TREE_DEFAULT_COMMAND "switch-client -Zt '%%'"
|
||||
|
||||
#define WINDOW_TREE_DEFAULT_FORMAT \
|
||||
"#{?pane_format," \
|
||||
@ -89,6 +89,7 @@ static const char *window_tree_sort_list[] = {
|
||||
"name",
|
||||
"time"
|
||||
};
|
||||
static struct mode_tree_sort_criteria *window_tree_sort;
|
||||
|
||||
enum window_tree_type {
|
||||
WINDOW_TREE_NONE,
|
||||
@ -184,62 +185,92 @@ window_tree_free_item(struct window_tree_itemdata *item)
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_cmp_session_name(const void *a0, const void *b0)
|
||||
window_tree_cmp_session(const void *a0, const void *b0)
|
||||
{
|
||||
const struct session *const *a = a0;
|
||||
const struct session *const *b = b0;
|
||||
const struct session *const *a = a0;
|
||||
const struct session *const *b = b0;
|
||||
const struct session *sa = *a;
|
||||
const struct session *sb = *b;
|
||||
int result = 0;
|
||||
|
||||
return (strcmp((*a)->name, (*b)->name));
|
||||
switch (window_tree_sort->field) {
|
||||
case WINDOW_TREE_BY_INDEX:
|
||||
result = sa->id - sb->id;
|
||||
break;
|
||||
case WINDOW_TREE_BY_TIME:
|
||||
if (timercmp(&sa->activity_time, &sb->activity_time, >)) {
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (timercmp(&sa->activity_time, &sb->activity_time, <)) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WINDOW_TREE_BY_NAME:
|
||||
result = strcmp(sa->name, sb->name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (window_tree_sort->reversed)
|
||||
result = -result;
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_cmp_session_time(const void *a0, const void *b0)
|
||||
window_tree_cmp_window(const void *a0, const void *b0)
|
||||
{
|
||||
const struct session *const *a = a0;
|
||||
const struct session *const *b = b0;
|
||||
const struct winlink *const *a = a0;
|
||||
const struct winlink *const *b = b0;
|
||||
const struct winlink *wla = *a;
|
||||
const struct winlink *wlb = *b;
|
||||
struct window *wa = wla->window;
|
||||
struct window *wb = wlb->window;
|
||||
int result = 0;
|
||||
|
||||
if (timercmp(&(*a)->activity_time, &(*b)->activity_time, >))
|
||||
return (-1);
|
||||
if (timercmp(&(*a)->activity_time, &(*b)->activity_time, <))
|
||||
return (1);
|
||||
return (strcmp((*a)->name, (*b)->name));
|
||||
switch (window_tree_sort->field) {
|
||||
case WINDOW_TREE_BY_INDEX:
|
||||
result = wla->idx - wlb->idx;
|
||||
break;
|
||||
case WINDOW_TREE_BY_TIME:
|
||||
if (timercmp(&wa->activity_time, &wb->activity_time, >)) {
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
if (timercmp(&wa->activity_time, &wb->activity_time, <)) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WINDOW_TREE_BY_NAME:
|
||||
result = strcmp(wa->name, wb->name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (window_tree_sort->reversed)
|
||||
result = -result;
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_cmp_window_name(const void *a0, const void *b0)
|
||||
window_tree_cmp_pane(const void *a0, const void *b0)
|
||||
{
|
||||
const struct winlink *const *a = a0;
|
||||
const struct winlink *const *b = b0;
|
||||
const struct window_pane *const *a = a0;
|
||||
const struct window_pane *const *b = b0;
|
||||
int result;
|
||||
|
||||
return (strcmp((*a)->window->name, (*b)->window->name));
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_cmp_window_time(const void *a0, const void *b0)
|
||||
{
|
||||
const struct winlink *const *a = a0;
|
||||
const struct winlink *const *b = b0;
|
||||
|
||||
if (timercmp(&(*a)->window->activity_time,
|
||||
&(*b)->window->activity_time, >))
|
||||
return (-1);
|
||||
if (timercmp(&(*a)->window->activity_time,
|
||||
&(*b)->window->activity_time, <))
|
||||
return (1);
|
||||
return (strcmp((*a)->window->name, (*b)->window->name));
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_cmp_pane_time(const void *a0, const void *b0)
|
||||
{
|
||||
const struct window_pane *const *a = a0;
|
||||
const struct window_pane *const *b = b0;
|
||||
|
||||
if ((*a)->active_point < (*b)->active_point)
|
||||
return (-1);
|
||||
if ((*a)->active_point > (*b)->active_point)
|
||||
return (1);
|
||||
return (0);
|
||||
if (window_tree_sort->field == WINDOW_TREE_BY_TIME)
|
||||
result = (*a)->active_point - (*b)->active_point;
|
||||
else {
|
||||
/*
|
||||
* Panes don't have names, so use number order for any other
|
||||
* sort field.
|
||||
*/
|
||||
result = (*a)->id - (*b)->id;
|
||||
}
|
||||
if (window_tree_sort->reversed)
|
||||
result = -result;
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -285,8 +316,9 @@ window_tree_filter_pane(struct session *s, struct winlink *wl,
|
||||
}
|
||||
|
||||
static int
|
||||
window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
|
||||
u_int sort_type, struct mode_tree_item *parent, const char *filter)
|
||||
window_tree_build_window(struct session *s, struct winlink *wl,
|
||||
void *modedata, struct mode_tree_sort_criteria *sort_crit,
|
||||
struct mode_tree_item *parent, const char *filter)
|
||||
{
|
||||
struct window_tree_modedata *data = modedata;
|
||||
struct window_tree_itemdata *item;
|
||||
@ -335,16 +367,8 @@ window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
|
||||
if (n == 0)
|
||||
goto empty;
|
||||
|
||||
switch (sort_type) {
|
||||
case WINDOW_TREE_BY_INDEX:
|
||||
break;
|
||||
case WINDOW_TREE_BY_NAME:
|
||||
/* Panes don't have names, so leave in number order. */
|
||||
break;
|
||||
case WINDOW_TREE_BY_TIME:
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_pane_time);
|
||||
break;
|
||||
}
|
||||
window_tree_sort = sort_crit;
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_pane);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
window_tree_build_pane(s, wl, l[i], modedata, mti);
|
||||
@ -359,8 +383,8 @@ empty:
|
||||
}
|
||||
|
||||
static void
|
||||
window_tree_build_session(struct session *s, void* modedata,
|
||||
u_int sort_type, const char *filter)
|
||||
window_tree_build_session(struct session *s, void *modedata,
|
||||
struct mode_tree_sort_criteria *sort_crit, const char *filter)
|
||||
{
|
||||
struct window_tree_modedata *data = modedata;
|
||||
struct window_tree_itemdata *item;
|
||||
@ -392,20 +416,12 @@ window_tree_build_session(struct session *s, void* modedata,
|
||||
l = xreallocarray(l, n + 1, sizeof *l);
|
||||
l[n++] = wl;
|
||||
}
|
||||
switch (sort_type) {
|
||||
case WINDOW_TREE_BY_INDEX:
|
||||
break;
|
||||
case WINDOW_TREE_BY_NAME:
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_window_name);
|
||||
break;
|
||||
case WINDOW_TREE_BY_TIME:
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_window_time);
|
||||
break;
|
||||
}
|
||||
window_tree_sort = sort_crit;
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_window);
|
||||
|
||||
empty = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!window_tree_build_window(s, l[i], modedata, sort_type, mti,
|
||||
if (!window_tree_build_window(s, l[i], modedata, sort_crit, mti,
|
||||
filter))
|
||||
empty++;
|
||||
}
|
||||
@ -418,8 +434,8 @@ window_tree_build_session(struct session *s, void* modedata,
|
||||
}
|
||||
|
||||
static void
|
||||
window_tree_build(void *modedata, u_int sort_type, uint64_t *tag,
|
||||
const char *filter)
|
||||
window_tree_build(void *modedata, struct mode_tree_sort_criteria *sort_crit,
|
||||
uint64_t *tag, const char *filter)
|
||||
{
|
||||
struct window_tree_modedata *data = modedata;
|
||||
struct session *s, **l;
|
||||
@ -446,19 +462,11 @@ window_tree_build(void *modedata, u_int sort_type, uint64_t *tag,
|
||||
l = xreallocarray(l, n + 1, sizeof *l);
|
||||
l[n++] = s;
|
||||
}
|
||||
switch (sort_type) {
|
||||
case WINDOW_TREE_BY_INDEX:
|
||||
break;
|
||||
case WINDOW_TREE_BY_NAME:
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_session_name);
|
||||
break;
|
||||
case WINDOW_TREE_BY_TIME:
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_session_time);
|
||||
break;
|
||||
}
|
||||
window_tree_sort = sort_crit;
|
||||
qsort(l, n, sizeof *l, window_tree_cmp_session);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
window_tree_build_session(l[i], modedata, sort_type, filter);
|
||||
window_tree_build_session(l[i], modedata, sort_crit, filter);
|
||||
free(l);
|
||||
|
||||
switch (data->type) {
|
||||
@ -966,7 +974,7 @@ window_tree_get_target(struct window_tree_itemdata *item,
|
||||
}
|
||||
|
||||
static void
|
||||
window_tree_command_each(void* modedata, void* itemdata, struct client *c,
|
||||
window_tree_command_each(void *modedata, void *itemdata, struct client *c,
|
||||
__unused key_code key)
|
||||
{
|
||||
struct window_tree_modedata *data = modedata;
|
||||
@ -1023,7 +1031,7 @@ window_tree_command_free(void *modedata)
|
||||
}
|
||||
|
||||
static void
|
||||
window_tree_kill_each(__unused void* modedata, void* itemdata,
|
||||
window_tree_kill_each(__unused void *modedata, void *itemdata,
|
||||
__unused struct client *c, __unused key_code key)
|
||||
{
|
||||
struct window_tree_itemdata *item = itemdata;
|
||||
|
139
external/bsd/tmux/dist/window.c
vendored
139
external/bsd/tmux/dist/window.c
vendored
@ -306,12 +306,17 @@ window_update_activity(struct window *w)
|
||||
}
|
||||
|
||||
struct window *
|
||||
window_create(u_int sx, u_int sy)
|
||||
window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
|
||||
{
|
||||
struct window *w;
|
||||
|
||||
if (xpixel == 0)
|
||||
xpixel = DEFAULT_XPIXEL;
|
||||
if (ypixel == 0)
|
||||
ypixel = DEFAULT_YPIXEL;
|
||||
|
||||
w = xcalloc(1, sizeof *w);
|
||||
w->name = NULL;
|
||||
w->name = xstrdup("");
|
||||
w->flags = 0;
|
||||
|
||||
TAILQ_INIT(&w->panes);
|
||||
@ -322,6 +327,8 @@ window_create(u_int sx, u_int sy)
|
||||
|
||||
w->sx = sx;
|
||||
w->sy = sy;
|
||||
w->xpixel = xpixel;
|
||||
w->ypixel = ypixel;
|
||||
|
||||
w->options = options_create(global_w_options);
|
||||
|
||||
@ -408,11 +415,49 @@ window_set_name(struct window *w, const char *new_name)
|
||||
}
|
||||
|
||||
void
|
||||
window_resize(struct window *w, u_int sx, u_int sy)
|
||||
window_resize(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
|
||||
{
|
||||
log_debug("%s: @%u resize %ux%u", __func__, w->id, sx, sy);
|
||||
if (xpixel == 0)
|
||||
xpixel = DEFAULT_XPIXEL;
|
||||
if (ypixel == 0)
|
||||
ypixel = DEFAULT_YPIXEL;
|
||||
|
||||
log_debug("%s: @%u resize %ux%u (%ux%u)", __func__, w->id, sx, sy,
|
||||
xpixel == -1 ? w->xpixel : (u_int)xpixel,
|
||||
ypixel == -1 ? w->ypixel : (u_int)ypixel);
|
||||
w->sx = sx;
|
||||
w->sy = sy;
|
||||
if (xpixel != -1)
|
||||
w->xpixel = xpixel;
|
||||
if (ypixel != -1)
|
||||
w->ypixel = ypixel;
|
||||
}
|
||||
|
||||
void
|
||||
window_pane_send_resize(struct window_pane *wp, int yadjust)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
struct winsize ws;
|
||||
|
||||
if (wp->fd == -1)
|
||||
return;
|
||||
|
||||
memset(&ws, 0, sizeof ws);
|
||||
ws.ws_col = wp->sx;
|
||||
ws.ws_row = wp->sy + yadjust;
|
||||
ws.ws_xpixel = w->xpixel * ws.ws_col;
|
||||
ws.ws_ypixel = w->ypixel * ws.ws_row;
|
||||
if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
|
||||
#ifdef __sun
|
||||
/*
|
||||
* Some versions of Solaris apparently can return an error when
|
||||
* resizing; don't know why this happens, can't reproduce on
|
||||
* other platforms and ignoring it doesn't seem to cause any
|
||||
* issues.
|
||||
*/
|
||||
if (errno != EINVAL && errno != ENXIO)
|
||||
#endif
|
||||
fatal("ioctl failed");
|
||||
}
|
||||
|
||||
int
|
||||
@ -503,31 +548,38 @@ window_get_active_at(struct window *w, u_int x, u_int y)
|
||||
struct window_pane *
|
||||
window_find_string(struct window *w, const char *s)
|
||||
{
|
||||
u_int x, y;
|
||||
u_int x, y, top = 0, bottom = w->sy - 1;
|
||||
int status;
|
||||
|
||||
x = w->sx / 2;
|
||||
y = w->sy / 2;
|
||||
|
||||
status = options_get_number(w->options, "pane-border-status");
|
||||
if (status == PANE_STATUS_TOP)
|
||||
top++;
|
||||
else if (status == PANE_STATUS_BOTTOM)
|
||||
bottom--;
|
||||
|
||||
if (strcasecmp(s, "top") == 0)
|
||||
y = 0;
|
||||
y = top;
|
||||
else if (strcasecmp(s, "bottom") == 0)
|
||||
y = w->sy - 1;
|
||||
y = bottom;
|
||||
else if (strcasecmp(s, "left") == 0)
|
||||
x = 0;
|
||||
else if (strcasecmp(s, "right") == 0)
|
||||
x = w->sx - 1;
|
||||
else if (strcasecmp(s, "top-left") == 0) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
y = top;
|
||||
} else if (strcasecmp(s, "top-right") == 0) {
|
||||
x = w->sx - 1;
|
||||
y = 0;
|
||||
y = top;
|
||||
} else if (strcasecmp(s, "bottom-left") == 0) {
|
||||
x = 0;
|
||||
y = w->sy - 1;
|
||||
y = bottom;
|
||||
} else if (strcasecmp(s, "bottom-right") == 0) {
|
||||
x = w->sx - 1;
|
||||
y = w->sy - 1;
|
||||
y = bottom;
|
||||
} else
|
||||
return (NULL);
|
||||
|
||||
@ -585,6 +637,28 @@ window_unzoom(struct window *w)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
window_push_zoom(struct window *w, int flag)
|
||||
{
|
||||
log_debug("%s: @%u %d", __func__, w->id,
|
||||
flag && (w->flags & WINDOW_ZOOMED));
|
||||
if (flag && (w->flags & WINDOW_ZOOMED))
|
||||
w->flags |= WINDOW_WASZOOMED;
|
||||
else
|
||||
w->flags &= ~WINDOW_WASZOOMED;
|
||||
return (window_unzoom(w) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
window_pop_zoom(struct window *w)
|
||||
{
|
||||
log_debug("%s: @%u %d", __func__, w->id,
|
||||
!!(w->flags & WINDOW_WASZOOMED));
|
||||
if (w->flags & WINDOW_WASZOOMED)
|
||||
return (window_zoom(w->active) == 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct window_pane *
|
||||
window_add_pane(struct window *w, struct window_pane *other, u_int hlimit,
|
||||
int flags)
|
||||
@ -933,7 +1007,7 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
|
||||
if (wme != NULL && wme->mode->resize != NULL)
|
||||
wme->mode->resize(wme, sx, sy);
|
||||
|
||||
wp->flags |= PANE_RESIZE;
|
||||
wp->flags |= (PANE_RESIZE|PANE_RESIZED);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1173,7 +1247,7 @@ window_pane_reset_mode_all(struct window_pane *wp)
|
||||
window_pane_reset_mode(wp);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
||||
struct winlink *wl, key_code key, struct mouse_event *m)
|
||||
{
|
||||
@ -1181,23 +1255,24 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
||||
struct window_pane *wp2;
|
||||
|
||||
if (KEYC_IS_MOUSE(key) && m == NULL)
|
||||
return;
|
||||
return (-1);
|
||||
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme != NULL) {
|
||||
wp->modelast = time(NULL);
|
||||
if (wme->mode->key != NULL)
|
||||
wme->mode->key(wme, c, s, wl, (key & ~KEYC_XTERM), m);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (wp->fd == -1 || wp->flags & PANE_INPUTOFF)
|
||||
return;
|
||||
return (0);
|
||||
|
||||
input_key(wp, key, m);
|
||||
if (input_key(wp, key, m) != 0)
|
||||
return (-1);
|
||||
|
||||
if (KEYC_IS_MOUSE(key))
|
||||
return;
|
||||
return (0);
|
||||
if (options_get_number(wp->window->options, "synchronize-panes")) {
|
||||
TAILQ_FOREACH(wp2, &wp->window->panes, entry) {
|
||||
if (wp2 != wp &&
|
||||
@ -1208,6 +1283,7 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s,
|
||||
input_key(wp2, key, NULL);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1542,31 +1618,28 @@ winlink_shuffle_up(struct session *s, struct winlink *wl)
|
||||
}
|
||||
|
||||
static void
|
||||
window_pane_input_callback(struct client *c, int closed, void *data)
|
||||
window_pane_input_callback(struct client *c, __unused const char *path,
|
||||
int error, int closed, struct evbuffer *buffer, void *data)
|
||||
{
|
||||
struct window_pane_input_data *cdata = data;
|
||||
struct window_pane *wp;
|
||||
struct evbuffer *evb = c->stdin_data;
|
||||
u_char *buf = EVBUFFER_DATA(evb);
|
||||
size_t len = EVBUFFER_LENGTH(evb);
|
||||
u_char *buf = EVBUFFER_DATA(buffer);
|
||||
size_t len = EVBUFFER_LENGTH(buffer);
|
||||
|
||||
wp = window_pane_find_by_id(cdata->wp);
|
||||
if (wp == NULL || closed || c->flags & CLIENT_DEAD) {
|
||||
if (wp == NULL || closed || error != 0 || c->flags & CLIENT_DEAD) {
|
||||
if (wp == NULL)
|
||||
c->flags |= CLIENT_EXIT;
|
||||
evbuffer_drain(evb, len);
|
||||
|
||||
c->stdin_callback = NULL;
|
||||
server_client_unref(c);
|
||||
|
||||
evbuffer_drain(buffer, len);
|
||||
cmdq_continue(cdata->item);
|
||||
free(cdata);
|
||||
|
||||
server_client_unref(c);
|
||||
free(cdata);
|
||||
return;
|
||||
}
|
||||
|
||||
input_parse_buffer(wp, buf, len);
|
||||
evbuffer_drain(evb, len);
|
||||
evbuffer_drain(buffer, len);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1585,6 +1658,8 @@ window_pane_start_input(struct window_pane *wp, struct cmdq_item *item,
|
||||
cdata->item = item;
|
||||
cdata->wp = wp->id;
|
||||
|
||||
return (server_set_stdin_callback(c, window_pane_input_callback, cdata,
|
||||
cause));
|
||||
c->references++;
|
||||
file_read(c, "-", window_pane_input_callback, cdata);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
1
external/bsd/tmux/dist/xmalloc.h
vendored
1
external/bsd/tmux/dist/xmalloc.h
vendored
@ -27,6 +27,7 @@ void *xmalloc(size_t);
|
||||
void *xcalloc(size_t, size_t);
|
||||
void *xrealloc(void *, size_t);
|
||||
void *xreallocarray(void *, size_t, size_t);
|
||||
void *xrecallocarray(void *, size_t, size_t, size_t);
|
||||
char *xstrdup(const char *);
|
||||
char *xstrndup(const char *, size_t);
|
||||
int xasprintf(char **, const char *, ...)
|
||||
|
15
external/bsd/tmux/usr.bin/tmux/Makefile
vendored
15
external/bsd/tmux/usr.bin/tmux/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.24 2020/01/06 21:03:24 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.25 2020/11/01 15:16:05 christos Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
@ -85,6 +85,7 @@ colour.c \
|
||||
control-notify.c \
|
||||
control.c \
|
||||
environ.c \
|
||||
file.c \
|
||||
format.c \
|
||||
format-draw.c \
|
||||
grid-view.c \
|
||||
@ -160,13 +161,11 @@ CPPFLAGS+= \
|
||||
-DHAVE_ASPRINTF=1 \
|
||||
-DHAVE_B64_NTOP=1 \
|
||||
-DHAVE_BITSTRING_H=1 \
|
||||
-DHAVE_BSD_GETOPT=1 \
|
||||
-DHAVE_CFMAKERAW=1 \
|
||||
-DHAVE_CLOSEFROM=1 \
|
||||
-DHAVE_CURSES_H=1 \
|
||||
-DHAVE_DAEMON=1 \
|
||||
-DHAVE_DECL_OPTARG=1 \
|
||||
-DHAVE_DECL_OPTIND=1 \
|
||||
-DHAVE_DECL_OPTRESET=1 \
|
||||
-DHAVE_DIRENT_H=1 \
|
||||
-DHAVE_FCNTL_CLOSEM=1 \
|
||||
-DHAVE_FCNTL_H=1 \
|
||||
@ -209,13 +208,13 @@ CPPFLAGS+= \
|
||||
-DPACKAGE=\"tmux\" \
|
||||
-DPACKAGE_BUGREPORT=\"\" \
|
||||
-DPACKAGE_NAME=\"tmux\" \
|
||||
-DPACKAGE_STRING=\"tmux\ 3.0a\" \
|
||||
-DPACKAGE_STRING=\"tmux\ 3.1c\" \
|
||||
-DPACKAGE_TARNAME=\"tmux\" \
|
||||
-DPACKAGE_URL=\"\" \
|
||||
-DPACKAGE_VERSION=\"3.0a\" \
|
||||
-DPACKAGE_VERSION=\"3.1c\" \
|
||||
-DSTDC_HEADERS=1 \
|
||||
-DTMUX_CONF="\"/etc/tmux.conf\"" \
|
||||
-DVERSION=\"3.0a\" \
|
||||
-DTMUX_CONF="\"/etc/tmux.conf:~/.tmux.conf:~/.config/tmux/tmux.conf\"" \
|
||||
-DTMUX_VERSION=\"3.1c\" \
|
||||
-D_ALL_SOURCE=1 \
|
||||
-D_GNU_SOURCE=1 \
|
||||
-D_OPENBSD_SOURCE \
|
||||
|
Loading…
Reference in New Issue
Block a user