* [PATCH 2/6] menuconfig: Extend dialog_textbox so that it can exit on arbitrary keypresses
2012-07-30 19:22 [PATCH 0/6] menuconfig: jump to search results Benjamin Poirier
2012-07-30 19:22 ` [PATCH 1/6] menuconfig: Remove superfluous conditionnal Benjamin Poirier
@ 2012-07-30 19:22 ` Benjamin Poirier
2012-07-30 19:22 ` [PATCH 3/6] menuconfig: Extend dialog_textbox so that it can return to a scrolled position Benjamin Poirier
` (4 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Benjamin Poirier @ 2012-07-30 19:22 UTC (permalink / raw)
To: Michal Marek
Cc: Lucas De Marchi, Arnaud Lacombe, linux-kbuild, linux-kernel,
Randy Dunlap
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
scripts/kconfig/lxdialog/dialog.h | 3 ++-
scripts/kconfig/lxdialog/textbox.c | 31 +++++++++++++++++++++----------
scripts/kconfig/mconf.c | 12 ++++++++++--
3 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index b5211fc..014c029 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -209,7 +209,8 @@ int first_alpha(const char *string, const char *exempt);
int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
-int dialog_textbox(const char *title, const char *file, int height, int width);
+int dialog_textbox(const char *title, const char *file, int height, int width,
+ int *keys);
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 264a2b9..eb4ee92 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -47,14 +47,16 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
/*
* Display text from a file in a dialog box.
+ *
+ * keys is a null-terminated array
*/
-int dialog_textbox(const char *title, const char *tbuf,
- int initial_height, int initial_width)
+int dialog_textbox(const char *title, const char *tbuf, int initial_height,
+ int initial_width, int *keys)
{
int i, x, y, cur_x, cur_y, key = 0;
int height, width, boxh, boxw;
- int passed_end;
WINDOW *dialog, *box;
+ bool done = false;
begin_reached = 1;
end_reached = 0;
@@ -122,7 +124,7 @@ do_resize:
attr_clear(box, boxh, boxw, dlg.dialog.atr);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
- while ((key != KEY_ESC) && (key != '\n')) {
+ while (!done) {
key = wgetch(dialog);
switch (key) {
case 'E': /* Exit */
@@ -130,9 +132,9 @@ do_resize:
case 'X':
case 'x':
case 'q':
- delwin(box);
- delwin(dialog);
- return 0;
+ case '\n':
+ done = true;
+ break;
case 'g': /* First page */
case KEY_HOME:
if (!begin_reached) {
@@ -156,6 +158,8 @@ do_resize:
case 'k':
case KEY_UP:
if (!begin_reached) {
+ int passed_end = 0;
+
back_lines(page_length + 1);
/* We don't call print_page() here but use
@@ -169,7 +173,6 @@ do_resize:
wscrl(box, -1); /* Scroll box region down one line */
scrollok(box, FALSE);
page_length = 0;
- passed_end = 0;
for (i = 0; i < boxh; i++) {
if (!i) {
/* print first line of page */
@@ -252,7 +255,8 @@ do_resize:
cur_y, cur_x);
break;
case KEY_ESC:
- key = on_key_esc(dialog);
+ if (on_key_esc(dialog) == KEY_ESC)
+ done = true;
break;
case KEY_RESIZE:
back_lines(height);
@@ -260,11 +264,18 @@ do_resize:
delwin(dialog);
on_key_resize();
goto do_resize;
+ default:
+ for (i = 0; keys[i]; i++) {
+ if (key == keys[i]) {
+ done = true;
+ break;
+ }
+ }
}
}
delwin(box);
delwin(dialog);
- return key; /* ESC pressed */
+ return key;
}
/*
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index f584a28..116e5da 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -280,6 +280,8 @@ static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
static void conf_load(void);
static void conf_save(void);
+static int show_textbox_ext(const char *title, const char *text, int r, int c,
+ int *keys);
static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu);
@@ -619,10 +621,16 @@ static void conf(struct menu *menu)
}
}
-static void show_textbox(const char *title, const char *text, int r, int c)
+static int show_textbox_ext(const char *title, const char *text, int r, int c,
+ int *keys)
{
dialog_clear();
- dialog_textbox(title, text, r, c);
+ return dialog_textbox(title, text, r, c, keys);
+}
+
+static void show_textbox(const char *title, const char *text, int r, int c)
+{
+ show_textbox_ext(title, text, r, c, (int []) {0});
}
static void show_helptext(const char *title, const char *text)
--
1.7.7
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/6] menuconfig: Extend dialog_textbox so that it can return to a scrolled position
2012-07-30 19:22 [PATCH 0/6] menuconfig: jump to search results Benjamin Poirier
2012-07-30 19:22 ` [PATCH 1/6] menuconfig: Remove superfluous conditionnal Benjamin Poirier
2012-07-30 19:22 ` [PATCH 2/6] menuconfig: Extend dialog_textbox so that it can exit on arbitrary keypresses Benjamin Poirier
@ 2012-07-30 19:22 ` Benjamin Poirier
2012-07-30 19:22 ` [PATCH 4/6] menuconfig: Add jump keys to search results Benjamin Poirier
` (3 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Benjamin Poirier @ 2012-07-30 19:22 UTC (permalink / raw)
To: Michal Marek
Cc: Lucas De Marchi, Arnaud Lacombe, linux-kbuild, linux-kernel,
Randy Dunlap
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
scripts/kconfig/lxdialog/dialog.h | 2 +-
scripts/kconfig/lxdialog/textbox.c | 24 +++++++++++++++++++++++-
scripts/kconfig/mconf.c | 8 ++++----
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index 014c029..8e7f43b 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -210,7 +210,7 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
int dialog_textbox(const char *title, const char *file, int height, int width,
- int *keys);
+ int *keys, int *_vscroll, int *_hscroll);
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index eb4ee92..506a095 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -51,7 +51,7 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
* keys is a null-terminated array
*/
int dialog_textbox(const char *title, const char *tbuf, int initial_height,
- int initial_width, int *keys)
+ int initial_width, int *keys, int *_vscroll, int *_hscroll)
{
int i, x, y, cur_x, cur_y, key = 0;
int height, width, boxh, boxw;
@@ -65,6 +65,15 @@ int dialog_textbox(const char *title, const char *tbuf, int initial_height,
buf = tbuf;
page = buf; /* page is pointer to start of page to be displayed */
+ if (_vscroll && *_vscroll) {
+ begin_reached = 0;
+
+ for (i = 0; i < *_vscroll; i++)
+ get_line();
+ }
+ if (_hscroll)
+ hscroll = *_hscroll;
+
do_resize:
getmaxyx(stdscr, height, width);
if (height < 8 || width < 8)
@@ -275,6 +284,19 @@ do_resize:
}
delwin(box);
delwin(dialog);
+ if (_vscroll) {
+ const char *s;
+
+ s = buf;
+ *_vscroll = 0;
+ back_lines(page_length);
+ while (s < page && (s = strchr(s, '\n'))) {
+ (*_vscroll)++;
+ s++;
+ }
+ }
+ if (_hscroll)
+ *_hscroll = hscroll;
return key;
}
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 116e5da..c57cc6a 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -281,7 +281,7 @@ static void conf_string(struct menu *menu);
static void conf_load(void);
static void conf_save(void);
static int show_textbox_ext(const char *title, const char *text, int r, int c,
- int *keys);
+ int *keys, int *vscroll, int *hscroll);
static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu);
@@ -622,15 +622,15 @@ static void conf(struct menu *menu)
}
static int show_textbox_ext(const char *title, const char *text, int r, int c,
- int *keys)
+ int *keys, int *vscroll, int *hscroll)
{
dialog_clear();
- return dialog_textbox(title, text, r, c, keys);
+ return dialog_textbox(title, text, r, c, keys, vscroll, hscroll);
}
static void show_textbox(const char *title, const char *text, int r, int c)
{
- show_textbox_ext(title, text, r, c, (int []) {0});
+ show_textbox_ext(title, text, r, c, (int []) {0}, NULL, NULL);
}
static void show_helptext(const char *title, const char *text)
--
1.7.7
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/6] menuconfig: Add jump keys to search results
2012-07-30 19:22 [PATCH 0/6] menuconfig: jump to search results Benjamin Poirier
` (2 preceding siblings ...)
2012-07-30 19:22 ` [PATCH 3/6] menuconfig: Extend dialog_textbox so that it can return to a scrolled position Benjamin Poirier
@ 2012-07-30 19:22 ` Benjamin Poirier
2012-07-30 19:22 ` [PATCH 5/6] menuconfig: Do not open code textbox scroll up/down Benjamin Poirier
` (2 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Benjamin Poirier @ 2012-07-30 19:22 UTC (permalink / raw)
To: Michal Marek
Cc: Lucas De Marchi, Arnaud Lacombe, linux-kbuild, linux-kernel,
Randy Dunlap
makes it possible to jump directly to the menu for a configuration entry after
having searched for it with '/'. If this menu is not currently accessible we
jump to the nearest accessible parent instead. After exiting this menu, the
user is returned to the search results where he may jump further in or
elsewhere.
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
scripts/kconfig/expr.h | 2 +
scripts/kconfig/lkc_proto.h | 6 +++-
scripts/kconfig/mconf.c | 64 +++++++++++++++++++++++++++++--------------
| 55 +++++++++++++++++++++++++++++-------
scripts/kconfig/nconf.c | 2 +-
5 files changed, 94 insertions(+), 35 deletions(-)
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index d4ecce8..52f4246 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -173,6 +173,8 @@ struct menu {
#define MENU_CHANGED 0x0001
#define MENU_ROOT 0x0002
+#define JUMP_NB 9
+
extern struct file *file_list;
extern struct file *current_file;
struct file *lookup_file(const char *name);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 47fe9c3..946c2cb3 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -21,8 +21,10 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
P(menu_has_help,bool,(struct menu *menu));
P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
-P(get_relations_str, struct gstr, (struct symbol **sym_arr));
+P(get_symbol_str, int, (struct gstr *r, struct symbol *sym, struct menu
+ **jumps, int jump_nb));
+P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct menu
+ **jumps));
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
/* symbol.c */
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index c57cc6a..bf75753 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -236,16 +236,19 @@ search_help[] = N_(
"Result:\n"
"-----------------------------------------------------------------\n"
"Symbol: FOO [=m]\n"
+ "Type : tristate\n"
"Prompt: Foo bus is used to drive the bar HW\n"
- "Defined at drivers/pci/Kconfig:47\n"
- "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
- "Location:\n"
- " -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
- " -> PCI support (PCI [=y])\n"
- " -> PCI access mode (<choice> [=y])\n"
- "Selects: LIBCRC32\n"
- "Selected by: BAR\n"
+ " Defined at drivers/pci/Kconfig:47\n"
+ " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+ " Location:\n"
+ " -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
+ " -> PCI support (PCI [=y])\n"
+ "(1) -> PCI access mode (<choice> [=y])\n"
+ " Selects: LIBCRC32\n"
+ " Selected by: BAR\n"
"-----------------------------------------------------------------\n"
+ "o The line 'Type:' shows the type of the configuration option for\n"
+ " this symbol (boolean, tristate, string, ...)\n"
"o The line 'Prompt:' shows the text used in the menu structure for\n"
" this symbol\n"
"o The 'Defined at' line tell at what file / line number the symbol\n"
@@ -254,8 +257,12 @@ search_help[] = N_(
" this symbol to be visible in the menu (selectable)\n"
"o The 'Location:' lines tell where in the menu structure this symbol\n"
" is located\n"
- " A location followed by a [=y] indicate that this is a selectable\n"
- " menu item - and current value is displayed inside brackets.\n"
+ " A location followed by a [=y] indicates that this is a\n"
+ " selectable menu item - and the current value is displayed inside\n"
+ " brackets.\n"
+ " Press the key in the (#) prefix to jump directly to that\n"
+ " location. You will be returned to the current search results\n"
+ " after exiting this new menu\n"
"o The 'Selects:' line tell what symbol will be automatically\n"
" selected if this symbol is selected (y or m)\n"
"o The 'Selected by' line tell what symbol has selected this symbol\n"
@@ -275,7 +282,7 @@ static int single_menu_mode;
static int show_all_options;
static int saved_x, saved_y;
-static void conf(struct menu *menu);
+static void conf(struct menu *menu, struct menu *active_menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
static void conf_load(void);
@@ -309,7 +316,9 @@ static void search_conf(void)
struct symbol **sym_arr;
struct gstr res;
char *dialog_input;
- int dres;
+ int dres, vscroll = 0, hscroll = 0;
+ bool again;
+
again:
dialog_clear();
dres = dialog_inputbox(_("Search Configuration Parameter"),
@@ -332,10 +341,24 @@ again:
dialog_input += strlen(CONFIG_);
sym_arr = sym_re_search(dialog_input);
- res = get_relations_str(sym_arr);
+ do {
+ struct menu *jumps[JUMP_NB] = {0};
+ int keys[JUMP_NB + 1] = {0}, i;
+
+ res = get_relations_str(sym_arr, jumps);
+ for (i = 0; i < JUMP_NB && jumps[i]; i++)
+ keys[i] = '1' + i;
+ dres = show_textbox_ext(_("Search Results"), str_get(&res), 0,
+ 0, keys, &vscroll, &hscroll);
+ again = false;
+ for (i = 0; i < JUMP_NB && jumps[i]; i++)
+ if (dres == keys[i]) {
+ conf(jumps[i]->parent, jumps[i]);
+ again = true;
+ }
+ str_free(&res);
+ } while (again);
free(sym_arr);
- show_textbox(_("Search Results"), str_get(&res), 0, 0);
- str_free(&res);
}
static void build_conf(struct menu *menu)
@@ -516,12 +539,11 @@ conf_childs:
indent -= doint;
}
-static void conf(struct menu *menu)
+static void conf(struct menu *menu, struct menu *active_menu)
{
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
- struct menu *active_menu = NULL;
int res;
int s_scroll = 0;
@@ -564,13 +586,13 @@ static void conf(struct menu *menu)
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
else
- conf(submenu);
+ conf(submenu, NULL);
break;
case 't':
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
else if (submenu->prompt->type == P_MENU)
- conf(submenu);
+ conf(submenu, NULL);
break;
case 's':
conf_string(submenu);
@@ -609,7 +631,7 @@ static void conf(struct menu *menu)
if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
else if (item_is_tag('m'))
- conf(submenu);
+ conf(submenu, NULL);
break;
case 7:
search_conf();
@@ -881,7 +903,7 @@ int main(int ac, char **av)
set_config_filename(conf_get_configname());
do {
- conf(&rootmenu);
+ conf(&rootmenu, NULL);
res = handle_exit();
} while (res == KEY_ESC);
--git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 8c2a97e..a524185 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -507,10 +507,12 @@ const char *menu_get_help(struct menu *menu)
return "";
}
-static void get_prompt_str(struct gstr *r, struct property *prop)
+static int get_prompt_str(struct gstr *r, struct property *prop, struct menu
+ **jumps, int jump_nb)
{
int i, j;
- struct menu *submenu[8], *menu;
+ char header[4];
+ struct menu *submenu[8], *menu, *location = NULL;
str_printf(r, _("Prompt: %s\n"), _(prop->text));
str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
@@ -521,13 +523,34 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
str_append(r, "\n");
}
menu = prop->menu->parent;
- for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+ for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
+ bool accessible = menu_is_visible(menu);
+
submenu[i++] = menu;
+ if (location == NULL && accessible)
+ location = menu;
+ }
+ if (jumps && jump_nb < JUMP_NB && location) {
+ if (menu_is_visible(prop->menu)) {
+ /*
+ * There is not enough room to put the hint at the
+ * beginning of the "Prompt" line. Put the hint on the
+ * last "Location" line even when it would belong on
+ * the former.
+ */
+ jumps[jump_nb] = prop->menu;
+ } else
+ jumps[jump_nb] = location;
+ snprintf(header, 4, "(%d)", jump_nb + 1);
+ } else
+ location = NULL;
+
if (i > 0) {
str_printf(r, _(" Location:\n"));
- for (j = 4; --i >= 0; j += 2) {
+ for (j = 1; --i >= 0; j += 2) {
menu = submenu[i];
- str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
+ str_printf(r, "%s%*c-> %s", menu == location ? header
+ : " ", j, ' ', _(menu_get_prompt(menu)));
if (menu->sym) {
str_printf(r, " (%s [=%s])", menu->sym->name ?
menu->sym->name : _("<choice>"),
@@ -536,12 +559,20 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
str_append(r, "\n");
}
}
+
+ return location ? 1 : 0;
}
-void get_symbol_str(struct gstr *r, struct symbol *sym)
+/*
+ * jumps is optional and may be NULL
+ * returns the number of jumps inserted
+ */
+int get_symbol_str(struct gstr *r, struct symbol *sym, struct menu **jumps,
+ int jump_nb)
{
bool hit;
struct property *prop;
+ int i = 0;
if (sym && sym->name) {
str_printf(r, "Symbol: %s [=%s]\n", sym->name,
@@ -557,7 +588,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
}
}
for_all_prompts(sym, prop)
- get_prompt_str(r, prop);
+ i += get_prompt_str(r, prop, jumps, jump_nb + i);
hit = false;
for_all_properties(sym, prop, P_SELECT) {
if (!hit) {
@@ -575,16 +606,18 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
str_append(r, "\n");
}
str_append(r, "\n\n");
+
+ return i;
}
-struct gstr get_relations_str(struct symbol **sym_arr)
+struct gstr get_relations_str(struct symbol **sym_arr, struct menu **jumps)
{
struct symbol *sym;
struct gstr res = str_new();
- int i;
+ int i, jump_nb = 0;
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
- get_symbol_str(&res, sym);
+ jump_nb += get_symbol_str(&res, sym, jumps, jump_nb);
if (!i)
str_append(&res, _("No matches found.\n"));
return res;
@@ -603,5 +636,5 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
}
str_printf(help, "%s\n", _(help_text));
if (sym)
- get_symbol_str(help, sym);
+ get_symbol_str(help, sym, NULL, 0);
}
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 1704a85..87d4b15 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -721,7 +721,7 @@ again:
dialog_input += strlen(CONFIG_);
sym_arr = sym_re_search(dialog_input);
- res = get_relations_str(sym_arr);
+ res = get_relations_str(sym_arr, NULL);
free(sym_arr);
show_scroll_win(main_window,
_("Search Results"), str_get(&res));
--
1.7.7
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/6] menuconfig: Assign jump keys per-page instead of globally
2012-07-30 19:22 [PATCH 0/6] menuconfig: jump to search results Benjamin Poirier
` (4 preceding siblings ...)
2012-07-30 19:22 ` [PATCH 5/6] menuconfig: Do not open code textbox scroll up/down Benjamin Poirier
@ 2012-07-30 19:22 ` Benjamin Poirier
2012-07-30 19:58 ` [PATCH 0/6] menuconfig: jump to search results Borislav Petkov
6 siblings, 0 replies; 14+ messages in thread
From: Benjamin Poirier @ 2012-07-30 19:22 UTC (permalink / raw)
To: Michal Marek
Cc: Lucas De Marchi, Arnaud Lacombe, linux-kbuild, linux-kernel,
Randy Dunlap
At the moment, keys 1-9 are assigned to the first 9 search results. This patch
makes them assigned to the first 9 results per-page instead. We are much less
likely to run out of keys that way.
Signed-off-by: Benjamin Poirier <bpoirier@suse.de>
---
scripts/kconfig/expr.h | 9 ++++
scripts/kconfig/lkc_proto.h | 8 ++--
scripts/kconfig/lxdialog/dialog.h | 9 +++-
scripts/kconfig/lxdialog/textbox.c | 65 ++++++++++++++++++++------------
scripts/kconfig/mconf.c | 73 ++++++++++++++++++++++++++++-------
| 54 ++++++++++++++-------------
6 files changed, 147 insertions(+), 71 deletions(-)
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 52f4246..bd2e098 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -12,6 +12,7 @@ extern "C" {
#include <assert.h>
#include <stdio.h>
+#include <sys/queue.h>
#ifndef __cplusplus
#include <stdbool.h>
#endif
@@ -173,6 +174,14 @@ struct menu {
#define MENU_CHANGED 0x0001
#define MENU_ROOT 0x0002
+struct jump_key {
+ CIRCLEQ_ENTRY(jump_key) entries;
+ size_t offset;
+ struct menu *target;
+ int index;
+};
+CIRCLEQ_HEAD(jk_head, jump_key);
+
#define JUMP_NB 9
extern struct file *file_list;
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 946c2cb3..1d1c085 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -21,10 +21,10 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
P(menu_has_help,bool,(struct menu *menu));
P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str, int, (struct gstr *r, struct symbol *sym, struct menu
- **jumps, int jump_nb));
-P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct menu
- **jumps));
+P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head
+ *head));
+P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head
+ *head));
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
/* symbol.c */
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index 8e7f43b..28e8877 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -209,8 +209,13 @@ int first_alpha(const char *string, const char *exempt);
int dialog_yesno(const char *title, const char *prompt, int height, int width);
int dialog_msgbox(const char *title, const char *prompt, int height,
int width, int pause);
-int dialog_textbox(const char *title, const char *file, int height, int width,
- int *keys, int *_vscroll, int *_hscroll);
+
+
+typedef void (*update_text_fn)(char* buf, size_t start, size_t end, void
+ *_data);
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+ int initial_width, int *keys, int *_vscroll, int *_hscroll,
+ update_text_fn update_text, void *data);
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 3b3c5c4..fcca719e 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -22,23 +22,25 @@
#include "dialog.h"
static void back_lines(int n);
-static void print_page(WINDOW * win, int height, int width);
+static void print_page(WINDOW * win, int height, int width, update_text_fn
+ update_text, void *data);
static void print_line(WINDOW * win, int row, int width);
static char *get_line(void);
static void print_position(WINDOW * win);
static int hscroll;
static int begin_reached, end_reached, page_length;
-static const char *buf;
-static const char *page;
+static char *buf;
+static char *page;
/*
* refresh window content
*/
static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
- int cur_y, int cur_x)
+ int cur_y, int cur_x, update_text_fn update_text,
+ void *data)
{
- print_page(box, boxh, boxw);
+ print_page(box, boxh, boxw, update_text, data);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
@@ -49,9 +51,11 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
* Display text from a file in a dialog box.
*
* keys is a null-terminated array
+ * update_text() may not add or remove any '\n' or '\0' in tbuf
*/
-int dialog_textbox(const char *title, const char *tbuf, int initial_height,
- int initial_width, int *keys, int *_vscroll, int *_hscroll)
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+ int initial_width, int *keys, int *_vscroll, int *_hscroll,
+ update_text_fn update_text, void *data)
{
int i, x, y, cur_x, cur_y, key = 0;
int height, width, boxh, boxw;
@@ -131,7 +135,8 @@ do_resize:
/* Print first page of text */
attr_clear(box, boxh, boxw, dlg.dialog.atr);
- refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
+ data);
while (!done) {
key = wgetch(dialog);
@@ -150,7 +155,8 @@ do_resize:
begin_reached = 1;
page = buf;
refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ cur_y, cur_x, update_text,
+ data);
}
break;
case 'G': /* Last page */
@@ -160,8 +166,8 @@ do_resize:
/* point to last char in buf */
page = buf + strlen(buf);
back_lines(boxh);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case 'K': /* Previous line */
case 'k':
@@ -171,7 +177,7 @@ do_resize:
back_lines(page_length + 1);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
- cur_x);
+ cur_x, update_text, data);
break;
case 'B': /* Previous page */
case 'b':
@@ -180,8 +186,8 @@ do_resize:
if (begin_reached)
break;
back_lines(page_length + boxh);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case 'J': /* Next line */
case 'j':
@@ -191,7 +197,7 @@ do_resize:
back_lines(page_length - 1);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
- cur_x);
+ cur_x, update_text, data);
break;
case KEY_NPAGE: /* Next page */
case ' ':
@@ -200,8 +206,8 @@ do_resize:
break;
begin_reached = 0;
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
@@ -216,8 +222,8 @@ do_resize:
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case 'L': /* Scroll right */
case 'l':
@@ -227,8 +233,8 @@ do_resize:
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
- refresh_text_box(dialog, box, boxh, boxw,
- cur_y, cur_x);
+ refresh_text_box(dialog, box, boxh, boxw, cur_y,
+ cur_x, update_text, data);
break;
case KEY_ESC:
if (on_key_esc(dialog) == KEY_ESC)
@@ -301,12 +307,23 @@ static void back_lines(int n)
}
/*
- * Print a new page of text. Called by dialog_textbox().
+ * Print a new page of text.
*/
-static void print_page(WINDOW * win, int height, int width)
+static void print_page(WINDOW * win, int height, int width, update_text_fn
+ update_text, void *data)
{
int i, passed_end = 0;
+ if (update_text) {
+ char *end;
+
+ for (i = 0; i < height; i++)
+ get_line();
+ end = page;
+ back_lines(height);
+ update_text(buf, page - buf, end - buf, data);
+ }
+
page_length = 0;
for (i = 0; i < height; i++) {
print_line(win, i, width);
@@ -319,7 +336,7 @@ static void print_page(WINDOW * win, int height, int width)
}
/*
- * Print a new line of text. Called by dialog_textbox() and print_page().
+ * Print a new line of text.
*/
static void print_line(WINDOW * win, int row, int width)
{
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index bf75753..8246e2d 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -287,8 +287,9 @@ static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
static void conf_load(void);
static void conf_save(void);
-static int show_textbox_ext(const char *title, const char *text, int r, int c,
- int *keys, int *vscroll, int *hscroll);
+static int show_textbox_ext(const char *title, char *text, int r, int c,
+ int *keys, int *vscroll, int *hscroll,
+ update_text_fn update_text, void *data);
static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu);
@@ -311,6 +312,39 @@ static void set_config_filename(const char *config_filename)
}
+struct search_data {
+ struct jk_head *head;
+ struct menu **targets;
+ int *keys;
+};
+
+static void update_text(char* buf, size_t start, size_t end, void *_data)
+{
+ struct search_data *data = _data;
+ struct jump_key *pos;
+ int k = 0;
+
+ CIRCLEQ_FOREACH(pos, data->head, entries) {
+ if (pos->offset >= start && pos->offset < end) {
+ char header[4];
+
+ if (k < JUMP_NB) {
+ int key = '0' + (pos->index % JUMP_NB) + 1;
+
+ sprintf(header, "(%c)", key);
+ data->keys[k] = key;
+ data->targets[k] = pos->target;
+ k++;
+ } else {
+ sprintf(header, " ");
+ }
+
+ memcpy(buf + pos->offset, header, sizeof(header) - 1);
+ }
+ }
+ data->keys[k] = 0;
+}
+
static void search_conf(void)
{
struct symbol **sym_arr;
@@ -342,18 +376,24 @@ again:
sym_arr = sym_re_search(dialog_input);
do {
- struct menu *jumps[JUMP_NB] = {0};
- int keys[JUMP_NB + 1] = {0}, i;
+ struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head);
+ struct menu *targets[JUMP_NB];
+ int keys[JUMP_NB + 1], i;
+ struct search_data data = {
+ .head = &head,
+ .targets = targets,
+ .keys = keys,
+ };
- res = get_relations_str(sym_arr, jumps);
- for (i = 0; i < JUMP_NB && jumps[i]; i++)
- keys[i] = '1' + i;
- dres = show_textbox_ext(_("Search Results"), str_get(&res), 0,
- 0, keys, &vscroll, &hscroll);
+ res = get_relations_str(sym_arr, &head);
+ dres = show_textbox_ext(_("Search Results"), (char *)
+ str_get(&res), 0, 0, keys, &vscroll,
+ &hscroll, &update_text, (void *)
+ &data);
again = false;
- for (i = 0; i < JUMP_NB && jumps[i]; i++)
+ for (i = 0; i < JUMP_NB && keys[i]; i++)
if (dres == keys[i]) {
- conf(jumps[i]->parent, jumps[i]);
+ conf(targets[i]->parent, targets[i]);
again = true;
}
str_free(&res);
@@ -643,16 +683,19 @@ static void conf(struct menu *menu, struct menu *active_menu)
}
}
-static int show_textbox_ext(const char *title, const char *text, int r, int c,
- int *keys, int *vscroll, int *hscroll)
+static int show_textbox_ext(const char *title, char *text, int r, int c, int
+ *keys, int *vscroll, int *hscroll, update_text_fn
+ update_text, void *data)
{
dialog_clear();
- return dialog_textbox(title, text, r, c, keys, vscroll, hscroll);
+ return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
+ update_text, data);
}
static void show_textbox(const char *title, const char *text, int r, int c)
{
- show_textbox_ext(title, text, r, c, (int []) {0}, NULL, NULL);
+ show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
+ NULL, NULL);
}
static void show_helptext(const char *title, const char *text)
--git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index a524185..0dcf202 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -507,12 +507,12 @@ const char *menu_get_help(struct menu *menu)
return "";
}
-static int get_prompt_str(struct gstr *r, struct property *prop, struct menu
- **jumps, int jump_nb)
+static void get_prompt_str(struct gstr *r, struct property *prop, struct
+ jk_head *head)
{
int i, j;
- char header[4];
struct menu *submenu[8], *menu, *location = NULL;
+ struct jump_key *jump;
str_printf(r, _("Prompt: %s\n"), _(prop->text));
str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
@@ -530,7 +530,9 @@ static int get_prompt_str(struct gstr *r, struct property *prop, struct menu
if (location == NULL && accessible)
location = menu;
}
- if (jumps && jump_nb < JUMP_NB && location) {
+ if (head && location) {
+ jump = malloc(sizeof(struct jump_key));
+
if (menu_is_visible(prop->menu)) {
/*
* There is not enough room to put the hint at the
@@ -538,19 +540,26 @@ static int get_prompt_str(struct gstr *r, struct property *prop, struct menu
* last "Location" line even when it would belong on
* the former.
*/
- jumps[jump_nb] = prop->menu;
+ jump->target = prop->menu;
} else
- jumps[jump_nb] = location;
- snprintf(header, 4, "(%d)", jump_nb + 1);
- } else
- location = NULL;
+ jump->target = location;
+
+ if (CIRCLEQ_EMPTY(head))
+ jump->index = 0;
+ else
+ jump->index = CIRCLEQ_LAST(head)->index + 1;
+
+ CIRCLEQ_INSERT_TAIL(head, jump, entries);
+ }
if (i > 0) {
str_printf(r, _(" Location:\n"));
- for (j = 1; --i >= 0; j += 2) {
+ for (j = 4; --i >= 0; j += 2) {
menu = submenu[i];
- str_printf(r, "%s%*c-> %s", menu == location ? header
- : " ", j, ' ', _(menu_get_prompt(menu)));
+ if (head && location && menu == location)
+ jump->offset = r->len - 1;
+ str_printf(r, "%*c-> %s", j, ' ',
+ _(menu_get_prompt(menu)));
if (menu->sym) {
str_printf(r, " (%s [=%s])", menu->sym->name ?
menu->sym->name : _("<choice>"),
@@ -559,20 +568,15 @@ static int get_prompt_str(struct gstr *r, struct property *prop, struct menu
str_append(r, "\n");
}
}
-
- return location ? 1 : 0;
}
/*
- * jumps is optional and may be NULL
- * returns the number of jumps inserted
+ * head is optional and may be NULL
*/
-int get_symbol_str(struct gstr *r, struct symbol *sym, struct menu **jumps,
- int jump_nb)
+void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head)
{
bool hit;
struct property *prop;
- int i = 0;
if (sym && sym->name) {
str_printf(r, "Symbol: %s [=%s]\n", sym->name,
@@ -588,7 +592,7 @@ int get_symbol_str(struct gstr *r, struct symbol *sym, struct menu **jumps,
}
}
for_all_prompts(sym, prop)
- i += get_prompt_str(r, prop, jumps, jump_nb + i);
+ get_prompt_str(r, prop, head);
hit = false;
for_all_properties(sym, prop, P_SELECT) {
if (!hit) {
@@ -606,18 +610,16 @@ int get_symbol_str(struct gstr *r, struct symbol *sym, struct menu **jumps,
str_append(r, "\n");
}
str_append(r, "\n\n");
-
- return i;
}
-struct gstr get_relations_str(struct symbol **sym_arr, struct menu **jumps)
+struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head)
{
struct symbol *sym;
struct gstr res = str_new();
- int i, jump_nb = 0;
+ int i;
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
- jump_nb += get_symbol_str(&res, sym, jumps, jump_nb);
+ get_symbol_str(&res, sym, head);
if (!i)
str_append(&res, _("No matches found.\n"));
return res;
@@ -636,5 +638,5 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
}
str_printf(help, "%s\n", _(help_text));
if (sym)
- get_symbol_str(help, sym, NULL, 0);
+ get_symbol_str(help, sym, NULL);
}
--
1.7.7
^ permalink raw reply related [flat|nested] 14+ messages in thread