enum cmd_retval cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c = cmdq->client; struct session *s; struct window_pane *wp = cmdq->state.tflag.wp; if (args_has(args, 'M')) { if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL) return (CMD_RETURN_NORMAL); if (c == NULL || c->session != s) return (CMD_RETURN_NORMAL); } if (self->entry == &cmd_clock_mode_entry) { window_pane_set_mode(wp, &window_clock_mode); return (CMD_RETURN_NORMAL); } if (wp->mode != &window_copy_mode) { if (window_pane_set_mode(wp, &window_copy_mode) != 0) return (CMD_RETURN_NORMAL); window_copy_init_from_pane(wp, args_has(self->args, 'e')); } if (args_has(args, 'M')) { if (wp->mode != NULL && wp->mode != &window_copy_mode) return (CMD_RETURN_NORMAL); window_copy_start_drag(c, &cmdq->item->mouse); } if (wp->mode == &window_copy_mode && args_has(self->args, 'u')) window_copy_pageup(wp); return (CMD_RETURN_NORMAL); }
static enum cmd_retval cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; struct cmdq_shared *shared = item->shared; struct client *c = item->client; struct session *s; struct window_pane *wp = item->target.wp; if (args_has(args, 'M')) { if ((wp = cmd_mouse_pane(&shared->mouse, &s, NULL)) == NULL) return (CMD_RETURN_NORMAL); if (c == NULL || c->session != s) return (CMD_RETURN_NORMAL); } if (self->entry == &cmd_clock_mode_entry) { window_pane_set_mode(wp, &window_clock_mode, NULL, NULL); return (CMD_RETURN_NORMAL); } if (window_pane_set_mode(wp, &window_copy_mode, NULL, args) != 0) return (CMD_RETURN_NORMAL); if (args_has(args, 'M')) window_copy_start_drag(c, &shared->mouse); if (args_has(self->args, 'u')) window_copy_pageup(wp, 0); return (CMD_RETURN_NORMAL); }
static void cmd_run_shell_print(struct job *job, const char *msg) { struct cmd_run_shell_data *cdata = job->data; struct window_pane *wp = NULL; struct cmd_find_state fs; if (cdata->wp_id != -1) wp = window_pane_find_by_id(cdata->wp_id); if (wp == NULL) { if (cdata->item != NULL) { cmdq_print(cdata->item, "%s", msg); return; } if (cmd_find_from_nothing(&fs, 0) != 0) return; wp = fs.wp; if (wp == NULL) return; } if (window_pane_set_mode(wp, &window_copy_mode, NULL, NULL) == 0) window_copy_init_for_output(wp); if (wp->mode == &window_copy_mode) window_copy_add(wp, "%s", msg); }
enum cmd_retval cmd_pipe_input_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; struct client *c1; struct window_choose_data *cdata; struct winlink *wl; struct session *s; struct window_pane *wp; if ((c = cmd_current_client(cmdq)) == NULL) { cmdq_error(cmdq, "no client available"); return (CMD_RETURN_ERROR); } if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) return (CMD_RETURN_ERROR); if (wl->window->active == wp){ cmdq_error(cmdq, "cant select self pane"); return (CMD_RETURN_ERROR); } if (window_pane_set_mode(wl->window->active, &window_input_mode) != 0) return (CMD_RETURN_NORMAL); window_input_set_pane(wl->window->active, wp); return (CMD_RETURN_NORMAL); }
int cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct cmd_choose_window_data *cdata; struct session *s; struct winlink *wl, *wm; struct format_tree *ft; const char *template; char *line; u_int idx, cur; if (ctx->curclient == NULL) { ctx->error(ctx, "must be run interactively"); return (-1); } s = ctx->curclient->session; if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) return (-1); if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) return (0); if ((template = args_get(args, 'F')) == NULL)
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct mouse_event *m) { char buf[10]; size_t len; if (wp->screen->mode & ALL_MOUSE_MODES) { if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->b + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->b > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->b + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); } else if ((m->b & MOUSE_BUTTON) != MOUSE_2) { if (options_get_number(&wp->window->options, "mode-mouse") && window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, NULL, m); } } }
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) { char buf[40]; size_t len; struct paste_buffer *pb; if (wp->screen->mode & ALL_MOUSE_MODES) { /* * Use the SGR (1006) extension only if the application * requested it and the underlying terminal also sent the event * in this format (this is because an old style mouse release * event cannot be converted into the new SGR format, since the * released button is unknown). Otherwise pretend that tmux * doesn't speak this extension, and fall back to the UTF-8 * (1005) extension if the application requested, or to the * legacy format. */ if (m->sgr && (wp->screen->mode & MODE_MOUSE_SGR)) { len = xsnprintf(buf, sizeof buf, "\033[<%d;%d;%d%c", m->sgr_xb, m->x + 1, m->y + 1, m->sgr_rel ? 'm' : 'M'); } else if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->xb + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->xb > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->xb + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); return; } if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) && options_get_number(&wp->window->options, "mode-mouse") == 1) { pb = paste_get_top(&global_buffers); if (pb != NULL) { paste_send_pane(pb, wp, "\r", wp->screen->mode & MODE_BRACKETPASTE); } } else if ((m->xb & 3) != 1 && options_get_number(&wp->window->options, "mode-mouse") == 1) { if (window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, s, m); } } }
int cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct window_pane *wp; if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) return (-1); window_pane_set_mode(wp, &window_clock_mode); return (0); }
int cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct window_pane *wp; if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) return (-1); window_pane_set_mode(wp, &window_clock_mode); return (0); }
enum cmd_retval cmd_clock_mode_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); window_pane_set_mode(wp, &window_clock_mode); return (CMD_RETURN_NORMAL); }
static enum cmd_retval cmd_find_window_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args, *new_args; struct window_pane *wp = item->target.wp; const char *s = args->argv[0]; char *filter, *argv = { NULL }; int C, N, T; C = args_has(args, 'C'); N = args_has(args, 'N'); T = args_has(args, 'T'); if (!C && !N && !T) C = N = T = 1; if (C && N && T) { xasprintf(&filter, "#{||:" "#{C:%s},#{||:#{m:*%s*,#{window_name}}," "#{m:*%s*,#{pane_title}}}}", s, s, s); } else if (C && N) { xasprintf(&filter, "#{||:#{C:%s},#{m:*%s*,#{window_name}}}", s, s); } else if (C && T) { xasprintf(&filter, "#{||:#{C:%s},#{m:*%s*,#{pane_title}}}", s, s); } else if (N && T) { xasprintf(&filter, "#{||:#{m:*%s*,#{window_name}},#{m:*%s*,#{pane_title}}}", s, s); } else if (C) xasprintf(&filter, "#{C:%s}", s); else if (N) xasprintf(&filter, "#{m:*%s*,#{window_name}}", s); else xasprintf(&filter, "#{m:*%s*,#{pane_title}}", s); new_args = args_parse("", 1, &argv); args_set(new_args, 'f', filter); window_pane_set_mode(wp, &window_tree_mode, &item->target, new_args); args_free(new_args); free(filter); return (CMD_RETURN_NORMAL); }
void printflike2 key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...) { struct winlink *wl = ctx->curclient->session->curw; va_list ap; if (wl->window->active->mode != &window_more_mode) window_pane_reset_mode(wl->window->active); window_pane_set_mode(wl->window->active, &window_more_mode); va_start(ap, fmt); window_more_vadd(wl->window->active, fmt, ap); va_end(ap); }
int cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct window_pane *wp; if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL) return (-1); window_pane_set_mode(wp, &window_copy_mode); if (wp->mode == &window_copy_mode && cmd_check_flag(data->chflags, 'u')) window_copy_pageup(wp); return (0); }
int cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct winlink *wl; struct window_pane *wp; if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) return (-1); wp = wl->window->active; window_pane_set_mode(wp, &window_scroll_mode); if (wp->mode == &window_scroll_mode && data->flags & CMD_UFLAG) window_scroll_pageup(wp); return (0); }
int cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct window_pane *wp; if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL) return (-1); if (window_pane_set_mode(wp, &window_copy_mode) != 0) return (0); window_copy_init_from_pane(wp); if (wp->mode == &window_copy_mode && args_has(self->args, 'u')) window_copy_pageup(wp); return (0); }
enum cmd_retval cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) return (CMD_RETURN_ERROR); if (window_pane_set_mode(wp, &window_copy_mode) != 0) return (CMD_RETURN_NORMAL); window_copy_init_from_pane(wp); if (wp->mode == &window_copy_mode && args_has(self->args, 'u')) window_copy_pageup(wp); return (CMD_RETURN_NORMAL); }
void cmd_run_shell_print(struct job *job, const char *msg) { struct cmd_run_shell_data *cdata = job->data; struct window_pane *wp = NULL; if (cdata->wp_id != -1) wp = window_pane_find_by_id(cdata->wp_id); if (wp == NULL) { cmdq_print(cdata->cmdq, "%s", msg); return; } if (window_pane_set_mode(wp, &window_copy_mode) == 0) window_copy_init_for_output(wp); if (wp->mode == &window_copy_mode) window_copy_add(wp, "%s", msg); }
void cfg_show_causes(struct session *s) { struct window_pane *wp; char *cause; u_int i; if (s == NULL || ARRAY_EMPTY(&cfg_causes)) return; wp = s->curw->window->active; window_pane_set_mode(wp, &window_copy_mode); window_copy_init_for_output(wp); for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) { cause = ARRAY_ITEM(&cfg_causes, i); window_copy_add(wp, "%s", cause); free(cause); } ARRAY_FREE(&cfg_causes); }
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) { char buf[10]; size_t len; struct paste_buffer *pb; if (wp->screen->mode & ALL_MOUSE_MODES) { if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->xb + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->xb > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->xb + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); return; } if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) && options_get_number(&wp->window->options, "mode-mouse") == 1) { pb = paste_get_top(&global_buffers); if (pb != NULL) { paste_send_pane(pb, wp, "\r", wp->screen->mode & MODE_BRACKETPASTE); } } else if ((m->xb & 3) != 1 && options_get_number(&wp->window->options, "mode-mouse") == 1) { if (window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, s, m); } } }
static enum cmd_retval cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; struct window_pane *wp = item->target.wp; const struct window_mode *mode; if (self->entry == &cmd_choose_buffer_entry) { if (paste_get_top(NULL) == NULL) return (CMD_RETURN_NORMAL); mode = &window_buffer_mode; } else if (self->entry == &cmd_choose_client_entry) { if (server_client_how_many() == 0) return (CMD_RETURN_NORMAL); mode = &window_client_mode; } else mode = &window_tree_mode; window_pane_set_mode(wp, mode, &item->target, args); return (CMD_RETURN_NORMAL); }
void cfg_show_causes(struct session *s) { struct window_pane *wp; u_int i; if (s == NULL || cfg_ncauses == 0) return; wp = s->curw->window->active; window_pane_set_mode(wp, &window_copy_mode); window_copy_init_for_output(wp); for (i = 0; i < cfg_ncauses; i++) { window_copy_add(wp, "%s", cfg_causes[i]); free(cfg_causes[i]); } free(cfg_causes); cfg_causes = NULL; cfg_ncauses = 0; }
int cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct window_choose_data *cdata; struct winlink *wl; struct client *c; const char *template; char *action; u_int i, idx, cur; if (ctx->curclient == NULL) { ctx->error(ctx, "must be run interactively"); return (-1); } if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL) return (-1); if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) return (0); if ((template = args_get(args, 'F')) == NULL)
int cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct causelist causes; char *cause; struct window_pane *wp; int retval; u_int i; ARRAY_INIT(&causes); retval = load_cfg(args->argv[0], ctx, &causes); if (ARRAY_EMPTY(&causes)) return (retval); if (retval == 1 && !RB_EMPTY(&sessions) && ctx->cmdclient != NULL) { wp = RB_MIN(sessions, &sessions)->curw->window->active; window_pane_set_mode(wp, &window_copy_mode); window_copy_init_for_output(wp); for (i = 0; i < ARRAY_LENGTH(&causes); i++) { cause = ARRAY_ITEM(&causes, i); window_copy_add(wp, "%s", cause); xfree(cause); } } else { for (i = 0; i < ARRAY_LENGTH(&causes); i++) { cause = ARRAY_ITEM(&causes, i); ctx->print(ctx, "%s", cause); xfree(cause); } } ARRAY_FREE(&causes); return (retval); }
int cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct session *s, *old_s, *groupwith; struct window *w; struct window_pane *wp; struct environ env; struct termios tio, *tiop; struct passwd *pw; const char *newname, *target, *update, *cwd; char *overrides, *cmd, *cause; int detached, idx; u_int sx, sy, i; newname = args_get(args, 's'); if (newname != NULL && session_find(newname) != NULL) { ctx->error(ctx, "duplicate session: %s", newname); return (-1); } target = args_get(args, 't'); if (target != NULL) { groupwith = cmd_find_session(ctx, target); if (groupwith == NULL) return (-1); } else groupwith = NULL; /* * There are three cases: * * 1. If cmdclient is non-NULL, new-session has been called from the * command-line - cmdclient is to become a new attached, interactive * client. Unless -d is given, the terminal must be opened and then * the client sent MSG_READY. * * 2. If cmdclient is NULL, new-session has been called from an * existing client (such as a key binding). * * 3. Both are NULL, the command was in the configuration file. Treat * this as if -d was given even if it was not. * * In all cases, a new additional session needs to be created and * (unless -d) set as the current session for the client. */ /* Set -d if no client. */ detached = args_has(args, 'd'); if (ctx->cmdclient == NULL && ctx->curclient == NULL) detached = 1; /* * Save the termios settings, part of which is used for new windows in * this session. * * This is read again with tcgetattr() rather than using tty.tio as if * detached, tty_open won't be called. Because of this, it must be done * before opening the terminal as that calls tcsetattr() to prepare for * tmux taking over. */ if (ctx->cmdclient != NULL && ctx->cmdclient->tty.fd != -1) { if (tcgetattr(ctx->cmdclient->tty.fd, &tio) != 0) fatal("tcgetattr failed"); tiop = &tio; } else tiop = NULL; /* Open the terminal if necessary. */ if (!detached && ctx->cmdclient != NULL) { if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) { ctx->error(ctx, "not a terminal"); return (-1); } overrides = options_get_string(&global_s_options, "terminal-overrides"); if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) { ctx->error(ctx, "open terminal failed: %s", cause); xfree(cause); return (-1); } } /* Get the new session working directory. */ if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) cwd = ctx->cmdclient->cwd; else { pw = getpwuid(getuid()); if (pw->pw_dir != NULL && *pw->pw_dir != '\0') cwd = pw->pw_dir; else cwd = "/"; } /* Find new session size. */ if (detached) { sx = 80; sy = 24; } else if (ctx->cmdclient != NULL) { sx = ctx->cmdclient->tty.sx; sy = ctx->cmdclient->tty.sy; } else { sx = ctx->curclient->tty.sx; sy = ctx->curclient->tty.sy; } if (sy > 0 && options_get_number(&global_s_options, "status")) sy--; if (sx == 0) sx = 1; if (sy == 0) sy = 1; /* Figure out the command for the new window. */ if (target != NULL) cmd = NULL; else if (args->argc != 0) cmd = args->argv[0]; else cmd = options_get_string(&global_s_options, "default-command"); /* Construct the environment. */ environ_init(&env); update = options_get_string(&global_s_options, "update-environment"); if (ctx->cmdclient != NULL) environ_update(update, &ctx->cmdclient->environ, &env); /* Create the new session. */ idx = -1 - options_get_number(&global_s_options, "base-index"); s = session_create(newname, cmd, cwd, &env, tiop, idx, sx, sy, &cause); if (s == NULL) { ctx->error(ctx, "create session failed: %s", cause); xfree(cause); return (-1); } environ_free(&env); /* Set the initial window name if one given. */ if (cmd != NULL && args_has(args, 'n')) { w = s->curw->window; xfree(w->name); w->name = xstrdup(args_get(args, 'n')); options_set_number(&w->options, "automatic-rename", 0); } /* * If a target session is given, this is to be part of a session group, * so add it to the group and synchronize. */ if (groupwith != NULL) { session_group_add(groupwith, s); session_group_synchronize_to(s); session_select(s, RB_ROOT(&s->windows)->idx); } /* * Set the client to the new session. If a command client exists, it is * taking this session and needs to get MSG_READY and stay around. */ if (!detached) { if (ctx->cmdclient != NULL) { server_write_client(ctx->cmdclient, MSG_READY, NULL, 0); old_s = ctx->cmdclient->session; if (old_s != NULL) ctx->cmdclient->last_session = old_s; ctx->cmdclient->session = s; session_update_activity(s); server_redraw_client(ctx->cmdclient); } else { old_s = ctx->curclient->session; if (old_s != NULL) ctx->curclient->last_session = old_s; ctx->curclient->session = s; session_update_activity(s); server_redraw_client(ctx->curclient); } } recalculate_sizes(); server_update_socket(); /* * If there are still configuration file errors to display, put the new * session's current window into more mode and display them now. */ if (cfg_finished && !ARRAY_EMPTY(&cfg_causes)) { wp = s->curw->window->active; window_pane_set_mode(wp, &window_copy_mode); window_copy_init_for_output(wp); for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) { cause = ARRAY_ITEM(&cfg_causes, i); window_copy_add(wp, "%s", cause); xfree(cause); } ARRAY_FREE(&cfg_causes); } return (!detached); /* 1 means don't tell command client to exit */ }