aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2009-01-06 17:04:56 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2009-01-06 17:04:56 +0000
commit4af8db90e825a2e6dd7034ec88fd6f856bf83e9e (patch)
tree2d16baaefd6306329f94c267ae0b39ca022e2d9e
parent9cddd796ffef383893b5fd4e228f4d18673a77bd (diff)
downloadrtmux-4af8db90e825a2e6dd7034ec88fd6f856bf83e9e.tar.gz
rtmux-4af8db90e825a2e6dd7034ec88fd6f856bf83e9e.tar.bz2
rtmux-4af8db90e825a2e6dd7034ec88fd6f856bf83e9e.zip
Complete option names as well.
-rw-r--r--CHANGES4
-rw-r--r--TODO4
-rw-r--r--cmd.c53
-rw-r--r--status.c124
-rw-r--r--tmux.h3
5 files changed, 118 insertions, 70 deletions
diff --git a/CHANGES b/CHANGES
index acf1a7a2..303375a1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,7 @@
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.
* Use a splay tree for key bindings instead of an array. As a side-effect this
sorts them when listed.
@@ -798,7 +800,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other
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: rivo nurges lscm Erdely eol smysession mysession ek dstname RB
diff --git a/TODO b/TODO
index 99e56002..3571bba9 100644
--- a/TODO
+++ b/TODO
@@ -44,9 +44,7 @@
session not being watched?
- tidy up window modes
- problems with force-width when wrapping line in emacs?
-- command history for command-prompt. better tab completion (use options too)
-- window options should be done similarly to standard options
-- next prev word etc in command prompt
+- next prev word etc in command prompt; also ^K
- many more info() displays for various things
- vi half page scroll
- document status line options, title bits
diff --git a/cmd.c b/cmd.c
index 4f4cf631..d9d46a40 100644
--- a/cmd.c
+++ b/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>
@@ -74,57 +74,6 @@ const struct cmd_entry *cmd_table[] = {
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 *
cmd_parse(int argc, char **argv, char **cause)
{
diff --git a/status.c b/status.c
index dde750aa..528f4299 100644
--- a/status.c
+++ b/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>
@@ -33,6 +33,7 @@ size_t status_width(struct winlink *);
char *status_print(struct session *, struct winlink *, struct grid_cell *);
void status_prompt_add_history(struct client *);
+char *status_prompt_complete(const char *);
/* Draw status for client on the last lines of given context. */
void
@@ -225,9 +226,10 @@ draw:
gc.attr |= GRID_ATTR_REVERSE;
else
gc.attr &= ~GRID_ATTR_REVERSE;
- if (rlen != 0)
- ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - rlen - 2, yy);
- else
+ if (rlen != 0) {
+ ctx.write(
+ ctx.data, TTY_CURSORMOVE, c->sx - rlen - 2, yy);
+ } else
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - 1, yy);
screen_redraw_putc(&ctx, &gc, '>');
gc.attr &= ~GRID_ATTR_REVERSE;
@@ -467,8 +469,9 @@ status_prompt_redraw(struct client *c)
void
status_prompt_key(struct client *c, int key)
{
- char *s;
- size_t size;
+ char *s, *first, *last;
+ size_t size, n, off, idx;
+ char word[64];
size = strlen(c->prompt_buffer);
switch (key) {
@@ -497,16 +500,51 @@ status_prompt_key(struct client *c, int key)
}
break;
case '\011':
- if (strchr(c->prompt_buffer, ' ') != NULL)
+ if (*c->prompt_buffer == '\0')
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';
- s = cmd_complete(c->prompt_buffer);
- xfree(c->prompt_buffer);
+ /* And try to complete it. */
+ if ((s = status_prompt_complete(word)) == NULL)
+ break;
- c->prompt_buffer = s;
- c->prompt_index = strlen(c->prompt_buffer);
+ log_debug("XXX '%s' '%s' '%s'", c->prompt_buffer, first, last);
+
+ /* Trim out word. */
+ 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;
break;
@@ -607,3 +645,65 @@ status_prompt_add_history(struct client *c)
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);
+}
diff --git a/tmux.h b/tmux.h
index 8f891079..d709c18d 100644
--- a/tmux.h
+++ b/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>
@@ -1009,7 +1009,6 @@ struct session *arg_parse_session(const char *);
int arg_parse_window(const char *, struct session **, int *);
/* cmd.c */
-char *cmd_complete(const char *);
struct cmd *cmd_parse(int, char **, char **);
void cmd_exec(struct cmd *, struct cmd_ctx *);
void cmd_send(struct cmd *, struct buffer *);