From 4ee816510fbf81066030ff405539899fcac5aae6 Mon Sep 17 00:00:00 2001 From: Hannes Date: Fri, 1 Aug 2008 10:34:15 +0200 Subject: [PATCH] awesome-menu: match string mode and autocomplete I'm made some simple modifications of awesome-menu.c to achieve the following: 1. Match the string entered by the user with the whole search string. So far, it only matches from the start of the string. For menu entries like 'gksu synaptic', the default behaviour is very inconvenient, because obviously, I don't want to enter the 'gksu' part every time. Another example: I have iceweasel, iceape and icedove installed. Entering 'wea' is enough to find 'iceweasel' exclusively if the whole string is searched. 'ice', on the other hand, won't do much good. 2. If there's just one single match, select that one automatically. This saves hitting tab once in the cases when the choice is obvious (because there is only one). Signed-off-by: Julien Danjou --- awesome-menu.c | 37 +++++++++++++++++++++++++++++-------- common/configopts.c | 2 ++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/awesome-menu.c b/awesome-menu.c index 15b86b2b5..f0d27a0c3 100644 --- a/awesome-menu.c +++ b/awesome-menu.c @@ -122,6 +122,8 @@ typedef struct char *exec; /** Prompt */ char *prompt; + /** String match mode */ + Bool match_string; } AwesomeMenuConf; static AwesomeMenuConf globalconf; @@ -196,6 +198,7 @@ config_parse(int screen, const char *confpatharg, geometry->width = i; if((i = cfg_getint(cfg_menu, "height")) > 0) geometry->height = i; + globalconf.match_string = cfg_getbool(cfg_menu, "match_string"); } if(cfg_screen @@ -373,11 +376,12 @@ complete(Bool reverse) /** Compute a match from completion list for word. * \param word the word to match */ -static void +static int compute_match(const char *word) { ssize_t len = a_strlen(word); item_t *item; + int matches = 0; /* reset the selected item to NULL */ globalconf.item_selected = NULL; @@ -389,8 +393,11 @@ compute_match(const char *word) item_list_fill_file(word); for(item = globalconf.items; item; item = item->next) - if(!a_strncmp(word, item->data, a_strlen(word))) + if((globalconf.match_string && strstr(item->data, word) != NULL) || (!globalconf.match_string && !a_strncmp(word, item->data, a_strlen(word)))) + { item->match = True; + matches++; + } else item->match = False; } @@ -399,8 +406,14 @@ compute_match(const char *word) if(a_strlen(globalconf.text)) item_list_fill_file(NULL); for(item = globalconf.items; item; item = item->next) + { item->match = True; + matches++; + } } + + return matches; + } /* Why not? */ @@ -498,7 +511,7 @@ handle_kpress(XKeyEvent *e) { char buf[32]; KeySym ksym; - int num; + int num, matches; ssize_t len; size_t text_dst_len; @@ -538,7 +551,9 @@ handle_kpress(XKeyEvent *e) globalconf.text[i--] = '\0'; while(i >= 0 && globalconf.text[i] != ' ') globalconf.text[i--] = '\0'; - compute_match(get_last_word(globalconf.text)); + matches = compute_match(get_last_word(globalconf.text)); + if (matches == 1) + complete(False); redraw(); } return; @@ -576,7 +591,9 @@ handle_kpress(XKeyEvent *e) } a_strncat(globalconf.text, globalconf.text_size, buf, num); } - compute_match(get_last_word(globalconf.text)); + matches = compute_match(get_last_word(globalconf.text)); + if (matches == 1) + complete(False); redraw(); } break; @@ -584,7 +601,9 @@ handle_kpress(XKeyEvent *e) if(len) { globalconf.text[--len] = '\0'; - compute_match(get_last_word(globalconf.text)); + matches = compute_match(get_last_word(globalconf.text)); + if (matches == 1) + complete(False); redraw(); } break; @@ -696,7 +715,7 @@ int main(int argc, char **argv) { XEvent ev; - int opt, ret, x, y, i, screen = 0; + int opt, ret, x, y, i, screen = 0, matches; char *configfile = NULL, *cmd; ssize_t len; const char *shell = getenv("SHELL"); @@ -800,7 +819,9 @@ main(int argc, char **argv) item_list_fill_file(NULL); } - compute_match(NULL); + matches = compute_match(NULL); + if (matches == 1) + complete(False); redraw(); diff --git a/common/configopts.c b/common/configopts.c index 3ecc53496..2b29c8cf0 100644 --- a/common/configopts.c +++ b/common/configopts.c @@ -631,6 +631,8 @@ cfg_opt_t menu_opts[] = CFG_INT((char *) "x", 0xffffffff, CFGF_NONE), /** Y coordinate, do not set for auto. */ CFG_INT((char *) "y", 0xffffffff, CFGF_NONE), + /** String matching mode (true to complete string) */ + CFG_BOOL((char *) "match_string", cfg_false, CFGF_NONE), /** Styles to use for this menu. */ CFG_SEC((char *) "styles", styles_opts, CFGF_NONE), CFG_AWESOME_END()