diff --git a/cmd-attach-session.c b/cmd-attach-session.c index e9c23df3..079b22f3 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -54,8 +54,7 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, struct client *c = item->client, *c_loop; struct winlink *wl = item->state.tflag.wl; struct window_pane *wp = item->state.tflag.wp; - char *cause, *cwd; - struct format_tree *ft; + char *cause; if (RB_EMPTY(&sessions)) { cmdq_error(item, "no sessions"); @@ -77,13 +76,8 @@ cmd_attach_session(struct cmdq_item *item, int dflag, int rflag, } if (cflag != NULL) { - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, c, s, wl, wp); - cwd = format_expand(ft, cflag); - format_free(ft); - free((void *)s->cwd); - s->cwd = cwd; + s->cwd = format_single(item, cflag, c, s, wl, wp); } if (c->session != NULL) { diff --git a/cmd-break-pane.c b/cmd-break-pane.c index fdefeb17..3c564a0c 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -48,6 +48,7 @@ static enum cmd_retval cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + struct client *c = item->state.c; struct winlink *wl = item->state.sflag.wl; struct session *src_s = item->state.sflag.s; struct session *dst_s = item->state.tflag.s; @@ -55,7 +56,6 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) struct window *w = wl->window; char *name, *cause; int idx = item->state.tflag.idx; - struct format_tree *ft; const char *template; char *cp; @@ -106,15 +106,9 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL) template = BREAK_PANE_TEMPLATE; - - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, item->state.c, dst_s, wl, wp); - - cp = format_expand(ft, template); + cp = format_single(item, template, c, dst_s, wl, wp); cmdq_print(item, "%s", cp); free(cp); - - format_free(ft); } return (CMD_RETURN_NORMAL); } diff --git a/cmd-if-shell.c b/cmd-if-shell.c index ec4bf68e..f7d95d53 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -69,10 +69,10 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) char *shellcmd, *cmd, *cause; struct cmd_list *cmdlist; struct cmdq_item *new_item; + struct client *c = item->state.c; struct session *s = item->state.tflag.s; struct winlink *wl = item->state.tflag.wl; struct window_pane *wp = item->state.tflag.wp; - struct format_tree *ft; const char *cwd; if (item->client != NULL && item->client->session == NULL) @@ -82,11 +82,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) else cwd = NULL; - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, item->state.c, s, wl, wp); - shellcmd = format_expand(ft, args->argv[0]); - format_free(ft); - + shellcmd = format_single(item, args->argv[0], c, s, wl, wp); if (args_has(args, 'F')) { cmd = NULL; if (*shellcmd != '0' && *shellcmd != '\0') diff --git a/cmd-new-session.c b/cmd-new-session.c index 08fc6065..a5b197b0 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -78,7 +78,6 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) char **argv, *cause, *cp; int detached, already_attached, idx, argc; u_int sx, sy; - struct format_tree *ft; struct environ_entry *envent; struct cmd_find_state fs; @@ -155,10 +154,8 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) /* Get the new session working directory. */ if (args_has(args, 'c')) { - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, c, NULL, NULL, NULL); - to_free = cwd = format_expand(ft, args_get(args, 'c')); - format_free(ft); + cwd = args_get(args, 'c'); + to_free = cwd = format_single(item, cwd, c, NULL, NULL, NULL); } else if (c != NULL && c->session == NULL && c->cwd != NULL) cwd = c->cwd; else @@ -322,15 +319,9 @@ 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; - - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, c, s, NULL, NULL); - - cp = format_expand(ft, template); + cp = format_single(item, template, c, s, NULL, NULL); cmdq_print(item, "%s", cp); free(cp); - - format_free(ft); } if (!detached) diff --git a/cmd-new-window.c b/cmd-new-window.c index 082b7443..c10a4aaf 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -59,7 +59,6 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item) const char *cmd, *path, *template, *cwd, *to_free; char **argv, *cause, *cp; int argc, detached; - struct format_tree *ft; struct environ_entry *envent; struct cmd_find_state fs; @@ -95,10 +94,8 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item) to_free = NULL; if (args_has(args, 'c')) { - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, c, s, NULL, NULL); - cwd = to_free = format_expand(ft, args_get(args, 'c')); - format_free(ft); + cwd = args_get(args, 'c'); + to_free = cwd = format_single(item, cwd, c, s, NULL, NULL); } else if (item->client != NULL && item->client->session == NULL) cwd = item->client->cwd; else @@ -142,15 +139,9 @@ 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; - - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, c, s, wl, NULL); - - cp = format_expand(ft, template); + cp = format_single(item, template, c, s, wl, NULL); cmdq_print(item, "%s", cp); free(cp); - - format_free(ft); } if (to_free != NULL) diff --git a/cmd-run-shell.c b/cmd-run-shell.c index e6cd7936..d06d7f99 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -86,11 +86,10 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; struct cmd_run_shell_data *cdata; - char *shellcmd; + struct client *c = item->state.c; struct session *s = item->state.tflag.s; struct winlink *wl = item->state.tflag.wl; struct window_pane *wp = item->state.tflag.wp; - struct format_tree *ft; const char *cwd; if (item->client != NULL && item->client->session == NULL) @@ -100,13 +99,8 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) else cwd = NULL; - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, item->state.c, s, wl, wp); - shellcmd = format_expand(ft, args->argv[0]); - format_free(ft); - cdata = xcalloc(1, sizeof *cdata); - cdata->cmd = shellcmd; + cdata->cmd = format_single(item, args->argv[0], c, s, wl, wp); if (args_has(args, 't') && wp != NULL) cdata->wp_id = wp->id; @@ -116,7 +110,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) if (!args_has(args, 'b')) cdata->item = item; - job_run(shellcmd, s, cwd, cmd_run_shell_callback, cmd_run_shell_free, + job_run(cdata->cmd, s, cwd, cmd_run_shell_callback, cmd_run_shell_free, cdata); if (args_has(args, 'b')) diff --git a/cmd-split-window.c b/cmd-split-window.c index 57d58056..cbd5e0b2 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -53,6 +53,7 @@ static enum cmd_retval cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; + struct client *c = item->state.c; struct session *s = item->state.tflag.s; struct winlink *wl = item->state.tflag.wl; struct window *w = wl->window; @@ -64,7 +65,6 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) int argc, size, percentage; enum layout_type type; struct layout_cell *lc; - struct format_tree *ft; struct environ_entry *envent; struct cmd_find_state fs; @@ -91,10 +91,8 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) to_free = NULL; if (args_has(args, 'c')) { - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, item->state.c, s, NULL, NULL); - to_free = cwd = format_expand(ft, args_get(args, 'c')); - format_free(ft); + cwd = args_get(args, 'c'); + to_free = cwd = format_single(item, cwd, c, s, NULL, NULL); } else if (item->client != NULL && item->client->session == NULL) cwd = item->client->cwd; else @@ -167,15 +165,9 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL) template = SPLIT_WINDOW_TEMPLATE; - - ft = format_create(item, FORMAT_NONE, 0); - format_defaults(ft, item->state.c, s, wl, new_wp); - - cp = format_expand(ft, template); + cp = format_single(item, template, c, s, wl, new_wp); cmdq_print(item, "%s", cp); free(cp); - - format_free(ft); } notify_window("window-layout-changed", w); diff --git a/control-notify.c b/control-notify.c index 3b2d32eb..230bce61 100644 --- a/control-notify.c +++ b/control-notify.c @@ -64,10 +64,9 @@ control_notify_window_layout_changed(struct window *w) { struct client *c; struct session *s; - struct format_tree *ft; struct winlink *wl; const char *template; - char *expanded; + char *cp; template = "%layout-change #{window_id} #{window_layout} " "#{window_visible_layout} #{window_flags}"; @@ -88,15 +87,12 @@ control_notify_window_layout_changed(struct window *w) if (w->layout_root == NULL) continue; - ft = format_create(NULL, FORMAT_NONE, 0); wl = winlink_find_by_window(&s->windows, w); if (wl != NULL) { - format_defaults(ft, c, NULL, wl, NULL); - expanded = format_expand(ft, template); - control_write(c, "%s", expanded); - free(expanded); + cp = format_single(NULL, template, c, NULL, wl, NULL); + control_write(c, "%s", cp); + free(cp); } - format_free(ft); } } diff --git a/format.c b/format.c index b00b1f9e..78f7a94d 100644 --- a/format.c +++ b/format.c @@ -519,7 +519,6 @@ format_merge(struct format_tree *ft, struct format_tree *from) if (fe->value != NULL) format_add(ft, fe->key, "%s", fe->value); } - } /* Create a new tree. */ @@ -1081,6 +1080,22 @@ format_expand(struct format_tree *ft, const char *fmt) return (buf); } +/* Expand a single string. */ +char * +format_single(struct cmdq_item *item, const char *fmt, struct client *c, + struct session *s, struct winlink *wl, struct window_pane *wp) +{ + struct format_tree *ft; + char *expanded; + + ft = format_create(item, FORMAT_NONE, 0); + format_defaults(ft, c, s, wl, wp); + + expanded = format_expand(ft, fmt); + format_free(ft); + return (expanded); +} + /* Set defaults for any of arguments that are not NULL. */ void format_defaults(struct format_tree *ft, struct client *c, struct session *s, diff --git a/options.c b/options.c index 4de25937..4cd3ea10 100644 --- a/options.c +++ b/options.c @@ -427,6 +427,8 @@ options_match(const char *s, int *idx, int* ambiguous) size_t namelen; name = options_parse(s, idx); + if (name == NULL) + return (NULL); namelen = strlen(name); if (*name == '@') { diff --git a/tmux.h b/tmux.h index ded5dfc9..a799d45e 100644 --- a/tmux.h +++ b/tmux.h @@ -1512,6 +1512,9 @@ void printflike(3, 4) format_add(struct format_tree *, const char *, const char *, ...); char *format_expand_time(struct format_tree *, const char *, time_t); char *format_expand(struct format_tree *, const char *); +char *format_single(struct cmdq_item *, const char *, + struct client *, struct session *, struct winlink *, + struct window_pane *); void format_defaults(struct format_tree *, struct client *, struct session *, struct winlink *, struct window_pane *); void format_defaults_window(struct format_tree *, struct window *); diff --git a/tty.c b/tty.c index acc7ab54..0ed6125e 100644 --- a/tty.c +++ b/tty.c @@ -235,7 +235,7 @@ tty_start_tty(struct tty *tty) tty_putcode(tty, TTYC_SMCUP); - tty_putcode(tty, TTYC_RMKX); + tty_putcode(tty, TTYC_SMKX); if (tty_use_acs(tty)) tty_putcode(tty, TTYC_ENACS); tty_putcode(tty, TTYC_CLEAR); @@ -573,12 +573,6 @@ tty_update_mode(struct tty *tty, int mode, struct screen *s) tty_puts(tty, "\033[?1006l"); } } - if (changed & MODE_KKEYPAD) { - if (mode & MODE_KKEYPAD) - tty_putcode(tty, TTYC_SMKX); - else - tty_putcode(tty, TTYC_RMKX); - } if (changed & MODE_BRACKETPASTE) { if (mode & MODE_BRACKETPASTE) tty_puts(tty, "\033[?2004h"); diff --git a/window-copy.c b/window-copy.c index cb6243db..e50db0a1 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1604,29 +1604,23 @@ window_copy_copy_buffer(struct window_pane *wp, const char *bufname, void *buf, } static void -window_copy_copy_pipe(struct window_pane *wp, struct session *sess, +window_copy_copy_pipe(struct window_pane *wp, struct session *s, const char *bufname, const char *arg) { - void *buf; - size_t len; - struct job *job; - struct format_tree *ft; - char *expanded; + void *buf; + size_t len; + struct job *job; + char *expanded; buf = window_copy_get_selection(wp, &len); if (buf == NULL) return; + expanded = format_single(NULL, arg, NULL, s, NULL, wp); - ft = format_create(NULL, FORMAT_NONE, 0); - format_defaults(ft, NULL, sess, NULL, wp); - expanded = format_expand(ft, arg); - - job = job_run(expanded, sess, NULL, NULL, NULL, NULL); + job = job_run(expanded, s, NULL, NULL, NULL, NULL); bufferevent_write(job->event, buf, len); free(expanded); - format_free(ft); - window_copy_copy_buffer(wp, bufname, buf, len); } @@ -1927,14 +1921,22 @@ static void window_copy_cursor_left(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; - u_int py; + u_int py, cx; + struct grid_cell gc; py = screen_hsize(data->backing) + data->cy - data->oy; - if (data->cx == 0 && py > 0) { + cx = data->cx; + while (cx > 0) { + grid_get_cell(data->backing->grid, cx, py, &gc); + if (~gc.flags & GRID_FLAG_PADDING) + break; + cx--; + } + if (cx == 0 && py > 0) { window_copy_cursor_up(wp, 0); window_copy_cursor_end_of_line(wp); - } else if (data->cx > 0) { - window_copy_update_cursor(wp, data->cx - 1, data->cy); + } else if (cx > 0) { + window_copy_update_cursor(wp, cx - 1, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } @@ -1944,21 +1946,29 @@ static void window_copy_cursor_right(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; - u_int px, py, yy; + u_int px, py, yy, cx, cy; + struct grid_cell gc; py = screen_hsize(data->backing) + data->cy - data->oy; yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1; if (data->screen.sel.flag && data->rectflag) px = screen_size_x(&data->screen); - else { + else px = window_copy_find_length(wp, py); - } if (data->cx >= px && py < yy) { window_copy_cursor_start_of_line(wp); window_copy_cursor_down(wp, 0); } else if (data->cx < px) { - window_copy_update_cursor(wp, data->cx + 1, data->cy); + cx = data->cx + 1; + cy = screen_hsize(data->backing) + data->cy - data->oy; + while (cx < px) { + grid_get_cell(data->backing->grid, cx, cy, &gc); + if (~gc.flags & GRID_FLAG_PADDING) + break; + cx++; + } + window_copy_update_cursor(wp, cx, data->cy); if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); }