mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
Complete option names as well.
This commit is contained in:
parent
9cddd796ff
commit
4af8db90e8
4
CHANGES
4
CHANGES
@ -1,5 +1,7 @@
|
|||||||
06 January 2009
|
06 January 2009
|
||||||
|
|
||||||
|
* Complete words at any point inside command in prompt, also use option name
|
||||||
|
as well as command names.
|
||||||
* Per-client prompt history of up to 100 items.
|
* Per-client prompt history of up to 100 items.
|
||||||
* Use a splay tree for key bindings instead of an array. As a side-effect this
|
* Use a splay tree for key bindings instead of an array. As a side-effect this
|
||||||
sorts them when listed.
|
sorts them when listed.
|
||||||
@ -798,7 +800,7 @@
|
|||||||
(including mutt, emacs). No status bar yet and no key remapping or other
|
(including mutt, emacs). No status bar yet and no key remapping or other
|
||||||
customisation.
|
customisation.
|
||||||
|
|
||||||
$Id: CHANGES,v 1.178 2009-01-06 15:37:15 nicm Exp $
|
$Id: CHANGES,v 1.179 2009-01-06 17:04:56 nicm Exp $
|
||||||
|
|
||||||
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
|
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
|
||||||
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB
|
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB
|
||||||
|
4
TODO
4
TODO
@ -44,9 +44,7 @@
|
|||||||
session not being watched?
|
session not being watched?
|
||||||
- tidy up window modes
|
- tidy up window modes
|
||||||
- problems with force-width when wrapping line in emacs?
|
- problems with force-width when wrapping line in emacs?
|
||||||
- command history for command-prompt. better tab completion (use options too)
|
- next prev word etc in command prompt; also ^K
|
||||||
- window options should be done similarly to standard options
|
|
||||||
- next prev word etc in command prompt
|
|
||||||
- many more info() displays for various things
|
- many more info() displays for various things
|
||||||
- vi half page scroll
|
- vi half page scroll
|
||||||
- document status line options, title bits
|
- document status line options, title bits
|
||||||
|
53
cmd.c
53
cmd.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd.c,v 1.67 2008-12-15 21:21:56 nicm Exp $ */
|
/* $Id: cmd.c,v 1.68 2009-01-06 17:04:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -74,57 +74,6 @@ const struct cmd_entry *cmd_table[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
char *
|
|
||||||
cmd_complete(const char *s)
|
|
||||||
{
|
|
||||||
const struct cmd_entry **entryp;
|
|
||||||
ARRAY_DECL(, const char *) list;
|
|
||||||
char *prefix, *s2;
|
|
||||||
u_int i;
|
|
||||||
size_t j;
|
|
||||||
|
|
||||||
if (*s == '\0')
|
|
||||||
return (xstrdup(s));
|
|
||||||
|
|
||||||
/* First, build a list of all the possible matches. */
|
|
||||||
ARRAY_INIT(&list);
|
|
||||||
for (entryp = cmd_table; *entryp != NULL; entryp++) {
|
|
||||||
if (strncmp((*entryp)->name, s, strlen(s)) != 0)
|
|
||||||
continue;
|
|
||||||
ARRAY_ADD(&list, (*entryp)->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If none, bail now with the original string. */
|
|
||||||
if (ARRAY_LENGTH(&list) == 0) {
|
|
||||||
ARRAY_FREE(&list);
|
|
||||||
return (xstrdup(s));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If an exact match, return it, with a trailing space. */
|
|
||||||
if (ARRAY_LENGTH(&list) == 1) {
|
|
||||||
xasprintf(&s2, "%s ", ARRAY_FIRST(&list));
|
|
||||||
ARRAY_FREE(&list);
|
|
||||||
return (s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now loop through the list and find the longest common prefix. */
|
|
||||||
prefix = xstrdup(ARRAY_FIRST(&list));
|
|
||||||
for (i = 1; i < ARRAY_LENGTH(&list); i++) {
|
|
||||||
s = ARRAY_ITEM(&list, i);
|
|
||||||
|
|
||||||
j = strlen(s);
|
|
||||||
if (j > strlen(prefix))
|
|
||||||
j = strlen(prefix);
|
|
||||||
for (; j > 0; j--) {
|
|
||||||
if (prefix[j - 1] != s[j - 1])
|
|
||||||
prefix[j - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ARRAY_FREE(&list);
|
|
||||||
return (prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cmd *
|
struct cmd *
|
||||||
cmd_parse(int argc, char **argv, char **cause)
|
cmd_parse(int argc, char **argv, char **cause)
|
||||||
{
|
{
|
||||||
|
124
status.c
124
status.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: status.c,v 1.53 2009-01-06 15:37:15 nicm Exp $ */
|
/* $Id: status.c,v 1.54 2009-01-06 17:04:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -33,6 +33,7 @@ size_t status_width(struct winlink *);
|
|||||||
char *status_print(struct session *, struct winlink *, struct grid_cell *);
|
char *status_print(struct session *, struct winlink *, struct grid_cell *);
|
||||||
|
|
||||||
void status_prompt_add_history(struct client *);
|
void status_prompt_add_history(struct client *);
|
||||||
|
char *status_prompt_complete(const char *);
|
||||||
|
|
||||||
/* Draw status for client on the last lines of given context. */
|
/* Draw status for client on the last lines of given context. */
|
||||||
void
|
void
|
||||||
@ -225,9 +226,10 @@ draw:
|
|||||||
gc.attr |= GRID_ATTR_REVERSE;
|
gc.attr |= GRID_ATTR_REVERSE;
|
||||||
else
|
else
|
||||||
gc.attr &= ~GRID_ATTR_REVERSE;
|
gc.attr &= ~GRID_ATTR_REVERSE;
|
||||||
if (rlen != 0)
|
if (rlen != 0) {
|
||||||
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - rlen - 2, yy);
|
ctx.write(
|
||||||
else
|
ctx.data, TTY_CURSORMOVE, c->sx - rlen - 2, yy);
|
||||||
|
} else
|
||||||
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - 1, yy);
|
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - 1, yy);
|
||||||
screen_redraw_putc(&ctx, &gc, '>');
|
screen_redraw_putc(&ctx, &gc, '>');
|
||||||
gc.attr &= ~GRID_ATTR_REVERSE;
|
gc.attr &= ~GRID_ATTR_REVERSE;
|
||||||
@ -467,8 +469,9 @@ status_prompt_redraw(struct client *c)
|
|||||||
void
|
void
|
||||||
status_prompt_key(struct client *c, int key)
|
status_prompt_key(struct client *c, int key)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s, *first, *last;
|
||||||
size_t size;
|
size_t size, n, off, idx;
|
||||||
|
char word[64];
|
||||||
|
|
||||||
size = strlen(c->prompt_buffer);
|
size = strlen(c->prompt_buffer);
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@ -497,16 +500,51 @@ status_prompt_key(struct client *c, int key)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\011':
|
case '\011':
|
||||||
if (strchr(c->prompt_buffer, ' ') != NULL)
|
if (*c->prompt_buffer == '\0')
|
||||||
break;
|
break;
|
||||||
if (c->prompt_index != strlen(c->prompt_buffer))
|
|
||||||
|
idx = c->prompt_index;
|
||||||
|
if (idx != 0)
|
||||||
|
idx--;
|
||||||
|
|
||||||
|
/* Find the word we are in. */
|
||||||
|
first = c->prompt_buffer + idx;
|
||||||
|
while (first > c->prompt_buffer && *first != ' ')
|
||||||
|
first--;
|
||||||
|
while (*first == ' ')
|
||||||
|
first++;
|
||||||
|
last = c->prompt_buffer + idx;
|
||||||
|
while (*last != '\0' && *last != ' ')
|
||||||
|
last++;
|
||||||
|
while (*last == ' ')
|
||||||
|
last--;
|
||||||
|
if (*last != '\0')
|
||||||
|
last++;
|
||||||
|
if (last <= first || last - first > (sizeof word) - 1)
|
||||||
|
break;
|
||||||
|
memcpy(word, first, last - first);
|
||||||
|
word[last - first] = '\0';
|
||||||
|
|
||||||
|
/* And try to complete it. */
|
||||||
|
if ((s = status_prompt_complete(word)) == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
s = cmd_complete(c->prompt_buffer);
|
log_debug("XXX '%s' '%s' '%s'", c->prompt_buffer, first, last);
|
||||||
xfree(c->prompt_buffer);
|
|
||||||
|
|
||||||
c->prompt_buffer = s;
|
/* Trim out word. */
|
||||||
c->prompt_index = strlen(c->prompt_buffer);
|
n = size - (last - c->prompt_buffer) + 1; /* with \0 */
|
||||||
|
memmove(first, last, n);
|
||||||
|
size -= last - first;
|
||||||
|
|
||||||
|
/* Insert the new word. */
|
||||||
|
size += strlen(s);
|
||||||
|
off = first - c->prompt_buffer;
|
||||||
|
c->prompt_buffer = xrealloc(c->prompt_buffer, 1, size + 1);
|
||||||
|
first = c->prompt_buffer + off;
|
||||||
|
memmove(first + strlen(s), first, n);
|
||||||
|
memcpy(first, s, strlen(s));
|
||||||
|
|
||||||
|
c->prompt_index = (first - c->prompt_buffer) + strlen(s);
|
||||||
|
|
||||||
c->flags |= CLIENT_STATUS;
|
c->flags |= CLIENT_STATUS;
|
||||||
break;
|
break;
|
||||||
@ -607,3 +645,65 @@ status_prompt_add_history(struct client *c)
|
|||||||
|
|
||||||
ARRAY_ADD(&c->prompt_hdata, xstrdup(c->prompt_buffer));
|
ARRAY_ADD(&c->prompt_hdata, xstrdup(c->prompt_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Complete word. */
|
||||||
|
char *
|
||||||
|
status_prompt_complete(const char *s)
|
||||||
|
{
|
||||||
|
const struct cmd_entry **cmdent;
|
||||||
|
const struct set_option_entry *optent;
|
||||||
|
ARRAY_DECL(, const char *) list;
|
||||||
|
char *prefix, *s2;
|
||||||
|
u_int i;
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
if (*s == '\0')
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* First, build a list of all the possible matches. */
|
||||||
|
ARRAY_INIT(&list);
|
||||||
|
for (cmdent = cmd_table; *cmdent != NULL; cmdent++) {
|
||||||
|
if (strncmp((*cmdent)->name, s, strlen(s)) == 0)
|
||||||
|
ARRAY_ADD(&list, (*cmdent)->name);
|
||||||
|
}
|
||||||
|
for (i = 0; i < NSETOPTION; i++) {
|
||||||
|
optent = &set_option_table[i];
|
||||||
|
if (strncmp(optent->name, s, strlen(s)) == 0)
|
||||||
|
ARRAY_ADD(&list, optent->name);
|
||||||
|
}
|
||||||
|
for (i = 0; i < NSETWINDOWOPTION; i++) {
|
||||||
|
optent = &set_window_option_table[i];
|
||||||
|
if (strncmp(optent->name, s, strlen(s)) == 0)
|
||||||
|
ARRAY_ADD(&list, optent->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If none, bail now. */
|
||||||
|
if (ARRAY_LENGTH(&list) == 0) {
|
||||||
|
ARRAY_FREE(&list);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If an exact match, return it, with a trailing space. */
|
||||||
|
if (ARRAY_LENGTH(&list) == 1) {
|
||||||
|
xasprintf(&s2, "%s ", ARRAY_FIRST(&list));
|
||||||
|
ARRAY_FREE(&list);
|
||||||
|
return (s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now loop through the list and find the longest common prefix. */
|
||||||
|
prefix = xstrdup(ARRAY_FIRST(&list));
|
||||||
|
for (i = 1; i < ARRAY_LENGTH(&list); i++) {
|
||||||
|
s = ARRAY_ITEM(&list, i);
|
||||||
|
|
||||||
|
j = strlen(s);
|
||||||
|
if (j > strlen(prefix))
|
||||||
|
j = strlen(prefix);
|
||||||
|
for (; j > 0; j--) {
|
||||||
|
if (prefix[j - 1] != s[j - 1])
|
||||||
|
prefix[j - 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ARRAY_FREE(&list);
|
||||||
|
return (prefix);
|
||||||
|
}
|
||||||
|
3
tmux.h
3
tmux.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tmux.h,v 1.206 2009-01-06 15:37:15 nicm Exp $ */
|
/* $Id: tmux.h,v 1.207 2009-01-06 17:04:56 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -1009,7 +1009,6 @@ struct session *arg_parse_session(const char *);
|
|||||||
int arg_parse_window(const char *, struct session **, int *);
|
int arg_parse_window(const char *, struct session **, int *);
|
||||||
|
|
||||||
/* cmd.c */
|
/* cmd.c */
|
||||||
char *cmd_complete(const char *);
|
|
||||||
struct cmd *cmd_parse(int, char **, char **);
|
struct cmd *cmd_parse(int, char **, char **);
|
||||||
void cmd_exec(struct cmd *, struct cmd_ctx *);
|
void cmd_exec(struct cmd *, struct cmd_ctx *);
|
||||||
void cmd_send(struct cmd *, struct buffer *);
|
void cmd_send(struct cmd *, struct buffer *);
|
||||||
|
Loading…
Reference in New Issue
Block a user