diff options
-rw-r--r-- | alerts.c | 10 | ||||
-rw-r--r-- | client.c | 18 | ||||
-rw-r--r-- | cmd-attach-session.c | 5 | ||||
-rw-r--r-- | cmd-bind-key.c | 42 | ||||
-rw-r--r-- | cmd-display-message.c | 16 | ||||
-rw-r--r-- | cmd-display-panes.c | 91 | ||||
-rw-r--r-- | cmd-list-keys.c | 2 | ||||
-rw-r--r-- | cmd-load-buffer.c | 24 | ||||
-rw-r--r-- | cmd-queue.c | 2 | ||||
-rw-r--r-- | cmd-select-pane.c | 1 | ||||
-rw-r--r-- | cmd-set-buffer.c | 10 | ||||
-rw-r--r-- | cmd-set-environment.c | 25 | ||||
-rw-r--r-- | cmd-source-file.c | 14 | ||||
-rw-r--r-- | cmd-unbind-key.c | 54 | ||||
-rw-r--r-- | colour.c | 6 | ||||
-rw-r--r-- | compat.h | 4 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | control.c | 4 | ||||
-rw-r--r-- | format.c | 38 | ||||
-rw-r--r-- | grid.c | 21 | ||||
-rw-r--r-- | input-keys.c | 2 | ||||
-rw-r--r-- | input.c | 47 | ||||
-rw-r--r-- | key-bindings.c | 10 | ||||
-rw-r--r-- | mode-tree.c | 2 | ||||
-rw-r--r-- | options-table.c | 9 | ||||
-rw-r--r-- | options.c | 42 | ||||
-rw-r--r-- | popup.c | 2 | ||||
-rw-r--r-- | proc.c | 1 | ||||
-rw-r--r-- | server-client.c | 12 | ||||
-rw-r--r-- | server-fn.c | 1 | ||||
-rw-r--r-- | server.c | 8 | ||||
-rw-r--r-- | status.c | 12 | ||||
-rw-r--r-- | tmux.1 | 58 | ||||
-rw-r--r-- | tmux.c | 4 | ||||
-rw-r--r-- | tmux.h | 16 | ||||
-rw-r--r-- | tty-term.c | 2 | ||||
-rw-r--r-- | tty.c | 22 | ||||
-rw-r--r-- | window-copy.c | 156 | ||||
-rw-r--r-- | window-customize.c | 10 |
39 files changed, 539 insertions, 270 deletions
@@ -200,7 +200,7 @@ alerts_check_bell(struct window *w) * not check WINLINK_BELL). */ s = wl->session; - if (s->curw != wl) { + if (s->curw != wl || s->attached == 0) { wl->flags |= WINLINK_BELL; server_status_session(s); } @@ -236,7 +236,7 @@ alerts_check_activity(struct window *w) if (wl->flags & WINLINK_ACTIVITY) continue; s = wl->session; - if (s->curw != wl) { + if (s->curw != wl || s->attached == 0) { wl->flags |= WINLINK_ACTIVITY; server_status_session(s); } @@ -272,7 +272,7 @@ alerts_check_silence(struct window *w) if (wl->flags & WINLINK_SILENCE) continue; s = wl->session; - if (s->curw != wl) { + if (s->curw != wl || s->attached == 0) { wl->flags |= WINLINK_SILENCE; server_status_session(s); } @@ -316,9 +316,9 @@ alerts_set_message(struct winlink *wl, const char *type, const char *option) if (visual == VISUAL_OFF) continue; if (c->session->curw == wl) - status_message_set(c, 1, "%s in current window", type); + status_message_set(c, -1, 1, "%s in current window", type); else { - status_message_set(c, 1, "%s in window %d", type, + status_message_set(c, -1, 1, "%s in window %d", type, wl->idx); } } @@ -59,7 +59,8 @@ 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 int client_connect(struct event_base *, const char *, + uint64_t); static void client_send_identify(const char *, const char *, int); static void client_signal(int); static void client_dispatch(struct imsg *, void *); @@ -100,7 +101,7 @@ client_get_lock(char *lockfile) /* Connect client to server. */ static int -client_connect(struct event_base *base, const char *path, int flags) +client_connect(struct event_base *base, const char *path, uint64_t flags) { struct sockaddr_un sa; size_t size; @@ -238,7 +239,8 @@ client_exit(void) /* Client main loop. */ int -client_main(struct event_base *base, int argc, char **argv, int flags, int feat) +client_main(struct event_base *base, int argc, char **argv, uint64_t flags, + int feat) { struct cmd_parse_result *pr; struct msg_command *data; @@ -284,7 +286,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat) /* Save the flags. */ client_flags = flags; - log_debug("flags are %#llx", client_flags); + log_debug("flags are %#llx", (unsigned long long)client_flags); /* Initialize the client socket and start the server. */ fd = client_connect(base, socket_path, client_flags); @@ -442,6 +444,8 @@ client_send_identify(const char *ttynam, const char *cwd, int feat) pid_t pid; proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags); + proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &client_flags, + sizeof client_flags); if ((s = getenv("TERM")) == NULL) s = ""; @@ -891,7 +895,8 @@ client_dispatch_wait(struct imsg *imsg) fatalx("bad MSG_FLAGS string"); memcpy(&client_flags, data, sizeof client_flags); - log_debug("new flags are %#llx", client_flags); + log_debug("new flags are %#llx", + (unsigned long long)client_flags); break; case MSG_SHELL: if (datalen == 0 || data[datalen - 1] != '\0') @@ -944,7 +949,8 @@ client_dispatch_attached(struct imsg *imsg) fatalx("bad MSG_FLAGS string"); memcpy(&client_flags, data, sizeof client_flags); - log_debug("new flags are %#llx", client_flags); + log_debug("new flags are %#llx", + (unsigned long long)client_flags); break; case MSG_DETACH: case MSG_DETACHKILL: diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 38d9c024..6a7ebba7 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -59,7 +59,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag, struct session *s; struct winlink *wl; struct window_pane *wp; - char *cause; + char *cwd, *cause; enum msgtype msgtype; if (RB_EMPTY(&sessions)) { @@ -99,8 +99,9 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag, } if (cflag != NULL) { + cwd = format_single(item, cflag, c, s, wl, wp); free((void *)s->cwd); - s->cwd = format_single(item, cflag, c, s, wl, wp); + s->cwd = cwd; } if (fflag) server_client_set_flags(c, fflag); diff --git a/cmd-bind-key.c b/cmd-bind-key.c index dcb56c06..b4e4167c 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -33,9 +33,9 @@ const struct cmd_entry cmd_bind_key_entry = { .name = "bind-key", .alias = "bind", - .args = { "nrN:T:", 2, -1 }, + .args = { "nrN:T:", 1, -1 }, .usage = "[-nr] [-T key-table] [-N note] key " - "command [arguments]", + "[command [arguments]]", .flags = CMD_AFTERHOOK, .exec = cmd_bind_key_exec @@ -46,7 +46,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = cmd_get_args(self); key_code key; - const char *tablename, *note; + const char *tablename, *note = args_get(args, 'N'); struct cmd_parse_result *pr; char **argv = args->argv; int argc = args->argc, repeat; @@ -65,22 +65,24 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item) tablename = "prefix"; repeat = args_has(args, 'r'); - if (argc == 2) - pr = cmd_parse_from_string(argv[1], NULL); - else - pr = cmd_parse_from_arguments(argc - 1, argv + 1, NULL); - switch (pr->status) { - case CMD_PARSE_EMPTY: - cmdq_error(item, "empty command"); - return (CMD_RETURN_ERROR); - case CMD_PARSE_ERROR: - cmdq_error(item, "%s", pr->error); - free(pr->error); - return (CMD_RETURN_ERROR); - case CMD_PARSE_SUCCESS: - break; - } - note = args_get(args, 'N'); - key_bindings_add(tablename, key, note, repeat, pr->cmdlist); + if (argc != 1) { + if (argc == 2) + pr = cmd_parse_from_string(argv[1], NULL); + else + pr = cmd_parse_from_arguments(argc - 1, argv + 1, NULL); + switch (pr->status) { + case CMD_PARSE_EMPTY: + cmdq_error(item, "empty command"); + return (CMD_RETURN_ERROR); + case CMD_PARSE_ERROR: + cmdq_error(item, "%s", pr->error); + free(pr->error); + return (CMD_RETURN_ERROR); + case CMD_PARSE_SUCCESS: + break; + } + key_bindings_add(tablename, key, note, repeat, pr->cmdlist); + } else + key_bindings_add(tablename, key, note, repeat, NULL); return (CMD_RETURN_NORMAL); } diff --git a/cmd-display-message.c b/cmd-display-message.c index 634f0a93..fc9c4851 100644 --- a/cmd-display-message.c +++ b/cmd-display-message.c @@ -39,8 +39,8 @@ const struct cmd_entry cmd_display_message_entry = { .name = "display-message", .alias = "display", - .args = { "ac:Ipt:F:v", 0, 1 }, - .usage = "[-aIpv] [-c target-client] [-F format] " + .args = { "acd:Ipt:F:v", 0, 1 }, + .usage = "[-aIpv] [-c target-client] [-d delay] [-F format] " CMD_TARGET_PANE_USAGE " [message]", .target = { 't', CMD_FIND_PANE, 0 }, @@ -68,6 +68,7 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item) struct window_pane *wp = target->wp; const char *template; char *msg, *cause; + int delay = -1; struct format_tree *ft; int flags; @@ -85,6 +86,15 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_ERROR); } + if (args_has(args, 'd')) { + delay = args_strtonum(args, 'd', 0, UINT_MAX, &cause); + if (cause != NULL) { + cmdq_error(item, "delay %s", cause); + free(cause); + return (CMD_RETURN_ERROR); + } + } + template = args_get(args, 'F'); if (args->argc != 0) template = args->argv[0]; @@ -117,7 +127,7 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'p')) cmdq_print(item, "%s", msg); else if (tc != NULL) - status_message_set(tc, 0, "%s", msg); + status_message_set(tc, delay, 0, "%s", msg); free(msg); format_free(ft); diff --git a/cmd-display-panes.c b/cmd-display-panes.c index a13a06ae..352b2e4d 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -55,11 +55,11 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx, struct session *s = c->session; struct options *oo = s->options; struct window *w = wp->window; - struct grid_cell gc; - u_int idx, px, py, i, j, xoff, yoff, sx, sy; + struct grid_cell fgc, bgc; + u_int pane, idx, px, py, i, j, xoff, yoff, sx, sy; int colour, active_colour; - char buf[16], *ptr; - size_t len; + char buf[16], lbuf[16], rbuf[16], *ptr; + size_t len, llen, rlen; if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx || @@ -109,29 +109,50 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx, px = sx / 2; py = sy / 2; - if (window_pane_index(wp, &idx) != 0) + if (window_pane_index(wp, &pane) != 0) fatalx("index not found"); - len = xsnprintf(buf, sizeof buf, "%u", idx); + len = xsnprintf(buf, sizeof buf, "%u", pane); if (sx < len) return; colour = options_get_number(oo, "display-panes-colour"); active_colour = options_get_number(oo, "display-panes-active-colour"); + memcpy(&fgc, &grid_default_cell, sizeof fgc); + memcpy(&bgc, &grid_default_cell, sizeof bgc); + if (w->active == wp) { + fgc.fg = active_colour; + bgc.bg = active_colour; + } else { + fgc.fg = colour; + bgc.bg = colour; + } + + rlen = xsnprintf(rbuf, sizeof rbuf, "%ux%u", wp->sx, wp->sy); + if (pane > 9 && pane < 35) + llen = xsnprintf(lbuf, sizeof lbuf, "%c", 'a' + (pane - 10)); + else + llen = 0; + if (sx < len * 6 || sy < 5) { - tty_cursor(tty, xoff + px - len / 2, yoff + py); - goto draw_text; + tty_attributes(tty, &fgc, &grid_default_cell, NULL); + if (sx >= len + llen + 1) { + len += llen + 1; + tty_cursor(tty, xoff + px - len / 2, yoff + py); + tty_putn(tty, buf, len, len); + tty_putn(tty, " ", 1, 1); + tty_putn(tty, lbuf, llen, llen); + } else { + tty_cursor(tty, xoff + px - len / 2, yoff + py); + tty_putn(tty, buf, len, len); + } + goto out; } px -= len * 3; py -= 2; - memcpy(&gc, &grid_default_cell, sizeof gc); - if (w->active == wp) - gc.bg = active_colour; - else - gc.bg = colour; - tty_attributes(tty, &gc, &grid_default_cell, NULL); + tty_attributes(tty, &bgc, &grid_default_cell, NULL); for (ptr = buf; *ptr != '\0'; ptr++) { if (*ptr < '0' || *ptr > '9') continue; @@ -147,20 +168,20 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx, px += 6; } - len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy); - if (sx < len || sy < 6) - return; - tty_cursor(tty, xoff + sx - len, yoff); - -draw_text: - memcpy(&gc, &grid_default_cell, sizeof gc); - if (w->active == wp) - gc.fg = active_colour; - else - gc.fg = colour; - tty_attributes(tty, &gc, &grid_default_cell, NULL); - tty_puts(tty, buf); + if (sy <= 6) + goto out; + tty_attributes(tty, &fgc, &grid_default_cell, NULL); + if (rlen != 0 && sx >= rlen) { + tty_cursor(tty, xoff + sx - rlen, yoff); + tty_putn(tty, rbuf, rlen, rlen); + } + if (llen != 0) { + tty_cursor(tty, xoff + sx / 2 + len * 3 - llen - 1, + yoff + py + 5); + tty_putn(tty, lbuf, llen, llen); + } +out: tty_cursor(tty, 0, 0); } @@ -197,11 +218,21 @@ cmd_display_panes_key(struct client *c, struct key_event *event) struct window *w = c->session->curw->window; struct window_pane *wp; enum cmd_parse_status status; - - if (event->key < '0' || event->key > '9') + u_int index; + key_code key; + + if (event->key >= '0' && event->key <= '9') + index = event->key - '0'; + else if ((event->key & KEYC_MASK_MODIFIERS) == 0) { + key = (event->key & KEYC_MASK_KEY); + if (key >= 'a' && key <= 'z') + index = 10 + (key - 'a'); + else + return (-1); + } else return (-1); - wp = window_pane_at_index(w, event->key - '0'); + wp = window_pane_at_index(w, index); if (wp == NULL) return (1); window_unzoom(w); diff --git a/cmd-list-keys.c b/cmd-list-keys.c index b3bdbd12..dd82e57e 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -114,7 +114,7 @@ cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args, note = xstrdup(bd->note); tmp = utf8_padcstr(key, keywidth + 1); if (args_has(args, '1') && tc != NULL) - status_message_set(tc, 1, "%s%s%s", prefix, tmp, note); + status_message_set(tc, -1, 1, "%s%s%s", prefix, tmp, note); else cmdq_print(item, "%s%s%s", prefix, tmp, note); free(tmp); diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c index 49e834d6..bca9a860 100644 --- a/cmd-load-buffer.c +++ b/cmd-load-buffer.c @@ -37,14 +37,15 @@ const struct cmd_entry cmd_load_buffer_entry = { .name = "load-buffer", .alias = "loadb", - .args = { "b:", 1, 1 }, - .usage = CMD_BUFFER_USAGE " path", + .args = { "b:t:w", 1, 1 }, + .usage = CMD_BUFFER_USAGE " " CMD_TARGET_CLIENT_USAGE " path", - .flags = CMD_AFTERHOOK, + .flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG|CMD_CLIENT_CANFAIL, .exec = cmd_load_buffer_exec }; struct cmd_load_buffer_data { + struct client *client; struct cmdq_item *item; char *name; }; @@ -54,6 +55,7 @@ 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 client *tc = cdata->client; struct cmdq_item *item = cdata->item; void *bdata = EVBUFFER_DATA(buffer); size_t bsize = EVBUFFER_LENGTH(buffer); @@ -72,7 +74,12 @@ cmd_load_buffer_done(__unused struct client *c, const char *path, int error, cmdq_error(item, "%s", cause); free(cause); free(copy); - } + } else if (tc != NULL && + tc->session != NULL && + (~tc->flags & CLIENT_DEAD)) + tty_set_selection(&tc->tty, copy, bsize); + if (tc != NULL) + server_client_unref(tc); } cmdq_continue(item); @@ -84,16 +91,19 @@ static enum cmd_retval cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = cmd_get_args(self); + struct client *tc = cmdq_get_target_client(item); struct cmd_load_buffer_data *cdata; const char *bufname = args_get(args, 'b'); char *path; - cdata = xmalloc(sizeof *cdata); + cdata = xcalloc(1, sizeof *cdata); cdata->item = item; if (bufname != NULL) cdata->name = xstrdup(bufname); - else - cdata->name = NULL; + if (args_has(args, 'w') && tc != NULL) { + cdata->client = tc; + cdata->client->references++; + } path = format_single_from_target(item, args->argv[0]); file_read(cmdq_get_client(item), path, cmd_load_buffer_done, cdata); diff --git a/cmd-queue.c b/cmd-queue.c index 693f7d90..36f1c9be 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -858,7 +858,7 @@ cmdq_error(struct cmdq_item *item, const char *fmt, ...) c->retval = 1; } else { *msg = toupper((u_char) *msg); - status_message_set(c, 1, "%s", msg); + status_message_set(c, -1, 1, "%s", msg); } free(msg); diff --git a/cmd-select-pane.c b/cmd-select-pane.c index b0c78d74..30529722 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -198,6 +198,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'T')) { title = format_single_from_target(item, args_get(args, 'T')); if (screen_set_title(&wp->base, title)) { + notify_pane("pane-title-changed", wp); server_redraw_window_borders(wp->window); server_status_window(wp->window); } diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c index 0f3fffce..94d8cd52 100644 --- a/cmd-set-buffer.c +++ b/cmd-set-buffer.c @@ -33,10 +33,11 @@ const struct cmd_entry cmd_set_buffer_entry = { .name = "set-buffer", .alias = "setb", - .args = { "ab:n:", 0, 1 }, - .usage = "[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data", + .args = { "ab:t:n:w", 0, 1 }, + .usage = "[-aw] " CMD_BUFFER_USAGE " [-n new-buffer-name] " + CMD_TARGET_CLIENT_USAGE " data", - .flags = CMD_AFTERHOOK, + .flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG|CMD_CLIENT_CANFAIL, .exec = cmd_set_buffer_exec }; @@ -55,6 +56,7 @@ static enum cmd_retval cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = cmd_get_args(self); + struct client *tc = cmdq_get_target_client(item); struct paste_buffer *pb; char *bufdata, *cause; const char *bufname, *olddata; @@ -118,6 +120,8 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item) free(cause); return (CMD_RETURN_ERROR); } + if (args_has(args, 'w') && tc != NULL) + tty_set_selection(&tc->tty, bufdata, bufsize); return (CMD_RETURN_NORMAL); } diff --git a/cmd-set-environment.c b/cmd-set-environment.c index 3c43b635..f142df53 100644 --- a/cmd-set-environment.c +++ b/cmd-set-environment.c @@ -34,8 +34,8 @@ const struct cmd_entry cmd_set_environment_entry = { .name = "set-environment", .alias = "setenv", - .args = { "hgrt:u", 1, 2 }, - .usage = "[-hgru] " CMD_TARGET_SESSION_USAGE " name [value]", + .args = { "Fhgrt:u", 1, 2 }, + .usage = "[-Fhgru] " CMD_TARGET_SESSION_USAGE " name [value]", .target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL }, @@ -50,6 +50,8 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item) struct cmd_find_state *target = cmdq_get_target(item); struct environ *env; const char *name, *value, *tflag; + char *expand = NULL; + enum cmd_retval retval = CMD_RETURN_NORMAL; name = args->argv[0]; if (*name == '\0') { @@ -63,6 +65,8 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item) if (args->argc < 2) value = NULL; + else if (args_has(args, 'F')) + value = expand = format_single_from_target(item, args->argv[1]); else value = args->argv[1]; @@ -75,7 +79,8 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "no such session: %s", tflag); else cmdq_error(item, "no current session"); - return (CMD_RETURN_ERROR); + retval = CMD_RETURN_ERROR; + goto out; } env = target->s->environ; } @@ -83,25 +88,31 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'u')) { if (value != NULL) { cmdq_error(item, "can't specify a value with -u"); - return (CMD_RETURN_ERROR); + retval = CMD_RETURN_ERROR; + goto out; } environ_unset(env, name); } else if (args_has(args, 'r')) { if (value != NULL) { cmdq_error(item, "can't specify a value with -r"); - return (CMD_RETURN_ERROR); + retval = CMD_RETURN_ERROR; + goto out; } environ_clear(env, name); } else { if (value == NULL) { cmdq_error(item, "no value specified"); - return (CMD_RETURN_ERROR); + retval = CMD_RETURN_ERROR; + goto out; } + if (args_has(args, 'h')) environ_set(env, name, ENVIRON_HIDDEN, "%s", value); else environ_set(env, name, 0, "%s", value); } - return (CMD_RETURN_NORMAL); +out: + free(expand); + return (retval); } diff --git a/cmd-source-file.c b/cmd-source-file.c index f5a0ca4b..1da59193 100644 --- a/cmd-source-file.c +++ b/cmd-source-file.c @@ -35,8 +35,8 @@ const struct cmd_entry cmd_source_file_entry = { .name = "source-file", .alias = "source", - .args = { "nqv", 1, -1 }, - .usage = "[-nqv] path ...", + .args = { "Fnqv", 1, -1 }, + .usage = "[-Fnqv] path ...", .flags = 0, .exec = cmd_source_file_exec @@ -126,7 +126,7 @@ cmd_source_file_exec(struct cmd *self, struct cmdq_item *item) struct cmd_source_file_data *cdata; struct client *c = cmdq_get_client(item); enum cmd_retval retval = CMD_RETURN_NORMAL; - char *pattern, *cwd; + char *pattern, *cwd, *expand = NULL; const char *path, *error; glob_t g; int i, result; @@ -145,7 +145,12 @@ cmd_source_file_exec(struct cmd *self, struct cmdq_item *item) utf8_stravis(&cwd, server_client_get_cwd(c, NULL), VIS_GLOB); for (i = 0; i < args->argc; i++) { - path = args->argv[i]; + if (args_has(args, 'F')) { + free(expand); + expand = format_single_from_target(item, args->argv[i]); + path = expand; + } else + path = args->argv[i]; if (strcmp(path, "-") == 0) { cmd_source_file_add(cdata, "-"); continue; @@ -172,6 +177,7 @@ cmd_source_file_exec(struct cmd *self, struct cmdq_item *item) free(pattern); continue; } + free(expand); free(pattern); for (j = 0; j < g.gl_pathc; j++) diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c index 4b9f39a6..a29831af 100644 --- a/cmd-unbind-key.c +++ b/cmd-unbind-key.c @@ -32,8 +32,8 @@ const struct cmd_entry cmd_unbind_key_entry = { .name = "unbind-key", .alias = "unbind", - .args = { "anT:", 0, 1 }, - .usage = "[-an] [-T key-table] key", + .args = { "anqT:", 0, 1 }, + .usage = "[-anq] [-T key-table] key", .flags = CMD_AFTERHOOK, .exec = cmd_unbind_key_exec @@ -45,44 +45,54 @@ cmd_unbind_key_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); key_code key; const char *tablename; + int quiet = args_has(args, 'q'); - if (!args_has(args, 'a')) { - if (args->argc != 1) { - cmdq_error(item, "missing key"); - return (CMD_RETURN_ERROR); - } - key = key_string_lookup_string(args->argv[0]); - if (key == KEYC_NONE || key == KEYC_UNKNOWN) { - cmdq_error(item, "unknown key: %s", args->argv[0]); - return (CMD_RETURN_ERROR); - } - } else { + if (args_has(args, 'a')) { if (args->argc != 0) { - cmdq_error(item, "key given with -a"); + if (!quiet) + cmdq_error(item, "key given with -a"); return (CMD_RETURN_ERROR); } - key = KEYC_UNKNOWN; - } - if (key == KEYC_UNKNOWN) { tablename = args_get(args, 'T'); if (tablename == NULL) { - key_bindings_remove_table("root"); - key_bindings_remove_table("prefix"); - return (CMD_RETURN_NORMAL); + if (args_has(args, 'n')) + tablename = "root"; + else + tablename = "prefix"; } if (key_bindings_get_table(tablename, 0) == NULL) { - cmdq_error(item, "table %s doesn't exist", tablename); + if (!quiet) { + cmdq_error(item, "table %s doesn't exist" , + tablename); + } return (CMD_RETURN_ERROR); } + key_bindings_remove_table(tablename); return (CMD_RETURN_NORMAL); } + if (args->argc != 1) { + if (!quiet) + cmdq_error(item, "missing key"); + return (CMD_RETURN_ERROR); + } + + key = key_string_lookup_string(args->argv[0]); + if (key == KEYC_NONE || key == KEYC_UNKNOWN) { + if (!quiet) + cmdq_error(item, "unknown key: %s", args->argv[0]); + return (CMD_RETURN_ERROR); + } + if (args_has(args, 'T')) { tablename = args_get(args, 'T'); if (key_bindings_get_table(tablename, 0) == NULL) { - cmdq_error(item, "table %s doesn't exist", tablename); + if (!quiet) { + cmdq_error(item, "table %s doesn't exist" , + tablename); + } return (CMD_RETURN_ERROR); } } else if (args_has(args, 'n')) @@ -189,6 +189,12 @@ colour_fromstring(const char *s) return (-1); return (n | COLOUR_FLAG_256); } + if (strncasecmp(s, "color", (sizeof "color") - 1) == 0) { + n = strtonum(s + (sizeof "color") - 1, 0, 255, &errstr); + if (errstr != NULL) + return (-1); + return (n | COLOUR_FLAG_256); + } if (strcasecmp(s, "default") == 0) return (8); @@ -35,6 +35,10 @@ #define __attribute__(a) #endif +#ifdef BROKEN___DEAD +#undef __dead +#endif + #ifndef __unused #define __unused __attribute__ ((__unused__)) #endif diff --git a/configure.ac b/configure.ac index 22a48c8d..eb1a9594 100644 --- a/configure.ac +++ b/configure.ac @@ -570,6 +570,12 @@ case "$host_os" in AC_MSG_RESULT(darwin) PLATFORM=darwin # + # OS X uses __dead2 instead of __dead, like FreeBSD. But it + # defines __dead away so it needs to be removed before we can + # replace it. + # + AC_DEFINE(BROKEN___DEAD) + # # OS X CMSG_FIRSTHDR is broken, so redefine it with a working # one. daemon works but has some stupid side effects, so use # our internal version which has a workaround. @@ -688,8 +688,8 @@ control_write_pending(struct client *c, struct control_pane *cp, size_t limit) else age = 0; log_debug("%s: %s: output block %zu (age %llu) for %%%u " - "(used %zu/%zu)", __func__, c->name, cb->size, age, - cp->pane, used, limit); + "(used %zu/%zu)", __func__, c->name, cb->size, + (unsigned long long)age, cp->pane, used, limit); size = cb->size; if (size > limit - used) @@ -94,6 +94,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) #define FORMAT_WINDOWS 0x100 #define FORMAT_PANES 0x200 #define FORMAT_PRETTY 0x400 +#define FORMAT_LENGTH 0x800 /* Limit on recursion. */ #define FORMAT_LOOP_LIMIT 10 @@ -1642,7 +1643,7 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count) /* * Modifiers are a ; separated list of the forms: - * l,m,C,b,d,t,q,E,T,S,W,P,<,> + * l,m,C,b,d,n,t,q,E,T,S,W,P,<,> * =a * =/a * =/a/ @@ -1659,7 +1660,7 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count) cp++; /* Check single character modifiers with no arguments. */ - if (strchr("lbdqETSWP<>", cp[0]) != NULL && + if (strchr("lbdnqETSWP<>", cp[0]) != NULL && format_is_end(cp[1])) { format_add_modifier(&list, count, cp, 1, NULL, 0); cp++; @@ -2117,6 +2118,9 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, case 'd': modifiers |= FORMAT_DIRNAME; break; + case 'n': + modifiers |= FORMAT_LENGTH; + break; case 't': modifiers |= FORMAT_TIMESTRING; if (fm->argc < 1) @@ -2296,13 +2300,17 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, if (value == NULL) value = xstrdup(""); } else { - /* Neither: look up directly. */ - value = format_find(ft, copy, modifiers, time_format); - if (value == NULL) { - format_log(ft, "format '%s' not found", copy); - value = xstrdup(""); - } else - format_log(ft, "format '%s' found: %s", copy, value); + if (strstr(copy, "#{") != 0) { + format_log(ft, "expanding inner format '%s'", copy); + value = format_expand(ft, copy); + } else { + value = format_find(ft, copy, modifiers, time_format); + if (value == NULL) { + format_log(ft, "format '%s' not found", copy); + value = xstrdup(""); + } else + format_log(ft, "format '%s' found: %s", copy, value); + } } done: @@ -2311,8 +2319,7 @@ done: new = format_expand(ft, value); free(value); value = new; - } - else if (modifiers & FORMAT_EXPANDTIME) { + } else if (modifiers & FORMAT_EXPANDTIME) { new = format_expand_time(ft, value); free(value); value = new; @@ -2366,6 +2373,14 @@ done: format_log(ft, "applied padding width %d: %s", width, value); } + /* Replace with the length if needed. */ + if (modifiers & FORMAT_LENGTH) { + xasprintf(&new, "%zu", strlen(value)); + free(value); + value = new; + format_log(ft, "replacing with length: %s", new); + } + /* Expand the buffer and copy in the value. */ valuelen = strlen(value); while (*len - *off < valuelen + 1) { @@ -2889,6 +2904,7 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_dead", "%d", wp->fd == -1); else format_add(ft, "pane_dead", "0"); + format_add(ft, "pane_last", "%d", wp == w->last); if (server_check_marked() && marked_pane.wp == wp) format_add(ft, "pane_marked", "1"); @@ -463,7 +463,7 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx, u_int bg) sx = gd->sx / 4; else if (sx < gd->sx / 2) sx = gd->sx / 2; - else + else if (gd->sx > sx) sx = gd->sx; gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata); @@ -1277,7 +1277,7 @@ grid_reflow(struct grid *gd, u_int sx) struct grid *target; struct grid_line *gl; struct grid_cell gc; - u_int yy, width, i, at, first; + u_int yy, width, i, at; /* * Create a destination grid. This is just used as a container for the @@ -1294,13 +1294,12 @@ grid_reflow(struct grid *gd, u_int sx) continue; /* - * Work out the width of this line. first is the width of the - * first character, at is the point at which the available - * width is hit, and width is the full line width. + * Work out the width of this line. at is the point at which + * the available width is hit, and width is the full line + * width. */ - first = at = width = 0; + at = width = 0; if (~gl->flags & GRID_LINE_EXTENDED) { - first = 1; width = gl->cellused; if (width > sx) at = sx; @@ -1309,8 +1308,6 @@ grid_reflow(struct grid *gd, u_int sx) } else { for (i = 0; i < gl->cellused; i++) { grid_get_cell1(gl, i, &gc); - if (i == 0) - first = gc.data.width; if (at == 0 && width + gc.data.width > sx) at = i; width += gc.data.width; @@ -1318,10 +1315,10 @@ grid_reflow(struct grid *gd, u_int sx) } /* - * If the line is exactly right or the first character is wider - * than the target width, just move it across unchanged. + * If the line is exactly right, just move it across + * unchanged. */ - if (width == sx || first > sx) { + if (width == sx) { grid_reflow_move(target, gl); continue; } diff --git a/input-keys.c b/input-keys.c index ff402503..32ca4b97 100644 --- a/input-keys.c +++ b/input-keys.c @@ -555,6 +555,8 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key) case KEYC_SHIFT|KEYC_META|KEYC_CTRL: modifier = '8'; break; + default: + fatalx("invalid key modifiers: %llx", key); } xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", outkey, modifier); bufferevent_write(bev, tmp, strlen(tmp)); @@ -65,7 +65,7 @@ struct input_param { INPUT_MISSING, INPUT_NUMBER, INPUT_STRING - } type; + } type; union { int num; char *str; @@ -81,7 +81,7 @@ struct input_ctx { struct input_cell cell; struct input_cell old_cell; - u_int old_cx; + u_int old_cx; u_int old_cy; int old_mode; @@ -121,7 +121,7 @@ struct input_ctx { * All input received since we were last in the ground state. Sent to * control clients on connection. */ - struct evbuffer *since_ground; + struct evbuffer *since_ground; }; /* Helper functions. */ @@ -1867,6 +1867,7 @@ input_csi_dispatch_winops(struct input_ctx *ictx) case 2: screen_pop_title(sctx->s); if (wp != NULL) { + notify_pane("pane-title-changed", wp); server_redraw_window_borders(wp->window); server_status_window(wp->window); } @@ -2261,6 +2262,7 @@ input_exit_osc(struct input_ctx *ictx) case 0: case 2: if (screen_set_title(sctx->s, p) && wp != NULL) { + notify_pane("pane-title-changed", wp); server_redraw_window_borders(wp->window); server_status_window(wp->window); } @@ -2326,6 +2328,7 @@ input_exit_apc(struct input_ctx *ictx) log_debug("%s: \"%s\"", __func__, ictx->input_buf); if (screen_set_title(sctx->s, ictx->input_buf) && wp != NULL) { + notify_pane("pane-title-changed", wp); server_redraw_window_borders(wp->window); server_status_window(wp->window); } @@ -2456,13 +2459,31 @@ input_osc_parse_colour(const char *p, u_int *r, u_int *g, u_int *b) return (1); } +/* Reply to a colour request. */ +static void +input_osc_colour_reply(struct input_ctx *ictx, u_int n, int c) +{ + u_char r, g, b; + const char *end; + + if (c == 8 || (~c & COLOUR_FLAG_RGB)) + return; + colour_split_rgb(c, &r, &g, &b); + + if (ictx->input_end == INPUT_END_BEL) + end = "\007"; + else + end = "\033\\"; + input_reply(ictx, "\033]%u;rgb:%02hhx/%02hhx/%02hhx%s", n, r, g, b, end); +} + /* Handle the OSC 4 sequence for setting (multiple) palette entries. */ static void input_osc_4(struct input_ctx *ictx, const char *p) { struct window_pane *wp = ictx->wp; char *copy, *s, *next = NULL; - long idx; + long idx; u_int r, g, b; if (wp == NULL) @@ -2494,17 +2515,22 @@ bad: free(copy); } -/* Handle the OSC 10 sequence for setting foreground colour. */ +/* Handle the OSC 10 sequence for setting and querying foreground colour. */ static void input_osc_10(struct input_ctx *ictx, const char *p) { struct window_pane *wp = ictx->wp; + struct grid_cell defaults; u_int r, g, b; if (wp == NULL) return; - if (strcmp(p, "?") == 0) + + if (strcmp(p, "?") == 0) { + tty_default_colours(&defaults, wp); + input_osc_colour_reply(ictx, 10, defaults.fg); return; + } if (!input_osc_parse_colour(p, &r, &g, &b)) goto bad; @@ -2517,17 +2543,22 @@ bad: log_debug("bad OSC 10: %s", p); } -/* Handle the OSC 11 sequence for setting background colour. */ +/* Handle the OSC 11 sequence for setting and querying background colour. */ static void input_osc_11(struct input_ctx *ictx, const char *p) { struct window_pane *wp = ictx->wp; + struct grid_cell defaults; u_int r, g, b; if (wp == NULL) return; - if (strcmp(p, "?") == 0) + + if (strcmp(p, "?") == 0) { + tty_default_colours(&defaults, wp); + input_osc_colour_reply(ictx, 11, defaults.bg); return; + } if (!input_osc_parse_colour(p, &r, &g, &b)) goto bad; diff --git a/key-bindings.c b/key-bindings.c index f11bb430..63d4bb26 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -191,6 +191,16 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat, table = key_bindings_get_table(name, 1); bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS); + if (cmdlist == NULL) { + if (bd != NULL) { + free((void *)bd->note); + if (note != NULL) + bd->note = xstrdup(note); + else + bd->note = NULL; + } + return; + } if (bd != NULL) { RB_REMOVE(key_bindings, &table->key_bindings, bd); key_bindings_free(bd); diff --git a/mode-tree.c b/mode-tree.c index c4b776f9..a47c0c06 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -1176,7 +1176,7 @@ mode_tree_run_command(struct client *c, struct cmd_find_state *fs, if (status == CMD_PARSE_ERROR) { if (c != NULL) { *error = toupper((u_char)*error); - status_message_set(c, 1, "%s", error); + status_message_set(c, -1, 1, "%s", error); } free(error); } diff --git a/options-table.c b/options-table.c index 0555d43e..873f8d67 100644 --- a/options-table.c +++ b/options-table.c @@ -170,6 +170,14 @@ static const char *options_table_status_format_default[] = { .separator = "" \ } +/* Map of name conversions. */ +const struct options_name_map options_other_names[] = { + { "display-panes-color", "display-panes-colour" }, + { "display-panes-active-color", "display-panes-active-colour" }, + { "clock-mode-color", "clock-mode-colour" }, + { NULL, NULL } +}; + /* Top-level options. */ const struct options_table_entry options_table[] = { /* Server options. */ @@ -1120,6 +1128,7 @@ const struct options_table_entry options_table[] = { OPTIONS_TABLE_PANE_HOOK("pane-focus-out", ""), OPTIONS_TABLE_PANE_HOOK("pane-mode-changed", ""), OPTIONS_TABLE_PANE_HOOK("pane-set-clipboard", ""), + OPTIONS_TABLE_PANE_HOOK("pane-title-changed", ""), OPTIONS_TABLE_HOOK("session-closed", ""), OPTIONS_TABLE_HOOK("session-created", ""), OPTIONS_TABLE_HOOK("session-renamed", ""), @@ -95,6 +95,18 @@ options_cmp(struct options_entry *lhs, struct options_entry *rhs) return (strcmp(lhs->name, rhs->name)); } +static const char * +options_map_name(const char *name) +{ + const struct options_name_map *map; + + for (map = options_other_names; map->from != NULL; map++) { + if (strcmp(map->from, name) == 0) + return (map->to); + } + return (name); +} + static const struct options_table_entry * options_parent_table_entry(struct options *oo, const char *s) { @@ -204,10 +216,14 @@ options_next(struct options_entry *o) struct options_entry * options_get_only(struct options *oo, const char *name) { - struct options_entry o; + struct options_entry o = { .name = name }, *found; - o.name = name; - return (RB_FIND(options_tree, &oo->tree, &o)); + found = RB_FIND(options_tree, &oo->tree, &o); + if (found == NULL) { + o.name = options_map_name(name); + return (RB_FIND(options_tree, &oo->tree, &o)); + } + return (found); } struct options_entry * @@ -608,19 +624,21 @@ char * options_match(const char *s, int *idx, int *ambiguous) { const struct options_table_entry *oe, *found; - char *name; + char *parsed; + const char *name; size_t namelen; - name = options_parse(s, idx); - if (name == NULL) + parsed = options_parse(s, idx); + if (parsed == NULL) return (NULL); - namelen = strlen(name); - - if (*name == '@') { + if (*parsed == '@') { *ambiguous = 0; - return (name); + return (parsed); } + name = options_map_name(parsed); + namelen = strlen(name); + found = NULL; for (oe = options_table; oe->name != NULL; oe++) { if (strcmp(oe->name, name) == 0) { @@ -630,13 +648,13 @@ options_match(const char *s, int *idx, int *ambiguous) if (strncmp(oe->name, name, namelen) == 0) { if (found != NULL) { *ambiguous = 1; - free(name); + free(parsed); return (NULL); } found = oe; } } - free(name); + free(parsed); if (found == NULL) { *ambiguous = 0; return (NULL); @@ -261,7 +261,7 @@ popup_handle_drag(struct client *c, struct popup_data *pd, pd->sx = m->x - pd->px; pd->sy = m->y - pd->py; - screen_resize(&pd->s, pd->sx, pd->sy, 0); + screen_resize(&pd->s, pd->sx - 2, pd->sy - 2, 0); if (pd->ictx == NULL) popup_write_screen(c, pd); else if (pd->job != NULL) @@ -239,6 +239,7 @@ proc_set_signals(struct tmuxproc *tp, void (*signalcb)(int)) sigaction(SIGTSTP, &sa, NULL); sigaction(SIGTTIN, &sa, NULL); sigaction(SIGTTOU, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); signal_set(&tp->ev_sigint, SIGINT, proc_signal_cb, tp); signal_add(&tp->ev_sigint, NULL); diff --git a/server-client.c b/server-client.c index 5749ba94..62281c83 100644 --- a/server-client.c +++ b/server-client.c @@ -1660,8 +1660,6 @@ server_client_reset_state(struct client *c) s = wp->screen; if (s != NULL) mode = s->mode; - if (c->prompt_string != NULL || c->message_string != NULL) - mode &= ~MODE_CURSOR; log_debug("%s: client %s mode %x", __func__, c->name, mode); /* Reset region and margin. */ @@ -1985,6 +1983,7 @@ server_client_dispatch(struct imsg *imsg, void *arg) switch (imsg->hdr.type) { case MSG_IDENTIFY_FEATURES: case MSG_IDENTIFY_FLAGS: + case MSG_IDENTIFY_LONGFLAGS: case MSG_IDENTIFY_TERM: case MSG_IDENTIFY_TTYNAME: case MSG_IDENTIFY_CWD: @@ -2143,6 +2142,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) const char *data, *home; size_t datalen; int flags, feat; + uint64_t longflags; char *name; if (c->flags & CLIENT_IDENTIFIED) @@ -2167,6 +2167,14 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) c->flags |= flags; log_debug("client %p IDENTIFY_FLAGS %#x", c, flags); break; + case MSG_IDENTIFY_LONGFLAGS: + if (datalen != sizeof longflags) + fatalx("bad MSG_IDENTIFY_LONGFLAGS size"); + memcpy(&longflags, data, sizeof longflags); + c->flags |= longflags; + log_debug("client %p IDENTIFY_LONGFLAGS %#llx", c, + (unsigned long long)longflags); + break; case MSG_IDENTIFY_TERM: if (datalen == 0 || data[datalen - 1] != '\0') fatalx("bad MSG_IDENTIFY_TERM string"); diff --git a/server-fn.c b/server-fn.c index d5e7cbd7..e3cc181f 100644 --- a/server-fn.c +++ b/server-fn.c @@ -342,6 +342,7 @@ server_destroy_pane(struct window_pane *wp, int notify) time(&t); ctime_r(&t, tim); + tim[strcspn(tim, "\n")] = '\0'; if (WIFEXITED(wp->status)) { screen_write_nputs(&ctx, -1, &gc, @@ -157,7 +157,7 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base, { int pair[2]; sigset_t set, oldset; - struct client *c; + struct client *c = NULL; char *cause = NULL; sigfillset(&set); @@ -223,9 +223,11 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base, } if (cause != NULL) { - cmdq_append(c, cmdq_get_error(cause)); + if (c != NULL) { + cmdq_append(c, cmdq_get_error(cause)); + c->flags |= CLIENT_EXIT; + } free(cause); - c->flags |= CLIENT_EXIT; } server_add_accept(0); @@ -423,11 +423,11 @@ status_redraw(struct client *c) /* Set a status line message. */ void -status_message_set(struct client *c, int ignore_styles, const char *fmt, ...) +status_message_set(struct client *c, int delay, int ignore_styles, + const char *fmt, ...) { struct timeval tv; va_list ap; - int delay; status_message_clear(c); status_push_screen(c); @@ -439,7 +439,12 @@ status_message_set(struct client *c, int ignore_styles, const char *fmt, ...) server_add_message("%s message: %s", c->name, c->message_string); - delay = options_get_number(c->session->options, "display-time"); + /* + * With delay -1, the display-time option is used; zero means wait for + * key press; more than zero is the actual delay time in milliseconds. + */ + if (delay == -1) + delay = options_get_number(c->session->options, "display-time"); if (delay > 0) { tv.tv_sec = delay / 1000; tv.tv_usec = (delay % 1000) * 1000L; @@ -447,6 +452,7 @@ status_message_set(struct client *c, int ignore_styles, const char *fmt, ...) if (event_initialized(&c->message_timer)) evtimer_del(&c->message_timer); evtimer_set(&c->message_timer, status_message_callback, c); + evtimer_add(&c->message_timer, &tv); } @@ -1407,7 +1407,7 @@ and .Fl T show debugging information about jobs and terminals. .It Xo Ic source-file -.Op Fl nqv +.Op Fl Fnqv .Ar path .Ar ... .Xc @@ -1418,6 +1418,11 @@ Execute commands from one or more files specified by .Xr glob 7 patterns). If +.Fl F +is present, then +.Ar path +is expanded as a format. +If .Fl q is given, no error will be returned if .Ar path @@ -3034,7 +3039,7 @@ Send the prefix key, or with .Fl 2 the secondary prefix key, to a window as if it was pressed. .It Xo Ic unbind-key -.Op Fl an +.Op Fl anq .Op Fl T Ar key-table .Ar key .Xc @@ -3049,6 +3054,9 @@ are the same as for If .Fl a is present, all key bindings are removed. +The +.Fl q +option prevents errors being returned. .El .Sh OPTIONS The appearance and behaviour of @@ -3159,6 +3167,9 @@ flag unsets an option, so a session inherits the option from the global options (or with .Fl g , restores a global option to the default). +.Ar value +depends on the option and may be a number, a string, or a flag (on, off, or +omitted to toggle). .Pp The .Fl o @@ -3230,9 +3241,6 @@ includes hooks (omitted by default). .Fl A includes options inherited from a parent set of options, such options are marked with an asterisk. -.Ar value -depends on the option and may be a number, a string, or a flag (on, off, or -omitted to toggle). .El .Pp Available server options are: @@ -4574,6 +4582,9 @@ 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. +.Ql n +expands to the length of the variable, for example +.Ql #{n:window_name} . .Pp Prefixing a time variable with .Ql t:\& @@ -4770,6 +4781,7 @@ The following variables are available, where appropriate: .It Li "pane_in_mode" Ta "" Ta "1 if pane is in a mode" .It Li "pane_index" Ta "#P" Ta "Index of pane" .It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled" +.It Li "pane_last" Ta "" Ta "1 if last pane" .It Li "pane_left" Ta "" Ta "Left of pane" .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" @@ -5098,7 +5110,7 @@ section). Commands to alter and view the environment are: .Bl -tag -width Ds .It Xo Ic set-environment -.Op Fl hgru +.Op Fl Fhgru .Op Fl t Ar target-session .Ar name Op Ar value .Xc @@ -5109,6 +5121,11 @@ If is used, the change is made in the global environment; otherwise, it is applied to the session environment for .Ar target-session . +If +.Fl F +is present, then +.Ar value +is expanded as a format. The .Fl u flag unsets a variable. @@ -5378,6 +5395,7 @@ The following keys are also available: .It Xo Ic display-message .Op Fl aIpv .Op Fl c Ar target-client +.Op Fl d Ar delay .Op Fl t Ar target-pane .Op Ar message .Xc @@ -5387,7 +5405,14 @@ If .Fl p is given, the output is printed to stdout, otherwise it is displayed in the .Ar target-client -status line. +status line for up to +.Ar delay +milliseconds. +If +.Ar delay +is not given, the +.Ic message-time +option is used; a delay of zero waits for a key press. The format of .Ar message is described in the @@ -5629,12 +5654,21 @@ See the .Sx FORMATS section. .It Xo Ic load-buffer +.Op Fl w .Op Fl b Ar buffer-name +.Op Fl t Ar target-client .Ar path .Xc .D1 (alias: Ic loadb ) Load the contents of the specified paste buffer from .Ar path . +If +.Fl w +is given, the buffer is also sent to the clipboard for +.Ar target-client +using the +.Xr xterm 1 +escape sequence, if possible. .It Xo Ic paste-buffer .Op Fl dpr .Op Fl b Ar buffer-name @@ -5671,14 +5705,22 @@ The .Fl a option appends to rather than overwriting the file. .It Xo Ic set-buffer -.Op Fl a +.Op Fl aw .Op Fl b Ar buffer-name +.Op Fl t Ar target-client .Op Fl n Ar new-buffer-name .Ar data .Xc .D1 (alias: Ic setb ) Set the contents of the specified buffer to .Ar data . +If +.Fl w +is given, the buffer is also sent to the clipboard for +.Ar target-client +using the +.Xr xterm 1 +escape sequence, if possible. The .Fl a option appends to rather than overwriting the buffer. @@ -322,8 +322,8 @@ main(int argc, char **argv) char *path = NULL, *label = NULL; char *cause, **var; const char *s, *shell, *cwd; - int opt, flags = 0, keys; - int feat = 0; + int opt, keys, feat = 0; + uint64_t flags = 0; const struct options_table_entry *oe; if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL && @@ -498,6 +498,7 @@ enum msgtype { MSG_IDENTIFY_CWD, MSG_IDENTIFY_FEATURES, MSG_IDENTIFY_STDOUT, + MSG_IDENTIFY_LONGFLAGS, MSG_COMMAND = 200, MSG_DETACH, @@ -1790,6 +1791,7 @@ enum options_table_type { struct options_table_entry { const char *name; + const char *alternative_name; enum options_table_type type; int scope; int flags; @@ -1809,6 +1811,11 @@ struct options_table_entry { const char *unit; }; +struct options_name_map { + const char *from; + const char *to; +}; + /* Common command usages. */ #define CMD_TARGET_PANE_USAGE "[-t target-pane]" #define CMD_TARGET_WINDOW_USAGE "[-t target-window]" @@ -2041,7 +2048,8 @@ int options_remove_or_default(struct options_entry *, int, char **); /* options-table.c */ -extern const struct options_table_entry options_table[]; +extern const struct options_table_entry options_table[]; +extern const struct options_name_map options_other_names[]; /* job.c */ typedef void (*job_update_cb) (struct job *); @@ -2121,6 +2129,7 @@ int tty_open(struct tty *, char **); void tty_close(struct tty *); void tty_free(struct tty *); void tty_update_features(struct tty *); +void tty_set_selection(struct tty *, const char *, size_t); void tty_write(void (*)(struct tty *, const struct tty_ctx *), struct tty_ctx *); void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *); @@ -2325,7 +2334,7 @@ void printflike(2, 3) cmdq_error(struct cmdq_item *, const char *, ...); void cmd_wait_for_flush(void); /* client.c */ -int client_main(struct event_base *, int, char **, int, int); +int client_main(struct event_base *, int, char **, uint64_t, int); /* key-bindings.c */ struct key_table *key_bindings_get_table(const char *, int); @@ -2452,8 +2461,7 @@ struct style_range *status_get_range(struct client *, u_int, u_int); void status_init(struct client *); void status_free(struct client *); int status_redraw(struct client *); -void printflike(3, 4) status_message_set(struct client *, int, const char *, - ...); +void status_message_set(struct client *, int, int, const char *, ...); void status_message_clear(struct client *); int status_message_redraw(struct client *); void status_prompt_set(struct client *, struct cmd_find_state *, @@ -305,6 +305,8 @@ tty_term_strip(const char *s) ptr++; if (*ptr == '>') ptr++; + if (*ptr == '\0') + break; } buf[len++] = *ptr; @@ -1896,19 +1896,27 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx) { - char *buf; - size_t off; + tty_set_selection(tty, ctx->ptr, ctx->num); +} + +void +tty_set_selection(struct tty *tty, const char *buf, size_t len) +{ + char *encoded; + size_t size; + if (~tty->flags & TTY_STARTED) + return; if (!tty_term_has(tty->term, TTYC_MS)) return; - off = 4 * ((ctx->num + 2) / 3) + 1; /* storage for base64 */ - buf = xmalloc(off); + size = 4 * ((len + 2) / 3) + 1; /* storage for base64 */ + encoded = xmalloc(size); - b64_ntop(ctx->ptr, ctx->num, buf, off); - tty_putcode_ptr2(tty, TTYC_MS, "", buf); + b64_ntop(buf, len, encoded, size); + tty_putcode_ptr2(tty, TTYC_MS, "", encoded); - free(buf); + free(encoded); } void diff --git a/window-copy.c b/window-copy.c index 7103131d..1dc0c293 100644 --- a/window-copy.c +++ b/window-copy.c @@ -72,14 +72,13 @@ static int window_copy_search_marks(struct window_mode_entry *, struct screen *, int, int); static void window_copy_clear_marks(struct window_mode_entry *); static void window_copy_move_left(struct screen *, u_int *, u_int *, int); -static void window_copy_move_right(struct screen *, u_int *, u_int *, int); static int window_copy_is_lowercase(const char *); static int window_copy_search_jump(struct window_mode_entry *, struct grid *, struct grid *, u_int, u_int, u_int, int, int, - int, int); -static int window_copy_search(struct window_mode_entry *, int, int); -static int window_copy_search_up(struct window_mode_entry *, int); -static int window_copy_search_down(struct window_mode_entry *, int); + int, int, u_int *); +static int window_copy_search(struct window_mode_entry *, int, int, int); +static int window_copy_search_up(struct window_mode_entry *, int, int); +static int window_copy_search_down(struct window_mode_entry *, int, int); static void window_copy_goto_line(struct window_mode_entry *, const char *); static void window_copy_update_cursor(struct window_mode_entry *, u_int, u_int); @@ -110,7 +109,7 @@ static void window_copy_cursor_back_to_indentation( static void window_copy_cursor_end_of_line(struct window_mode_entry *); static void window_copy_other_end(struct window_mode_entry *); static void window_copy_cursor_left(struct window_mode_entry *); -static void window_copy_cursor_right(struct window_mode_entry *); +static void window_copy_cursor_right(struct window_mode_entry *, int); static void window_copy_cursor_up(struct window_mode_entry *, int); static void window_copy_cursor_down(struct window_mode_entry *, int); static void window_copy_cursor_jump(struct window_mode_entry *); @@ -1094,7 +1093,7 @@ window_copy_cmd_cursor_right(struct window_copy_cmd_state *cs) u_int np = wme->prefix; for (; np != 0; np--) - window_copy_cursor_right(wme); + window_copy_cursor_right(wme, 0); return (WINDOW_COPY_CMD_NOTHING); } @@ -1685,10 +1684,10 @@ window_copy_cmd_search_again(struct window_copy_cmd_state *cs) if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) - window_copy_search_up(wme, data->searchregex); + window_copy_search_up(wme, data->searchregex, 1); } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) - window_copy_search_down(wme, data->searchregex); + window_copy_search_down(wme, data->searchregex, 1); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1702,10 +1701,10 @@ window_copy_cmd_search_reverse(struct window_copy_cmd_state *cs) if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) - window_copy_search_down(wme, data->searchregex); + window_copy_search_down(wme, data->searchregex, 1); } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) - window_copy_search_up(wme, data->searchregex); + window_copy_search_up(wme, data->searchregex, 1); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1953,7 +1952,7 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs) data->searchregex = 1; data->timeout = 0; for (; np != 0; np--) - window_copy_search_up(wme, 1); + window_copy_search_up(wme, 1, 0); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1973,7 +1972,7 @@ window_copy_cmd_search_backward_text(struct window_copy_cmd_state *cs) data->searchregex = 0; data->timeout = 0; for (; np != 0; np--) - window_copy_search_up(wme, 0); + window_copy_search_up(wme, 0, 0); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1993,7 +1992,7 @@ window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) data->searchregex = 1; data->timeout = 0; for (; np != 0; np--) - window_copy_search_down(wme, 1); + window_copy_search_down(wme, 1, 0); } return (WINDOW_COPY_CMD_NOTHING); } @@ -2013,7 +2012,7 @@ window_copy_cmd_search_forward_text(struct window_copy_cmd_state *cs) data->searchregex = 0; data->timeout = 0; for (; np != 0; np--) - window_copy_search_down(wme, 0); + window_copy_search_down(wme, 0, 0); } return (WINDOW_COPY_CMD_NOTHING); } @@ -2052,7 +2051,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); - if (!window_copy_search_up(wme, 0)) { + if (!window_copy_search_up(wme, 0, 1)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2062,7 +2061,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); - if (!window_copy_search_down(wme, 0)) { + if (!window_copy_search_down(wme, 0, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2105,7 +2104,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); - if (!window_copy_search_down(wme, 0)) { + if (!window_copy_search_down(wme, 0, 1)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2115,7 +2114,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); - if (!window_copy_search_up(wme, 0)) { + if (!window_copy_search_up(wme, 0, 1)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2406,8 +2405,8 @@ window_copy_search_compare(struct grid *gd, u_int px, u_int py, } static int -window_copy_search_lr(struct grid *gd, - struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last, int cis) +window_copy_search_lr(struct grid *gd, struct grid *sgd, u_int *ppx, u_int py, + u_int first, u_int last, int cis) { u_int ax, bx, px, pywrap, endline; int matched; @@ -2817,23 +2816,6 @@ window_copy_move_left(struct screen *s, u_int *fx, u_int *fy, int wrapflag) *fx = *fx - 1; } -static void -window_copy_move_right(struct screen *s, u_int *fx, u_int *fy, int wrapflag) -{ - if (*fx == screen_size_x(s) - 1) { /* right */ - if (*fy == screen_hsize(s) + screen_size_y(s) - 1) { /* bottom */ - if (wrapflag) { - *fx = 0; - *fy = 0; - } - return; - } - *fx = 0; - *fy = *fy + 1; - } else - *fx = *fx + 1; -} - static int window_copy_is_lowercase(const char *ptr) { @@ -2854,7 +2836,7 @@ window_copy_is_lowercase(const char *ptr) static int window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd, struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap, - int direction, int regex) + int direction, int regex, u_int *foundlen) { u_int i, px, sx, ssize = 1; int found = 0, cflags = REG_EXTENDED; @@ -2871,6 +2853,7 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd, free(sbuf); return (0); } + free(sbuf); } if (direction) { @@ -2878,15 +2861,20 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd, if (regex) { found = window_copy_search_lr_regex(gd, &px, &sx, i, fx, gd->sx, ®); + if (found) + *foundlen = sx; } else { found = window_copy_search_lr(gd, sgd, &px, i, fx, gd->sx, cis); + if (found) + *foundlen = sgd->sx; } if (found) break; fx = 0; } } else { + *foundlen = 0; for (i = fy + 1; endline < i; i--) { if (regex) { found = window_copy_search_rl_regex(gd, @@ -2902,10 +2890,8 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd, fx = gd->sx - 1; } } - if (regex) { - free(sbuf); + if (regex) regfree(®); - } if (found) { window_copy_scroll_to(wme, px, i, 1); @@ -2915,7 +2901,7 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd, return (window_copy_search_jump(wme, gd, sgd, direction ? 0 : gd->sx - 1, direction ? 0 : gd->hsize + gd->sy - 1, fy, cis, 0, - direction, regex)); + direction, regex, foundlen)); } return (0); } @@ -2925,7 +2911,8 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd, * down. */ static int -window_copy_search(struct window_mode_entry *wme, int direction, int regex) +window_copy_search(struct window_mode_entry *wme, int direction, int regex, + int again) { struct window_pane *wp = wme->wp; struct window_copy_mode_data *data = wme->data; @@ -2933,7 +2920,7 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex) struct screen_write_ctx ctx; struct grid *gd = s->grid; const char *str = data->searchstr; - u_int fx, fy, endline; + u_int fx, fy, endline, i, foundlen; int wrapflag, cis, found, visible_only; if (regex && str[strcspn(str, "^$*+()?[].\\")] == '\0') @@ -2961,18 +2948,23 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex) wrapflag = options_get_number(wp->window->options, "wrap-search"); cis = window_copy_is_lowercase(str); - if (direction) { - window_copy_move_right(s, &fx, &fy, wrapflag); + if (direction) endline = gd->hsize + gd->sy - 1; - } else { - window_copy_move_left(s, &fx, &fy, wrapflag); + else { + if (again) + window_copy_move_left(s, &fx, &fy, wrapflag); endline = 0; } found = window_copy_search_jump(wme, gd, ss.grid, fx, fy, endline, cis, - wrapflag, direction, regex); - if (found) + wrapflag, direction, regex, &foundlen); + if (found) { window_copy_search_marks(wme, &ss, regex, visible_only); + if (foundlen != 0) { + for (i = 0; i < foundlen; i++) + window_copy_cursor_right(wme, 1); + } + } window_copy_redraw_screen(wme); screen_free(&ss); @@ -2995,8 +2987,8 @@ window_copy_visible_lines(struct window_copy_mode_data *data, u_int *start, } static int -window_copy_search_mark_at(struct window_copy_mode_data *data, u_int px, u_int py, - u_int *at) +window_copy_search_mark_at(struct window_copy_mode_data *data, u_int px, + u_int py, u_int *at) { struct screen *s = data->backing; struct grid *gd = s->grid; @@ -3049,6 +3041,7 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp, free(sbuf); return (0); } + free(sbuf); } tstart = get_timer(); @@ -3096,7 +3089,7 @@ again: data->searchgen++; } - px++; + px += width; } t = get_timer(); @@ -3146,10 +3139,8 @@ again: out: if (ssp == &ss) screen_free(&ss); - if (regex) { - free(sbuf); + if (regex) regfree(®); - } return (1); } @@ -3163,15 +3154,15 @@ window_copy_clear_marks(struct window_mode_entry *wme) } static int -window_copy_search_up(struct window_mode_entry *wme, int regex) +window_copy_search_up(struct window_mode_entry *wme, int regex, int again) { - return (window_copy_search(wme, 0, regex)); + return (window_copy_search(wme, 0, regex, again)); } static int -window_copy_search_down(struct window_mode_entry *wme, int regex) +window_copy_search_down(struct window_mode_entry *wme, int regex, int again) { - return (window_copy_search(wme, 1, regex)); + return (window_copy_search(wme, 1, regex, again)); } static void @@ -3256,7 +3247,7 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy, { struct window_copy_mode_data *data = wme->data; u_int mark, start, end, cy, cursor, current; - int inv = 0; + int inv = 0, found = 0; if (data->showmark && fy == data->my) { gc->attr = mkgc->attr; @@ -3282,20 +3273,28 @@ window_copy_update_style(struct window_mode_entry *wme, u_int fx, u_int fy, return; cy = screen_hsize(data->backing) - data->oy + data->cy; - if (window_copy_search_mark_at(data, data->cx, cy, &cursor) == 0 && - data->searchmark[cursor] == mark) { - window_copy_match_start_end(data, cursor, &start, &end); - if (current >= start && current <= end) { - gc->attr = cgc->attr; - if (inv) { - gc->fg = cgc->bg; - gc->bg = cgc->fg; - } - else { - gc->fg = cgc->fg; - gc->bg = cgc->bg; + if (window_copy_search_mark_at(data, data->cx, cy, &cursor) == 0) { + if (data->searchmark[cursor] == mark) + found = 1; + else if (cursor != 0) { + cursor--; + if (data->searchmark[cursor] == mark) + found = 1; + } + if (found) { + window_copy_match_start_end(data, cursor, &start, &end); + if (current >= start && current <= end) { + gc->attr = cgc->attr; + if (inv) { + gc->fg = cgc->bg; + gc->bg = cgc->fg; + } + else { + gc->fg = cgc->fg; + gc->bg = cgc->bg; + } + return; } - return; } } @@ -3370,7 +3369,8 @@ window_copy_write_line(struct window_mode_entry *wme, } else if (data->searchthis == -1) { size = xsnprintf(hdr, sizeof hdr, "(%d%s results) [%u/%u]", data->searchcount, - data->searchmore ? "+" : "", data->oy, hsize); + data->searchmore ? "+" : "", data->oy, + hsize); } else { size = xsnprintf(hdr, sizeof hdr, "(%d/%d results) [%u/%u]", data->searchthis, @@ -4142,7 +4142,7 @@ window_copy_cursor_left(struct window_mode_entry *wme) } static void -window_copy_cursor_right(struct window_mode_entry *wme) +window_copy_cursor_right(struct window_mode_entry *wme, int all) { struct window_copy_mode_data *data = wme->data; u_int px, py, yy, cx, cy; @@ -4150,7 +4150,7 @@ window_copy_cursor_right(struct window_mode_entry *wme) py = screen_hsize(data->backing) + data->cy - data->oy; yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1; - if (data->screen.sel != NULL && data->rectflag) + if (all || (data->screen.sel != NULL && data->rectflag)) px = screen_size_x(&data->screen); else px = window_copy_find_length(wme, py); diff --git a/window-customize.c b/window-customize.c index ecafc776..1dad07cd 100644 --- a/window-customize.c +++ b/window-customize.c @@ -380,7 +380,7 @@ window_customize_build_options(struct window_customize_modedata *data, struct format_tree *ft, const char *filter, struct cmd_find_state *fs) { struct mode_tree_item *top; - struct options_entry *o, *loop; + struct options_entry *o = NULL, *loop; const char **list = NULL, *name; u_int size = 0, i; enum window_customize_scope scope; @@ -1003,7 +1003,7 @@ window_customize_set_option_callback(struct client *c, void *itemdata, fail: *cause = toupper((u_char)*cause); - status_message_set(c, 1, "%s", cause); + status_message_set(c, -1, 1, "%s", cause); free(cause); return (0); } @@ -1018,7 +1018,7 @@ window_customize_set_option(struct client *c, struct options *oo; struct window_customize_itemdata *new_item; int flag, idx = item->idx; - enum window_customize_scope scope; + enum window_customize_scope scope = WINDOW_CUSTOMIZE_NONE; u_int choice; const char *name = item->name, *space = ""; char *prompt, *value, *text; @@ -1031,7 +1031,7 @@ window_customize_set_option(struct client *c, return; oe = options_table_entry(o); - if (~oe->scope & OPTIONS_TABLE_PANE) + if (oe != NULL && ~oe->scope & OPTIONS_TABLE_PANE) pane = 0; if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_ARRAY)) { scope = item->scope; @@ -1209,7 +1209,7 @@ window_customize_set_command_callback(struct client *c, void *itemdata, fail: *error = toupper((u_char)*error); - status_message_set(c, 1, "%s", error); + status_message_set(c, -1, 1, "%s", error); free(error); return (0); } |