aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNir Tzachar <nir.tzachar@gmail.com>2010-08-08 09:50:06 -0400
committerMichal Marek <mmarek@suse.cz>2010-08-16 16:04:55 -0400
commita72f3e2b82eb26f43bed1f83beeeb47830918811 (patch)
tree0735c997af4315ad5bea95a9b1d8acaaf5b557aa
parent3643f849d7da5c12da589beb03c12303fe79b841 (diff)
nconfig: add search support
Remove the old hotkeys feature, and replace it by an interactive string search. From nconfig help: Searching: pressing '/' triggers interactive search mode. nconfig performs a case insensitive search for the string in the menu prompts (no regex support). Pressing the up/down keys highlights the previous/next matching item. Backspace removes one character from the match string. Pressing either '/' again or ESC exits search mode. All other keys behave normally. Miscellaneous other changes (including Rundy's and Justin's input). Signed-off-by: Nir Tzachar <nir.tzachar@gmail.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Michal Marek <mmarek@suse.cz>
-rw-r--r--scripts/kconfig/nconf.c365
-rw-r--r--scripts/kconfig/nconf.gui.c20
-rw-r--r--scripts/kconfig/nconf.h3
3 files changed, 208 insertions, 180 deletions
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 2ba71bcd38e6..18a215de9f36 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -5,9 +5,12 @@
5 * Derived from menuconfig. 5 * Derived from menuconfig.
6 * 6 *
7 */ 7 */
8#define _GNU_SOURCE
9#include <string.h>
8#define LKC_DIRECT_LINK 10#define LKC_DIRECT_LINK
9#include "lkc.h" 11#include "lkc.h"
10#include "nconf.h" 12#include "nconf.h"
13#include <ctype.h>
11 14
12static const char nconf_readme[] = N_( 15static const char nconf_readme[] = N_(
13"Overview\n" 16"Overview\n"
@@ -23,7 +26,7 @@ static const char nconf_readme[] = N_(
23" < > can be built in, modularized or removed\n" 26" < > can be built in, modularized or removed\n"
24" { } can be built in or modularized (selected by other feature)\n" 27" { } can be built in or modularized (selected by other feature)\n"
25" - - are selected by other feature,\n" 28" - - are selected by other feature,\n"
26" XXX cannot be selected. use Symbol Info to find out why,\n" 29" XXX cannot be selected. Use Symbol Info to find out why,\n"
27"while *, M or whitespace inside braces means to build in, build as\n" 30"while *, M or whitespace inside braces means to build in, build as\n"
28"a module or to exclude the feature respectively.\n" 31"a module or to exclude the feature respectively.\n"
29"\n" 32"\n"
@@ -41,9 +44,13 @@ static const char nconf_readme[] = N_(
41" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" 44" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
42" Submenus are designated by \"--->\".\n" 45" Submenus are designated by \"--->\".\n"
43"\n" 46"\n"
44" Shortcut: Press the option's highlighted letter (hotkey).\n" 47" Searching: pressing '/' triggers interactive search mode.\n"
45" Pressing a hotkey more than once will sequence\n" 48" nconfig performs a case insensitive search for the string\n"
46" through all visible items which use that hotkey.\n" 49" in the menu prompts (no regex support).\n"
50" Pressing the up/down keys highlights the previous/next\n"
51" matching item. Backspace removes one character from the\n"
52" match string. Pressing either '/' again or ESC exits\n"
53" search mode. All other keys behave normally.\n"
47"\n" 54"\n"
48" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" 55" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
49" unseen options into view.\n" 56" unseen options into view.\n"
@@ -141,21 +148,21 @@ menu_no_f_instructions[] = N_(
141" <Enter> or <right-arrow> selects submenus --->.\n" 148" <Enter> or <right-arrow> selects submenus --->.\n"
142" Capital Letters are hotkeys.\n" 149" Capital Letters are hotkeys.\n"
143" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 150" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
144" Pressing SpaceBar toggles between the above options\n" 151" Pressing SpaceBar toggles between the above options.\n"
145" Press <Esc> or <left-arrow> to go back one menu, \n" 152" Press <Esc> or <left-arrow> to go back one menu,\n"
146" <?> or <h> for Help, </> for Search.\n" 153" <?> or <h> for Help, </> for Search.\n"
147" <1> is interchangable with <F1>, <2> with <F2>, etc.\n" 154" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
148" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 155" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
149" <Esc> always leaves the current window\n"), 156" <Esc> always leaves the current window.\n"),
150menu_instructions[] = N_( 157menu_instructions[] = N_(
151" Arrow keys navigate the menu.\n" 158" Arrow keys navigate the menu.\n"
152" <Enter> or <right-arrow> selects submenus --->.\n" 159" <Enter> or <right-arrow> selects submenus --->.\n"
153" Capital Letters are hotkeys.\n" 160" Capital Letters are hotkeys.\n"
154" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 161" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
155" Pressing SpaceBar toggles between the above options\n" 162" Pressing SpaceBar toggles between the above options\n"
156" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n" 163" Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
157" <?>, <F1> or <h> for Help, </> for Search.\n" 164" <?>, <F1> or <h> for Help, </> for Search.\n"
158" <1> is interchangable with <F1>, <2> with <F2>, etc.\n" 165" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
159" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 166" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
160" <Esc> always leaves the current window\n"), 167" <Esc> always leaves the current window\n"),
161radiolist_instructions[] = N_( 168radiolist_instructions[] = N_(
@@ -252,7 +259,6 @@ struct mitem {
252 char str[256]; 259 char str[256];
253 char tag; 260 char tag;
254 void *usrptr; 261 void *usrptr;
255 int is_hot;
256 int is_visible; 262 int is_visible;
257}; 263};
258 264
@@ -275,14 +281,6 @@ static int items_num;
275static int global_exit; 281static int global_exit;
276/* the currently selected button */ 282/* the currently selected button */
277const char *current_instructions = menu_instructions; 283const char *current_instructions = menu_instructions;
278/* this array is used to implement hot keys. it is updated in item_make and
279 * resetted in clean_items. It would be better to use a hash, but lets keep it
280 * simple... */
281#define MAX_SAME_KEY MAX_MENU_ITEMS
282struct {
283 int count;
284 int ptrs[MAX_MENU_ITEMS];
285} hotkeys[1<<(sizeof(char)*8)];
286 284
287static void conf(struct menu *menu); 285static void conf(struct menu *menu);
288static void conf_choice(struct menu *menu); 286static void conf_choice(struct menu *menu);
@@ -292,6 +290,7 @@ static void conf_save(void);
292static void show_help(struct menu *menu); 290static void show_help(struct menu *menu);
293static int do_exit(void); 291static int do_exit(void);
294static void setup_windows(void); 292static void setup_windows(void);
293static void search_conf(void);
295 294
296typedef void (*function_key_handler_t)(int *key, struct menu *menu); 295typedef void (*function_key_handler_t)(int *key, struct menu *menu);
297static void handle_f1(int *key, struct menu *current_item); 296static void handle_f1(int *key, struct menu *current_item);
@@ -302,6 +301,7 @@ static void handle_f5(int *key, struct menu *current_item);
302static void handle_f6(int *key, struct menu *current_item); 301static void handle_f6(int *key, struct menu *current_item);
303static void handle_f7(int *key, struct menu *current_item); 302static void handle_f7(int *key, struct menu *current_item);
304static void handle_f8(int *key, struct menu *current_item); 303static void handle_f8(int *key, struct menu *current_item);
304static void handle_f9(int *key, struct menu *current_item);
305 305
306struct function_keys { 306struct function_keys {
307 const char *key_str; 307 const char *key_str;
@@ -310,7 +310,7 @@ struct function_keys {
310 function_key_handler_t handler; 310 function_key_handler_t handler;
311}; 311};
312 312
313static const int function_keys_num = 8; 313static const int function_keys_num = 9;
314struct function_keys function_keys[] = { 314struct function_keys function_keys[] = {
315 { 315 {
316 .key_str = "F1", 316 .key_str = "F1",
@@ -320,13 +320,13 @@ struct function_keys function_keys[] = {
320 }, 320 },
321 { 321 {
322 .key_str = "F2", 322 .key_str = "F2",
323 .func = "Symbol Info", 323 .func = "Sym Info",
324 .key = F_SYMBOL, 324 .key = F_SYMBOL,
325 .handler = handle_f2, 325 .handler = handle_f2,
326 }, 326 },
327 { 327 {
328 .key_str = "F3", 328 .key_str = "F3",
329 .func = "Instructions", 329 .func = "Insts",
330 .key = F_INSTS, 330 .key = F_INSTS,
331 .handler = handle_f3, 331 .handler = handle_f3,
332 }, 332 },
@@ -356,9 +356,15 @@ struct function_keys function_keys[] = {
356 }, 356 },
357 { 357 {
358 .key_str = "F8", 358 .key_str = "F8",
359 .func = "Sym Search",
360 .key = F_SEARCH,
361 .handler = handle_f8,
362 },
363 {
364 .key_str = "F9",
359 .func = "Exit", 365 .func = "Exit",
360 .key = F_EXIT, 366 .key = F_EXIT,
361 .handler = handle_f8, 367 .handler = handle_f9,
362 }, 368 },
363}; 369};
364 370
@@ -444,9 +450,16 @@ static void handle_f7(int *key, struct menu *current_item)
444 return; 450 return;
445} 451}
446 452
447/* exit */ 453/* search */
448static void handle_f8(int *key, struct menu *current_item) 454static void handle_f8(int *key, struct menu *current_item)
449{ 455{
456 search_conf();
457 return;
458}
459
460/* exit */
461static void handle_f9(int *key, struct menu *current_item)
462{
450 do_exit(); 463 do_exit();
451 return; 464 return;
452} 465}
@@ -479,110 +492,44 @@ static void clean_items(void)
479 free_item(curses_menu_items[i]); 492 free_item(curses_menu_items[i]);
480 bzero(curses_menu_items, sizeof(curses_menu_items)); 493 bzero(curses_menu_items, sizeof(curses_menu_items));
481 bzero(k_menu_items, sizeof(k_menu_items)); 494 bzero(k_menu_items, sizeof(k_menu_items));
482 bzero(hotkeys, sizeof(hotkeys));
483 items_num = 0; 495 items_num = 0;
484} 496}
485 497
486/* return the index of the next hot item, or -1 if no such item exists */ 498typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN,
487static int get_next_hot(int c) 499 FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f;
488{
489 static int hot_index;
490 static int hot_char;
491
492 if (c < 0 || c > 255 || hotkeys[c].count <= 0)
493 return -1;
494
495 if (hot_char == c) {
496 hot_index = (hot_index+1)%hotkeys[c].count;
497 return hotkeys[c].ptrs[hot_index];
498 } else {
499 hot_char = c;
500 hot_index = 0;
501 return hotkeys[c].ptrs[0];
502 }
503}
504
505/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
506static int canbhot(char c)
507{
508 c = tolower(c);
509 return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
510 c != 'n' && c != '?';
511}
512
513/* check if str already contains a hot key. */
514static int is_hot(int index)
515{
516 return k_menu_items[index].is_hot;
517}
518 500
519/* find the first possible hot key, and mark it. 501/* return the index of the matched item, or -1 if no such item exists */
520 * index is the index of the item in the menu 502static int get_mext_match(const char *match_str, match_f flag)
521 * return 0 on success*/
522static int make_hot(char *dest, int len, const char *org, int index)
523{ 503{
524 int position = -1; 504 int match_start = item_index(current_item(curses_menu));
525 int i; 505 int index;
526 int tmp; 506
527 int c; 507 if (flag == FIND_NEXT_MATCH_DOWN)
528 int org_len = strlen(org); 508 ++match_start;
529 509 else if (flag == FIND_NEXT_MATCH_UP)
530 if (org == NULL || is_hot(index)) 510 --match_start;
531 return 1; 511
532 512 index = match_start;
533 /* make sure not to make hot keys out of markers. 513 index = (index + items_num) % items_num;
534 * find where to start looking for a hot key 514 while (true) {
535 */ 515 char *str = k_menu_items[index].str;
536 i = 0; 516 if (strcasestr(str, match_str) != 0)
537 /* skip white space */ 517 return index;
538 while (i < org_len && org[i] == ' ') 518 if (flag == FIND_NEXT_MATCH_UP ||
539 i++; 519 flag == MATCH_TINKER_PATTERN_UP)
540 if (i == org_len) 520 --index;
541 return -1; 521 else
542 /* if encountering '(' or '<' or '[', find the match and look from there 522 ++index;
543 **/ 523 index = (index + items_num) % items_num;
544 if (org[i] == '[' || org[i] == '<' || org[i] == '(') { 524 if (index == match_start)
545 i++; 525 return -1;
546 for (; i < org_len; i++)
547 if (org[i] == ']' || org[i] == '>' || org[i] == ')')
548 break;
549 }
550 if (i == org_len)
551 return -1;
552 for (; i < org_len; i++) {
553 if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
554 position = i;
555 break;
556 }
557 } 526 }
558 if (position == -1)
559 return 1;
560
561 /* ok, char at org[position] should be a hot key to this item */
562 c = tolower(org[position]);
563 tmp = hotkeys[c].count;
564 hotkeys[c].ptrs[tmp] = index;
565 hotkeys[c].count++;
566 /*
567 snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
568 &org[position+1]);
569 */
570 /* make org[position] uppercase, and all leading letter small case */
571 strncpy(dest, org, len);
572 for (i = 0; i < position; i++)
573 dest[i] = tolower(dest[i]);
574 dest[position] = toupper(dest[position]);
575 k_menu_items[index].is_hot = 1;
576 return 0;
577} 527}
578 528
579/* Make a new item. Add a hotkey mark in the first possible letter. 529/* Make a new item. */
580 * As ncurses does not allow any attributes inside menue item, we mark the
581 * hot key as the first capitalized letter in the string */
582static void item_make(struct menu *menu, char tag, const char *fmt, ...) 530static void item_make(struct menu *menu, char tag, const char *fmt, ...)
583{ 531{
584 va_list ap; 532 va_list ap;
585 char tmp_str[256];
586 533
587 if (items_num > MAX_MENU_ITEMS-1) 534 if (items_num > MAX_MENU_ITEMS-1)
588 return; 535 return;
@@ -597,16 +544,13 @@ static void item_make(struct menu *menu, char tag, const char *fmt, ...)
597 k_menu_items[items_num].is_visible = 1; 544 k_menu_items[items_num].is_visible = 1;
598 545
599 va_start(ap, fmt); 546 va_start(ap, fmt);
600 vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); 547 vsnprintf(k_menu_items[items_num].str,
601 if (!k_menu_items[items_num].is_visible) 548 sizeof(k_menu_items[items_num].str),
602 memcpy(tmp_str, "XXX", 3); 549 fmt, ap);
603 va_end(ap); 550 va_end(ap);
604 if (make_hot( 551
605 k_menu_items[items_num].str, 552 if (!k_menu_items[items_num].is_visible)
606 sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) 553 memcpy(k_menu_items[items_num].str, "XXX", 3);
607 strncpy(k_menu_items[items_num].str,
608 tmp_str,
609 sizeof(k_menu_items[items_num].str));
610 554
611 curses_menu_items[items_num] = new_item( 555 curses_menu_items[items_num] = new_item(
612 k_menu_items[items_num].str, 556 k_menu_items[items_num].str,
@@ -638,11 +582,9 @@ static void item_add_str(const char *fmt, ...)
638 va_end(ap); 582 va_end(ap);
639 snprintf(tmp_str, sizeof(tmp_str), "%s%s", 583 snprintf(tmp_str, sizeof(tmp_str), "%s%s",
640 k_menu_items[index].str, new_str); 584 k_menu_items[index].str, new_str);
641 if (make_hot(k_menu_items[index].str, 585 strncpy(k_menu_items[index].str,
642 sizeof(k_menu_items[index].str), tmp_str, index) != 0) 586 tmp_str,
643 strncpy(k_menu_items[index].str, 587 sizeof(k_menu_items[index].str));
644 tmp_str,
645 sizeof(k_menu_items[index].str));
646 588
647 free_item(curses_menu_items[index]); 589 free_item(curses_menu_items[index]);
648 curses_menu_items[index] = new_item( 590 curses_menu_items[index] = new_item(
@@ -1027,23 +969,18 @@ static void reset_menu(void)
1027static void center_item(int selected_index, int *last_top_row) 969static void center_item(int selected_index, int *last_top_row)
1028{ 970{
1029 int toprow; 971 int toprow;
1030 int maxy, maxx;
1031 972
1032 scale_menu(curses_menu, &maxy, &maxx);
1033 set_top_row(curses_menu, *last_top_row); 973 set_top_row(curses_menu, *last_top_row);
1034 toprow = top_row(curses_menu); 974 toprow = top_row(curses_menu);
1035 if (selected_index >= toprow && selected_index < toprow+maxy) { 975 if (selected_index < toprow ||
1036 /* we can only move the selected item. no need to scroll */ 976 selected_index >= toprow+mwin_max_lines) {
1037 set_current_item(curses_menu, 977 toprow = max(selected_index-mwin_max_lines/2, 0);
1038 curses_menu_items[selected_index]); 978 if (toprow >= item_count(curses_menu)-mwin_max_lines)
1039 } else {
1040 toprow = max(selected_index-maxy/2, 0);
1041 if (toprow >= item_count(curses_menu)-maxy)
1042 toprow = item_count(curses_menu)-mwin_max_lines; 979 toprow = item_count(curses_menu)-mwin_max_lines;
1043 set_top_row(curses_menu, toprow); 980 set_top_row(curses_menu, toprow);
1044 set_current_item(curses_menu,
1045 curses_menu_items[selected_index]);
1046 } 981 }
982 set_current_item(curses_menu,
983 curses_menu_items[selected_index]);
1047 *last_top_row = toprow; 984 *last_top_row = toprow;
1048 post_menu(curses_menu); 985 post_menu(curses_menu);
1049 refresh_all_windows(main_window); 986 refresh_all_windows(main_window);
@@ -1075,7 +1012,7 @@ static void show_menu(const char *prompt, const char *instructions,
1075 /* position the menu at the middle of the screen */ 1012 /* position the menu at the middle of the screen */
1076 scale_menu(curses_menu, &maxy, &maxx); 1013 scale_menu(curses_menu, &maxy, &maxx);
1077 maxx = min(maxx, mwin_max_cols-2); 1014 maxx = min(maxx, mwin_max_cols-2);
1078 maxy = mwin_max_lines-2; 1015 maxy = mwin_max_lines;
1079 menu_window = derwin(main_window, 1016 menu_window = derwin(main_window,
1080 maxy, 1017 maxy,
1081 maxx, 1018 maxx,
@@ -1099,10 +1036,77 @@ static void show_menu(const char *prompt, const char *instructions,
1099 refresh_all_windows(main_window); 1036 refresh_all_windows(main_window);
1100} 1037}
1101 1038
1039static void adj_match_dir(match_f *match_direction)
1040{
1041 if (*match_direction == FIND_NEXT_MATCH_DOWN)
1042 *match_direction =
1043 MATCH_TINKER_PATTERN_DOWN;
1044 else if (*match_direction == FIND_NEXT_MATCH_UP)
1045 *match_direction =
1046 MATCH_TINKER_PATTERN_UP;
1047 /* else, do no change.. */
1048}
1102 1049
1103static void conf(struct menu *menu) 1050struct match_state
1104{ 1051{
1052 int in_search;
1053 match_f match_direction;
1105 char pattern[256]; 1054 char pattern[256];
1055};
1056
1057/* Return 0 means I have handled the key. In such a case, ans should hold the
1058 * item to center, or -1 otherwise.
1059 * Else return -1 .
1060 */
1061static int do_match(int key, struct match_state *state, int *ans)
1062{
1063 char c = (char) key;
1064 int terminate_search = 0;
1065 *ans = -1;
1066 if (key == '/' || (state->in_search && key == 27)) {
1067 move(0, 0);
1068 refresh();
1069 clrtoeol();
1070 state->in_search = 1-state->in_search;
1071 bzero(state->pattern, sizeof(state->pattern));
1072 state->match_direction = MATCH_TINKER_PATTERN_DOWN;
1073 return 0;
1074 } else if (!state->in_search)
1075 return 1;
1076
1077 if (isalnum(c) || isgraph(c) || c == ' ') {
1078 state->pattern[strlen(state->pattern)] = c;
1079 state->pattern[strlen(state->pattern)] = '\0';
1080 adj_match_dir(&state->match_direction);
1081 *ans = get_mext_match(state->pattern,
1082 state->match_direction);
1083 } else if (key == KEY_DOWN) {
1084 state->match_direction = FIND_NEXT_MATCH_DOWN;
1085 *ans = get_mext_match(state->pattern,
1086 state->match_direction);
1087 } else if (key == KEY_UP) {
1088 state->match_direction = FIND_NEXT_MATCH_UP;
1089 *ans = get_mext_match(state->pattern,
1090 state->match_direction);
1091 } else if (key == KEY_BACKSPACE || key == 127) {
1092 state->pattern[strlen(state->pattern)-1] = '\0';
1093 adj_match_dir(&state->match_direction);
1094 } else
1095 terminate_search = 1;
1096
1097 if (terminate_search) {
1098 state->in_search = 0;
1099 bzero(state->pattern, sizeof(state->pattern));
1100 move(0, 0);
1101 refresh();
1102 clrtoeol();
1103 return -1;
1104 }
1105 return 0;
1106}
1107
1108static void conf(struct menu *menu)
1109{
1106 struct menu *submenu = 0; 1110 struct menu *submenu = 0;
1107 const char *prompt = menu_get_prompt(menu); 1111 const char *prompt = menu_get_prompt(menu);
1108 struct symbol *sym; 1112 struct symbol *sym;
@@ -1110,8 +1114,11 @@ static void conf(struct menu *menu)
1110 int res; 1114 int res;
1111 int current_index = 0; 1115 int current_index = 0;
1112 int last_top_row = 0; 1116 int last_top_row = 0;
1113 1117 struct match_state match_state = {
1114 bzero(pattern, sizeof(pattern)); 1118 .in_search = 0,
1119 .match_direction = MATCH_TINKER_PATTERN_DOWN,
1120 .pattern = "",
1121 };
1115 1122
1116 while (!global_exit) { 1123 while (!global_exit) {
1117 reset_menu(); 1124 reset_menu();
@@ -1124,7 +1131,22 @@ static void conf(struct menu *menu)
1124 _(menu_instructions), 1131 _(menu_instructions),
1125 current_index, &last_top_row); 1132 current_index, &last_top_row);
1126 keypad((menu_win(curses_menu)), TRUE); 1133 keypad((menu_win(curses_menu)), TRUE);
1127 while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { 1134 while (!global_exit) {
1135 if (match_state.in_search) {
1136 mvprintw(0, 0,
1137 "searching: %s", match_state.pattern);
1138 clrtoeol();
1139 }
1140 refresh_all_windows(main_window);
1141 res = wgetch(menu_win(curses_menu));
1142 if (!res)
1143 break;
1144 if (do_match(res, &match_state, &current_index) == 0) {
1145 if (current_index != -1)
1146 center_item(current_index,
1147 &last_top_row);
1148 continue;
1149 }
1128 if (process_special_keys(&res, 1150 if (process_special_keys(&res,
1129 (struct menu *) item_data())) 1151 (struct menu *) item_data()))
1130 break; 1152 break;
@@ -1155,19 +1177,13 @@ static void conf(struct menu *menu)
1155 if (res == 10 || res == 27 || 1177 if (res == 10 || res == 27 ||
1156 res == 32 || res == 'n' || res == 'y' || 1178 res == 32 || res == 'n' || res == 'y' ||
1157 res == KEY_LEFT || res == KEY_RIGHT || 1179 res == KEY_LEFT || res == KEY_RIGHT ||
1158 res == 'm' || res == '/') 1180 res == 'm')
1159 break; 1181 break;
1160 else if (canbhot(res)) {
1161 /* check for hot keys: */
1162 int tmp = get_next_hot(res);
1163 if (tmp != -1)
1164 center_item(tmp, &last_top_row);
1165 }
1166 refresh_all_windows(main_window); 1182 refresh_all_windows(main_window);
1167 } 1183 }
1168 1184
1169 refresh_all_windows(main_window); 1185 refresh_all_windows(main_window);
1170 /* if ESC or left*/ 1186 /* if ESC or left*/
1171 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) 1187 if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
1172 break; 1188 break;
1173 1189
@@ -1235,9 +1251,6 @@ static void conf(struct menu *menu)
1235 if (item_is_tag('t')) 1251 if (item_is_tag('t'))
1236 sym_set_tristate_value(sym, mod); 1252 sym_set_tristate_value(sym, mod);
1237 break; 1253 break;
1238 case '/':
1239 search_conf();
1240 break;
1241 } 1254 }
1242 } 1255 }
1243} 1256}
@@ -1268,6 +1281,11 @@ static void conf_choice(struct menu *menu)
1268 int selected_index = 0; 1281 int selected_index = 0;
1269 int last_top_row = 0; 1282 int last_top_row = 0;
1270 int res, i = 0; 1283 int res, i = 0;
1284 struct match_state match_state = {
1285 .in_search = 0,
1286 .match_direction = MATCH_TINKER_PATTERN_DOWN,
1287 .pattern = "",
1288 };
1271 1289
1272 active = sym_get_choice_value(menu->sym); 1290 active = sym_get_choice_value(menu->sym);
1273 /* this is mostly duplicated from the conf() function. */ 1291 /* this is mostly duplicated from the conf() function. */
@@ -1294,7 +1312,22 @@ static void conf_choice(struct menu *menu)
1294 _(radiolist_instructions), 1312 _(radiolist_instructions),
1295 selected_index, 1313 selected_index,
1296 &last_top_row); 1314 &last_top_row);
1297 while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { 1315 while (!global_exit) {
1316 if (match_state.in_search) {
1317 mvprintw(0, 0, "searching: %s",
1318 match_state.pattern);
1319 clrtoeol();
1320 }
1321 refresh_all_windows(main_window);
1322 res = wgetch(menu_win(curses_menu));
1323 if (!res)
1324 break;
1325 if (do_match(res, &match_state, &selected_index) == 0) {
1326 if (selected_index != -1)
1327 center_item(selected_index,
1328 &last_top_row);
1329 continue;
1330 }
1298 if (process_special_keys( 1331 if (process_special_keys(
1299 &res, 1332 &res,
1300 (struct menu *) item_data())) 1333 (struct menu *) item_data()))
@@ -1324,13 +1357,8 @@ static void conf_choice(struct menu *menu)
1324 break; 1357 break;
1325 } 1358 }
1326 if (res == 10 || res == 27 || res == ' ' || 1359 if (res == 10 || res == 27 || res == ' ' ||
1327 res == KEY_LEFT) 1360 res == KEY_LEFT){
1328 break; 1361 break;
1329 else if (canbhot(res)) {
1330 /* check for hot keys: */
1331 int tmp = get_next_hot(res);
1332 if (tmp != -1)
1333 center_item(tmp, &last_top_row);
1334 } 1362 }
1335 refresh_all_windows(main_window); 1363 refresh_all_windows(main_window);
1336 } 1364 }
@@ -1485,7 +1513,7 @@ void setup_windows(void)
1485 /* set up the menu and menu window */ 1513 /* set up the menu and menu window */
1486 main_window = newwin(LINES-2, COLS-2, 2, 1); 1514 main_window = newwin(LINES-2, COLS-2, 2, 1);
1487 keypad(main_window, TRUE); 1515 keypad(main_window, TRUE);
1488 mwin_max_lines = LINES-6; 1516 mwin_max_lines = LINES-7;
1489 mwin_max_cols = COLS-6; 1517 mwin_max_cols = COLS-6;
1490 1518
1491 /* panels order is from bottom to top */ 1519 /* panels order is from bottom to top */
@@ -1532,9 +1560,10 @@ int main(int ac, char **av)
1532 /* set btns menu */ 1560 /* set btns menu */
1533 curses_menu = new_menu(curses_menu_items); 1561 curses_menu = new_menu(curses_menu_items);
1534 menu_opts_off(curses_menu, O_SHOWDESC); 1562 menu_opts_off(curses_menu, O_SHOWDESC);
1535 menu_opts_off(curses_menu, O_SHOWMATCH); 1563 menu_opts_on(curses_menu, O_SHOWMATCH);
1536 menu_opts_on(curses_menu, O_ONEVALUE); 1564 menu_opts_on(curses_menu, O_ONEVALUE);
1537 menu_opts_on(curses_menu, O_NONCYCLIC); 1565 menu_opts_on(curses_menu, O_NONCYCLIC);
1566 menu_opts_on(curses_menu, O_IGNORECASE);
1538 set_menu_mark(curses_menu, " "); 1567 set_menu_mark(curses_menu, " ");
1539 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); 1568 set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
1540 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); 1569 set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
@@ -1550,8 +1579,6 @@ int main(int ac, char **av)
1550 _(menu_no_f_instructions)); 1579 _(menu_no_f_instructions));
1551 } 1580 }
1552 1581
1553
1554
1555 /* do the work */ 1582 /* do the work */
1556 while (!global_exit) { 1583 while (!global_exit) {
1557 conf(&rootmenu); 1584 conf(&rootmenu);
diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
index a9d9344e1365..d963071e48df 100644
--- a/scripts/kconfig/nconf.gui.c
+++ b/scripts/kconfig/nconf.gui.c
@@ -167,7 +167,7 @@ void print_in_middle(WINDOW *win,
167 length = strlen(string); 167 length = strlen(string);
168 temp = (width - length) / 2; 168 temp = (width - length) / 2;
169 x = startx + (int)temp; 169 x = startx + (int)temp;
170 wattrset(win, color); 170 (void) wattrset(win, color);
171 mvwprintw(win, y, x, "%s", string); 171 mvwprintw(win, y, x, "%s", string);
172 refresh(); 172 refresh();
173} 173}
@@ -297,11 +297,11 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
297 set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); 297 set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
298 set_menu_back(menu, attributes[DIALOG_MENU_BACK]); 298 set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
299 299
300 wattrset(win, attributes[DIALOG_BOX]); 300 (void) wattrset(win, attributes[DIALOG_BOX]);
301 box(win, 0, 0); 301 box(win, 0, 0);
302 302
303 /* print message */ 303 /* print message */
304 wattrset(msg_win, attributes[DIALOG_TEXT]); 304 (void) wattrset(msg_win, attributes[DIALOG_TEXT]);
305 fill_window(msg_win, msg); 305 fill_window(msg_win, msg);
306 306
307 set_menu_win(menu, win); 307 set_menu_win(menu, win);
@@ -392,16 +392,16 @@ int dialog_inputbox(WINDOW *main_window,
392 form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); 392 form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
393 keypad(form_win, TRUE); 393 keypad(form_win, TRUE);
394 394
395 wattrset(form_win, attributes[INPUT_FIELD]); 395 (void) wattrset(form_win, attributes[INPUT_FIELD]);
396 396
397 wattrset(win, attributes[INPUT_BOX]); 397 (void) wattrset(win, attributes[INPUT_BOX]);
398 box(win, 0, 0); 398 box(win, 0, 0);
399 wattrset(win, attributes[INPUT_HEADING]); 399 (void) wattrset(win, attributes[INPUT_HEADING]);
400 if (title) 400 if (title)
401 mvwprintw(win, 0, 3, "%s", title); 401 mvwprintw(win, 0, 3, "%s", title);
402 402
403 /* print message */ 403 /* print message */
404 wattrset(prompt_win, attributes[INPUT_TEXT]); 404 (void) wattrset(prompt_win, attributes[INPUT_TEXT]);
405 fill_window(prompt_win, prompt); 405 fill_window(prompt_win, prompt);
406 406
407 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); 407 mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
@@ -531,7 +531,7 @@ void show_scroll_win(WINDOW *main_window,
531 531
532 /* create the pad */ 532 /* create the pad */
533 pad = newpad(total_lines+10, total_cols+10); 533 pad = newpad(total_lines+10, total_cols+10);
534 wattrset(pad, attributes[SCROLLWIN_TEXT]); 534 (void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
535 fill_window(pad, text); 535 fill_window(pad, text);
536 536
537 win_lines = min(total_lines+4, LINES-2); 537 win_lines = min(total_lines+4, LINES-2);
@@ -546,9 +546,9 @@ void show_scroll_win(WINDOW *main_window,
546 win = newwin(win_lines, win_cols, y, x); 546 win = newwin(win_lines, win_cols, y, x);
547 keypad(win, TRUE); 547 keypad(win, TRUE);
548 /* show the help in the help window, and show the help panel */ 548 /* show the help in the help window, and show the help panel */
549 wattrset(win, attributes[SCROLLWIN_BOX]); 549 (void) wattrset(win, attributes[SCROLLWIN_BOX]);
550 box(win, 0, 0); 550 box(win, 0, 0);
551 wattrset(win, attributes[SCROLLWIN_HEADING]); 551 (void) wattrset(win, attributes[SCROLLWIN_HEADING]);
552 mvwprintw(win, 0, 3, " %s ", title); 552 mvwprintw(win, 0, 3, " %s ", title);
553 panel = new_panel(win); 553 panel = new_panel(win);
554 554
diff --git a/scripts/kconfig/nconf.h b/scripts/kconfig/nconf.h
index fb4296666004..58fbda8fc0dc 100644
--- a/scripts/kconfig/nconf.h
+++ b/scripts/kconfig/nconf.h
@@ -69,7 +69,8 @@ typedef enum {
69 F_BACK = 5, 69 F_BACK = 5,
70 F_SAVE = 6, 70 F_SAVE = 6,
71 F_LOAD = 7, 71 F_LOAD = 7,
72 F_EXIT = 8 72 F_SEARCH = 8,
73 F_EXIT = 9,
73} function_key; 74} function_key;
74 75
75void set_colors(void); 76void set_colors(void);