diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-05-16 15:16:38 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-05-16 15:16:38 +0000 |
commit | ab6540e15e0175e862fcc9df19b2fd939ab3ad11 (patch) | |
tree | e68011438f0a43fffdcbd50a0358b60f91642af0 /usr.bin/tmux | |
parent | ea8b037986e349a8e4b05f8c76746b5e13465fae (diff) |
Add -W and -T flags to command-prompt to only complete a window and a
target, also complete aliases.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/cmd-command-prompt.c | 10 | ||||
-rw-r--r-- | usr.bin/tmux/key-bindings.c | 6 | ||||
-rw-r--r-- | usr.bin/tmux/status.c | 114 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 12 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 |
5 files changed, 100 insertions, 46 deletions
diff --git a/usr.bin/tmux/cmd-command-prompt.c b/usr.bin/tmux/cmd-command-prompt.c index b5eeed79c0d..0a78ae8854c 100644 --- a/usr.bin/tmux/cmd-command-prompt.c +++ b/usr.bin/tmux/cmd-command-prompt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-command-prompt.c,v 1.51 2020/04/13 20:51:57 nicm Exp $ */ +/* $OpenBSD: cmd-command-prompt.c,v 1.52 2020/05/16 15:16:36 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -40,8 +40,8 @@ const struct cmd_entry cmd_command_prompt_entry = { .name = "command-prompt", .alias = NULL, - .args = { "1kiI:Np:t:", 0, 1 }, - .usage = "[-1kiN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " " + .args = { "1kiI:Np:Tt:W", 0, 1 }, + .usage = "[-1kiNTW] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " " "[template]", .flags = CMD_CLIENT_TFLAG, @@ -121,6 +121,10 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) cdata->flags |= PROMPT_INCREMENTAL; else if (args_has(args, 'k')) cdata->flags |= PROMPT_KEY; + else if (args_has(args, 'W')) + cdata->flags |= PROMPT_WINDOW; + else if (args_has(args, 'T')) + cdata->flags |= PROMPT_TARGET; status_prompt_set(tc, prompt, input, cmd_command_prompt_callback, cmd_command_prompt_free, cdata, cdata->flags); free(prompt); diff --git a/usr.bin/tmux/key-bindings.c b/usr.bin/tmux/key-bindings.c index 8e709b196fe..5f0f9902f3f 100644 --- a/usr.bin/tmux/key-bindings.c +++ b/usr.bin/tmux/key-bindings.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-bindings.c,v 1.123 2020/04/17 08:03:22 nicm Exp $ */ +/* $OpenBSD: key-bindings.c,v 1.124 2020/05/16 15:16:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -243,12 +243,12 @@ key_bindings_init(void) "bind -N 'Rename current session' '$' command-prompt -I'#S' \"rename-session -- '%%'\"", "bind -N 'Split window horizontally' % split-window -h", "bind -N 'Kill current window' & confirm-before -p\"kill-window #W? (y/n)\" kill-window", - "bind -N 'Prompt for window index to select' \"'\" command-prompt -pindex \"select-window -t ':%%'\"", + "bind -N 'Prompt for window index to select' \"'\" command-prompt -Wpindex \"select-window -t ':%%'\"", "bind -N 'Switch to previous client' ( switch-client -p", "bind -N 'Switch to next client' ) switch-client -n", "bind -N 'Rename current window' , command-prompt -I'#W' \"rename-window -- '%%'\"", "bind -N 'Delete the most recent paste buffer' - delete-buffer", - "bind -N 'Move the current window' . command-prompt \"move-window -t '%%'\"", + "bind -N 'Move the current window' . command-prompt -T \"move-window -t '%%'\"", "bind -N 'Describe key binding' '/' command-prompt -kpkey 'list-keys -1N \"%%%\"'", "bind -N 'Select window 0' 0 select-window -t:=0", "bind -N 'Select window 1' 1 select-window -t:=1", diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c index 3799174ee62..f53f0cca8ca 100644 --- a/usr.bin/tmux/status.c +++ b/usr.bin/tmux/status.c @@ -1,4 +1,4 @@ -/* $OpenBSD: status.c,v 1.204 2020/05/16 15:06:03 nicm Exp $ */ +/* $OpenBSD: status.c,v 1.205 2020/05/16 15:16:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -38,6 +38,8 @@ static const char *status_prompt_down_history(u_int *); static void status_prompt_add_history(const char *); static char *status_prompt_complete(struct client *, const char *, u_int); +static char *status_prompt_complete_window_menu(struct client *, + struct session *, u_int, char); struct status_prompt_menu { struct client *c; @@ -933,13 +935,11 @@ status_prompt_replace_complete(struct client *c, const char *s) size_t size, n, off, idx, used; struct utf8_data *first, *last, *ud; - if (c->prompt_buffer[0].size == 0) - return (0); - size = utf8_strlen(c->prompt_buffer); - + /* Work out where the cursor currently is. */ idx = c->prompt_index; if (idx != 0) idx--; + size = utf8_strlen(c->prompt_buffer); /* Find the word we are in. */ first = &c->prompt_buffer[idx]; @@ -954,7 +954,7 @@ status_prompt_replace_complete(struct client *c, const char *s) last--; if (last->size != 0) last++; - if (last <= first) + if (last < first) return (0); if (s == NULL) { used = 0; @@ -1071,7 +1071,15 @@ process_key: } break; case '\011': /* Tab */ - if (status_prompt_replace_complete(c, NULL)) + if (c->prompt_flags & PROMPT_WINDOW) { + s = status_prompt_complete_window_menu(c, c->session, + 0, '\0'); + if (s != NULL) { + free(c->prompt_buffer); + c->prompt_buffer = utf8_fromcstr(s); + c->prompt_index = utf8_strlen(c->prompt_buffer); + } + } else if (status_prompt_replace_complete(c, NULL)) goto changed; break; case KEYC_BSPACE: @@ -1376,6 +1384,11 @@ status_prompt_complete_list(u_int *size, const char *s, int at_start) list = xreallocarray(list, (*size) + 1, sizeof *list); list[(*size)++] = xstrdup((*cmdent)->name); } + if ((*cmdent)->alias != NULL && + strncmp((*cmdent)->alias, s, slen) == 0) { + list = xreallocarray(list, (*size) + 1, sizeof *list); + list[(*size)++] = xstrdup((*cmdent)->alias); + } } o = options_get_only(global_options, "command-alias"); if (o != NULL) { @@ -1450,7 +1463,12 @@ status_prompt_menu_callback(__unused struct menu *menu, u_int idx, key_code key, s = xstrdup(spm->list[idx]); else xasprintf(&s, "-%c%s", spm->flag, spm->list[idx]); - if (status_prompt_replace_complete(c, s)) + if (c->prompt_flags & PROMPT_WINDOW) { + free(c->prompt_buffer); + c->prompt_buffer = utf8_fromcstr(s); + c->prompt_index = utf8_strlen(c->prompt_buffer); + c->flags |= CLIENT_REDRAWSTATUS; + } else if (status_prompt_replace_complete(c, s)) c->flags |= CLIENT_REDRAWSTATUS; free(s); } @@ -1544,10 +1562,14 @@ status_prompt_complete_window_menu(struct client *c, struct session *s, menu = menu_create(""); RB_FOREACH(wl, winlinks, &s->windows) { list = xreallocarray(list, size + 1, sizeof *list); - xasprintf(&list[size++], "%s:%d", s->name, wl->idx); - - xasprintf(&tmp, "%s:%d (%s)", s->name, wl->idx, - wl->window->name); + if (c->prompt_flags & PROMPT_WINDOW) { + xasprintf(&tmp, "%d (%s)", wl->idx, wl->window->name); + xasprintf(&list[size++], "%d", wl->idx); + } else { + xasprintf(&tmp, "%s:%d (%s)", s->name, wl->idx, + wl->window->name); + xasprintf(&list[size++], "%s:%d", s->name, wl->idx); + } item.name = tmp; item.key = '0' + size - 1; item.command = NULL; @@ -1559,8 +1581,11 @@ status_prompt_complete_window_menu(struct client *c, struct session *s, } if (size == 1) { menu_free(menu); - xasprintf(&tmp, "-%c%s", flag, list[0]); - free(list[0]); + if (flag != '\0') { + xasprintf(&tmp, "-%c%s", flag, list[0]); + free(list[0]); + } else + tmp = list[0]; free(list); return (tmp); } @@ -1598,21 +1623,45 @@ status_prompt_complete_sort(const void *a, const void *b) return (strcmp(*aa, *bb)); } +/* Complete a session. */ +static char * +status_prompt_complete_session(char ***list, u_int *size, const char *s, + char flag) +{ + struct session *loop; + char *out, *tmp; + + RB_FOREACH(loop, sessions, &sessions) { + if (*s != '\0' && strncmp(loop->name, s, strlen(s)) != 0) + continue; + *list = xreallocarray(*list, (*size) + 2, sizeof **list); + xasprintf(&(*list)[(*size)++], "%s:", loop->name); + } + out = status_prompt_complete_prefix(*list, *size); + if (out != NULL && flag != '\0') { + xasprintf(&tmp, "-%c%s", flag, out); + free(out); + out = tmp; + } + return (out); +} + /* Complete word. */ static char * status_prompt_complete(struct client *c, const char *word, u_int offset) { - struct session *session, *loop; + struct session *session; const char *s, *colon; - size_t slen; - char **list = NULL, *copy = NULL, *out = NULL, *tmp; + char **list = NULL, *copy = NULL, *out = NULL; char flag = '\0'; u_int size = 0, i; - if (*word == '\0') + if (*word == '\0' && (~c->prompt_flags & PROMPT_TARGET)) return (NULL); - if (strncmp(word, "-t", 2) != 0 && strncmp(word, "-s", 2) != 0) { + if ((~c->prompt_flags & PROMPT_TARGET) && + strncmp(word, "-t", 2) != 0 && + strncmp(word, "-s", 2) != 0) { list = status_prompt_complete_list(&size, word, offset == 0); if (size == 0) out = NULL; @@ -1623,28 +1672,19 @@ status_prompt_complete(struct client *c, const char *word, u_int offset) goto found; } - s = word + 2; - slen = strlen(s); - - flag = word[1]; - offset += 2; - + if (c->prompt_flags & PROMPT_TARGET) { + s = word; + flag = '\0'; + } else { + s = word + 2; + flag = word[1]; + offset += 2; + } colon = strchr(s, ':'); /* If there is no colon, complete as a session. */ if (colon == NULL) { - RB_FOREACH(loop, sessions, &sessions) { - if (strncmp(loop->name, s, strlen(s)) != 0) - continue; - list = xreallocarray(list, size + 2, sizeof *list); - xasprintf(&list[size++], "%s:", loop->name); - } - out = status_prompt_complete_prefix(list, size); - if (out != NULL) { - xasprintf(&tmp, "-%c%s", flag, out); - free(out); - out = tmp; - } + out = status_prompt_complete_session(&list, &size, s, flag); goto found; } diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index f53f6376319..d7695354fac 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.757 2020/05/16 15:11:52 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.758 2020/05/16 15:16:36 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -4969,7 +4969,7 @@ session option. Commands related to the status line are as follows: .Bl -tag -width Ds .It Xo Ic command-prompt -.Op Fl 1ikN +.Op Fl 1ikNTW .Op Fl I Ar inputs .Op Fl p Ar prompts .Op Fl t Ar target-client @@ -5028,6 +5028,14 @@ makes the prompt only accept numeric key presses. .Fl i executes the command every time the prompt input changes instead of when the user exits the command prompt. +.Fl T +tells +.Nm +that the prompt is for a target which affects what completions are offered when +.Em Tab +is pressed; +.Fl W +is similar but indicates the prompt is for a window. .Pp The following keys have a special meaning in the command prompt, depending on the value of the diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 187200fefd2..bbcd85d3eec 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1027 2020/05/16 15:11:52 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1028 2020/05/16 15:16:37 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1602,6 +1602,8 @@ struct client { #define PROMPT_INCREMENTAL 0x4 #define PROMPT_NOFORMAT 0x8 #define PROMPT_KEY 0x10 +#define PROMPT_WINDOW 0x20 +#define PROMPT_TARGET 0x40 int prompt_flags; struct session *session; |