summaryrefslogtreecommitdiff
path: root/usr.bin/tmux
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2020-05-16 15:16:38 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2020-05-16 15:16:38 +0000
commitab6540e15e0175e862fcc9df19b2fd939ab3ad11 (patch)
treee68011438f0a43fffdcbd50a0358b60f91642af0 /usr.bin/tmux
parentea8b037986e349a8e4b05f8c76746b5e13465fae (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.c10
-rw-r--r--usr.bin/tmux/key-bindings.c6
-rw-r--r--usr.bin/tmux/status.c114
-rw-r--r--usr.bin/tmux/tmux.112
-rw-r--r--usr.bin/tmux/tmux.h4
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;