version 1.204, 2020/05/16 15:06:03 |
version 1.205, 2020/05/16 15:16:36 |
|
|
static void status_prompt_add_history(const char *); |
static void status_prompt_add_history(const char *); |
|
|
static char *status_prompt_complete(struct client *, const char *, u_int); |
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 status_prompt_menu { |
struct client *c; |
struct client *c; |
|
|
size_t size, n, off, idx, used; |
size_t size, n, off, idx, used; |
struct utf8_data *first, *last, *ud; |
struct utf8_data *first, *last, *ud; |
|
|
if (c->prompt_buffer[0].size == 0) |
/* Work out where the cursor currently is. */ |
return (0); |
|
size = utf8_strlen(c->prompt_buffer); |
|
|
|
idx = c->prompt_index; |
idx = c->prompt_index; |
if (idx != 0) |
if (idx != 0) |
idx--; |
idx--; |
|
size = utf8_strlen(c->prompt_buffer); |
|
|
/* Find the word we are in. */ |
/* Find the word we are in. */ |
first = &c->prompt_buffer[idx]; |
first = &c->prompt_buffer[idx]; |
|
|
last--; |
last--; |
if (last->size != 0) |
if (last->size != 0) |
last++; |
last++; |
if (last <= first) |
if (last < first) |
return (0); |
return (0); |
if (s == NULL) { |
if (s == NULL) { |
used = 0; |
used = 0; |
|
|
} |
} |
break; |
break; |
case '\011': /* Tab */ |
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; |
goto changed; |
break; |
break; |
case KEYC_BSPACE: |
case KEYC_BSPACE: |
|
|
list = xreallocarray(list, (*size) + 1, sizeof *list); |
list = xreallocarray(list, (*size) + 1, sizeof *list); |
list[(*size)++] = xstrdup((*cmdent)->name); |
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"); |
o = options_get_only(global_options, "command-alias"); |
if (o != NULL) { |
if (o != NULL) { |
|
|
s = xstrdup(spm->list[idx]); |
s = xstrdup(spm->list[idx]); |
else |
else |
xasprintf(&s, "-%c%s", spm->flag, spm->list[idx]); |
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; |
c->flags |= CLIENT_REDRAWSTATUS; |
|
} else if (status_prompt_replace_complete(c, s)) |
|
c->flags |= CLIENT_REDRAWSTATUS; |
free(s); |
free(s); |
} |
} |
|
|
|
|
menu = menu_create(""); |
menu = menu_create(""); |
RB_FOREACH(wl, winlinks, &s->windows) { |
RB_FOREACH(wl, winlinks, &s->windows) { |
list = xreallocarray(list, size + 1, sizeof *list); |
list = xreallocarray(list, size + 1, sizeof *list); |
xasprintf(&list[size++], "%s:%d", s->name, wl->idx); |
if (c->prompt_flags & PROMPT_WINDOW) { |
|
xasprintf(&tmp, "%d (%s)", wl->idx, wl->window->name); |
xasprintf(&tmp, "%s:%d (%s)", s->name, wl->idx, |
xasprintf(&list[size++], "%d", wl->idx); |
wl->window->name); |
} 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.name = tmp; |
item.key = '0' + size - 1; |
item.key = '0' + size - 1; |
item.command = NULL; |
item.command = NULL; |
|
|
} |
} |
if (size == 1) { |
if (size == 1) { |
menu_free(menu); |
menu_free(menu); |
xasprintf(&tmp, "-%c%s", flag, list[0]); |
if (flag != '\0') { |
free(list[0]); |
xasprintf(&tmp, "-%c%s", flag, list[0]); |
|
free(list[0]); |
|
} else |
|
tmp = list[0]; |
free(list); |
free(list); |
return (tmp); |
return (tmp); |
} |
} |
|
|
return (strcmp(*aa, *bb)); |
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. */ |
/* Complete word. */ |
static char * |
static char * |
status_prompt_complete(struct client *c, const char *word, u_int offset) |
status_prompt_complete(struct client *c, const char *word, u_int offset) |
{ |
{ |
struct session *session, *loop; |
struct session *session; |
const char *s, *colon; |
const char *s, *colon; |
size_t slen; |
char **list = NULL, *copy = NULL, *out = NULL; |
char **list = NULL, *copy = NULL, *out = NULL, *tmp; |
|
char flag = '\0'; |
char flag = '\0'; |
u_int size = 0, i; |
u_int size = 0, i; |
|
|
if (*word == '\0') |
if (*word == '\0' && (~c->prompt_flags & PROMPT_TARGET)) |
return (NULL); |
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); |
list = status_prompt_complete_list(&size, word, offset == 0); |
if (size == 0) |
if (size == 0) |
out = NULL; |
out = NULL; |
|
|
goto found; |
goto found; |
} |
} |
|
|
s = word + 2; |
if (c->prompt_flags & PROMPT_TARGET) { |
slen = strlen(s); |
s = word; |
|
flag = '\0'; |
flag = word[1]; |
} else { |
offset += 2; |
s = word + 2; |
|
flag = word[1]; |
|
offset += 2; |
|
} |
colon = strchr(s, ':'); |
colon = strchr(s, ':'); |
|
|
/* If there is no colon, complete as a session. */ |
/* If there is no colon, complete as a session. */ |
if (colon == NULL) { |
if (colon == NULL) { |
RB_FOREACH(loop, sessions, &sessions) { |
out = status_prompt_complete_session(&list, &size, s, flag); |
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; |
|
} |
|
goto found; |
goto found; |
} |
} |
|
|