diff options
author | Nir Tzachar <nir.tzachar@gmail.com> | 2010-08-08 09:50:06 -0400 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2010-08-16 16:04:55 -0400 |
commit | a72f3e2b82eb26f43bed1f83beeeb47830918811 (patch) | |
tree | 0735c997af4315ad5bea95a9b1d8acaaf5b557aa | |
parent | 3643f849d7da5c12da589beb03c12303fe79b841 (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.c | 365 | ||||
-rw-r--r-- | scripts/kconfig/nconf.gui.c | 20 | ||||
-rw-r--r-- | scripts/kconfig/nconf.h | 3 |
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 | ||
12 | static const char nconf_readme[] = N_( | 15 | static 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"), |
150 | menu_instructions[] = N_( | 157 | menu_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"), |
161 | radiolist_instructions[] = N_( | 168 | radiolist_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; | |||
275 | static int global_exit; | 281 | static int global_exit; |
276 | /* the currently selected button */ | 282 | /* the currently selected button */ |
277 | const char *current_instructions = menu_instructions; | 283 | const 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 | ||
282 | struct { | ||
283 | int count; | ||
284 | int ptrs[MAX_MENU_ITEMS]; | ||
285 | } hotkeys[1<<(sizeof(char)*8)]; | ||
286 | 284 | ||
287 | static void conf(struct menu *menu); | 285 | static void conf(struct menu *menu); |
288 | static void conf_choice(struct menu *menu); | 286 | static void conf_choice(struct menu *menu); |
@@ -292,6 +290,7 @@ static void conf_save(void); | |||
292 | static void show_help(struct menu *menu); | 290 | static void show_help(struct menu *menu); |
293 | static int do_exit(void); | 291 | static int do_exit(void); |
294 | static void setup_windows(void); | 292 | static void setup_windows(void); |
293 | static void search_conf(void); | ||
295 | 294 | ||
296 | typedef void (*function_key_handler_t)(int *key, struct menu *menu); | 295 | typedef void (*function_key_handler_t)(int *key, struct menu *menu); |
297 | static void handle_f1(int *key, struct menu *current_item); | 296 | static void handle_f1(int *key, struct menu *current_item); |
@@ -302,6 +301,7 @@ static void handle_f5(int *key, struct menu *current_item); | |||
302 | static void handle_f6(int *key, struct menu *current_item); | 301 | static void handle_f6(int *key, struct menu *current_item); |
303 | static void handle_f7(int *key, struct menu *current_item); | 302 | static void handle_f7(int *key, struct menu *current_item); |
304 | static void handle_f8(int *key, struct menu *current_item); | 303 | static void handle_f8(int *key, struct menu *current_item); |
304 | static void handle_f9(int *key, struct menu *current_item); | ||
305 | 305 | ||
306 | struct function_keys { | 306 | struct 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 | ||
313 | static const int function_keys_num = 8; | 313 | static const int function_keys_num = 9; |
314 | struct function_keys function_keys[] = { | 314 | struct 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 */ |
448 | static void handle_f8(int *key, struct menu *current_item) | 454 | static void handle_f8(int *key, struct menu *current_item) |
449 | { | 455 | { |
456 | search_conf(); | ||
457 | return; | ||
458 | } | ||
459 | |||
460 | /* exit */ | ||
461 | static 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 */ | 498 | typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, |
487 | static 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 */ | ||
506 | static 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. */ | ||
514 | static 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 | 502 | static int get_mext_match(const char *match_str, match_f flag) |
521 | * return 0 on success*/ | ||
522 | static 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 */ | ||
582 | static void item_make(struct menu *menu, char tag, const char *fmt, ...) | 530 | static 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) | |||
1027 | static void center_item(int selected_index, int *last_top_row) | 969 | static 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 | ||
1039 | static 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 | ||
1103 | static void conf(struct menu *menu) | 1050 | struct 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 | */ | ||
1061 | static 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 | |||
1108 | static 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, ¤t_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 | ||
75 | void set_colors(void); | 76 | void set_colors(void); |