mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	Complete option names as well.
This commit is contained in:
		
							
								
								
									
										4
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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>
 | 
			
		||||
@@ -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)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										126
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								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)
 | 
			
		||||
			break;
 | 
			
		||||
		if (c->prompt_index != strlen(c->prompt_buffer))
 | 
			
		||||
		if (*c->prompt_buffer == '\0')
 | 
			
		||||
			break;
 | 
			
		||||
		
 | 
			
		||||
		s = cmd_complete(c->prompt_buffer);
 | 
			
		||||
		xfree(c->prompt_buffer);
 | 
			
		||||
		idx = c->prompt_index;
 | 
			
		||||
		if (idx != 0)
 | 
			
		||||
			idx--;
 | 
			
		||||
 | 
			
		||||
		c->prompt_buffer = s;
 | 
			
		||||
		c->prompt_index = strlen(c->prompt_buffer);
 | 
			
		||||
		/* 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;
 | 
			
		||||
 | 
			
		||||
		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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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>
 | 
			
		||||
@@ -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 *);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user