Tuesday, August 6, 2013

Kernel menuconfig to move in VIM ways

Specially for VIM fans. The following is a patch to current (GIT) linux kernel lxdialog that allows you to move with h,j,k,l keys in menuconfig. Please click HERE to download the whole patch file.

diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index 3b15c08..002187c 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -48,10 +48,12 @@ static void print_item(WINDOW * win, int choice, int selected)
  if (!item_is_tag(':'))
   wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');

+ i = first_alpha(list_item, "SsHhJjKkLl");
+ mvwaddnstr(win, choice, item_x, list_item, i);
  wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
- mvwaddch(win, choice, item_x, list_item[0]);
+ waddch(win, list_item[i]);
  wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
- waddstr(win, list_item + 1);
+ waddstr(win, list_item + i + 1);
  if (selected) {
   wmove(win, choice, check_x + 1);
   wrefresh(win);
This hunk patches checklist to highlight correct characters for the hotkeys. It skips reserved characters (s,h,j,k,l) which are used for other commands.

@@ -209,14 +211,18 @@ do_resize:
   key = wgetch(dialog);

   for (i = 0; i < max_choice; i++) {
+                        int j;
    item_set(i + scroll);
-   if (toupper(key) == toupper(item_str()[0]))
+                        if (i == choice)
+                                continue;
+                        j = first_alpha(item_str(), "SsHhJjKkLl");
+   if (toupper(key) == toupper(item_str()[j]))
     break;
   }
This hunk patches checklist to use first un-rserved character of the item for its hotkey.


Then, hunks allowing h,j,k,l movements:
   if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
-      key == '+' || key == '-') {
-   if (key == KEY_UP || key == '-') {
+      key == '+' || key == '-' || key == 'j' || key == 'k') {
+   if (key == KEY_UP || key == '-' || key == 'k') {
     if (!choice) {
      if (!scroll)
       continue;
@@ -241,7 +247,7 @@ do_resize:
      continue; /* wait for another key press */
     } else
      i = choice - 1;
-   } else if (key == KEY_DOWN || key == '+') {
+   } else if (key == KEY_DOWN || key == '+' || key == 'j') {
     if (choice == max_choice - 1) {
      if (scroll + choice >= item_count() - 1)
       continue;
@@ -285,7 +291,6 @@ do_resize:
   }
   switch (key) {
   case 'H':
-  case 'h':
   case '?':
    button = 1;
    /* fall-through */
@@ -303,7 +308,9 @@ do_resize:
   case TAB:
   case KEY_LEFT:
   case KEY_RIGHT:
-   button = ((key == KEY_LEFT ? --button : ++button) < 0)
+  case 'h':
+  case 'l':
+   button = (((key == KEY_LEFT || key == 'h') ? --button : ++button) < 0)
        ? 1 : (button > 1 ? 0 : button);

    print_buttons(dialog, height, width, button);
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
index c93de0b..aed62d0 100644
--- a/scripts/kconfig/lxdialog/menubox.c
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -71,7 +71,7 @@ static void do_print_item(WINDOW * win, const char *item, int line_y,

  strncpy(menu_item, item, menu_width - item_x);
  menu_item[menu_width - item_x] = '\0';
- j = first_alpha(menu_item, "YyNnMmHh");
+ j = first_alpha(menu_item, "YyNnMmHhJjKk");

  /* Clear 'residue' of last item */
  wattrset(win, dlg.menubox.atr);
@@ -285,19 +285,19 @@ do_resize:
   if (key < 256 && isalpha(key))
    key = tolower(key);

-  if (strchr("ynmh", key))
+  if (strchr("ynmhjkl", key))
    i = max_choice;
   else {
    for (i = choice + 1; i < max_choice; i++) {
     item_set(scroll + i);
-    j = first_alpha(item_str(), "YyNnMmHh");
+    j = first_alpha(item_str(), "YyNnMmHhiJjKkLl");
     if (key == tolower(item_str()[j]))
      break;
    }
    if (i == max_choice)
     for (i = 0; i < max_choice; i++) {
      item_set(scroll + i);
-     j = first_alpha(item_str(), "YyNnMmHh");
+     j = first_alpha(item_str(), "YyNnMmHhJjKkLl");
      if (key == tolower(item_str()[j]))
       break;
     }
@@ -306,12 +306,13 @@ do_resize:
   if (item_count() != 0 &&
       (i < max_choice ||
        key == KEY_UP || key == KEY_DOWN ||
+       key == 'k' || key == 'j' ||
        key == '-' || key == '+' ||
        key == KEY_PPAGE || key == KEY_NPAGE)) {
    /* Remove highligt of current item */
    print_item(scroll + choice, choice, FALSE);

-   if (key == KEY_UP || key == '-') {
+   if (key == KEY_UP || key == '-' || key == 'k') {
     if (choice < 2 && scroll) {
      /* Scroll menu down */
      do_scroll(menu, &scroll, -1);
@@ -320,7 +321,7 @@ do_resize:
     } else
      choice = MAX(choice - 1, 0);

-   } else if (key == KEY_DOWN || key == '+') {
+   } else if (key == KEY_DOWN || key == '+' || key == 'j') {
     print_item(scroll+choice, choice, FALSE);

     if ((choice > max_choice - 3) &&
@@ -374,7 +375,9 @@ do_resize:
   case KEY_LEFT:
   case TAB:
   case KEY_RIGHT:
-   button = ((key == KEY_LEFT ? --button : ++button) < 0)
+  case 'h':
+  case 'l':
+   button = (((key == KEY_LEFT || key == 'h') ? --button : ++button) < 0)
        ? 4 : (button > 4 ? 0 : button);

    print_buttons(dialog, height, width, button);
@@ -386,7 +389,6 @@ do_resize:
   case 'n':
   case 'm':
   case '/':
-  case 'h':
   case '?':
   case 'z':
   case '\n':
@@ -397,7 +399,6 @@ do_resize:
    item_set(scroll + choice);
    item_set_selected(1);
    switch (key) {
-   case 'h':
    case '?':
     return 2;
    case 's':
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
index 676fb2f..305257f 100644
--- a/scripts/kconfig/lxdialog/yesno.c
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -90,7 +90,9 @@ do_resize:
   case TAB:
   case KEY_LEFT:
   case KEY_RIGHT:
-   button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button);
+  case 'l':
+  case 'h':
+   button = (((key == KEY_LEFT || key == 'h') ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button);

    print_buttons(dialog, height, width, button);
    wrefresh(dialog);

No comments: