Pārlūkot izejas kodu

ccmake: Add VIM-like bindings for navigation

* scroll with j/k
* toggle bool with space, enter insert mode with i
* bindings not shown at the bottom of the screen, but given in help
Paul Seyfert 9 gadi atpakaļ
vecāks
revīzija
e34e9c2705

+ 4 - 0
Help/release/dev/ccmake-vim-navigation.rst

@@ -0,0 +1,4 @@
+ccmake-vim-navigation
+---------------------
+
+* :manual:`ccmake(1)` learned to support vim-like navigation bindings.

+ 2 - 1
Source/CursesDialog/cmCursesBoolWidget.cxx

@@ -27,8 +27,9 @@ cmCursesBoolWidget::cmCursesBoolWidget(int width, int height, int left,
 bool cmCursesBoolWidget::HandleInput(int& key, cmCursesMainForm*, WINDOW* w)
 {
 
+  // toggle boolean values with enter or space
   // 10 == enter
-  if (key == 10 || key == KEY_ENTER) {
+  if (key == 10 || key == KEY_ENTER || key == ' ') {
     if (this->GetValueAsBool()) {
       this->SetValueAsBool(false);
     } else {

+ 11 - 7
Source/CursesDialog/cmCursesMainForm.cxx

@@ -837,7 +837,9 @@ void cmCursesMainForm::HandleInput()
       // therefore, the label field for the prev. entry is index-5
       // and the label field for the next entry is index+1
       // (index always corresponds to the value field)
-      else if (key == KEY_DOWN || key == ctrl('n')) {
+      // scroll down with arrow down, ctrl+n (emacs binding), or j (vim
+      // binding)
+      else if (key == KEY_DOWN || key == ctrl('n') || key == 'j') {
         FIELD* cur = current_field(this->Form);
         size_t findex = field_index(cur);
         if (findex == 3 * this->NumberOfVisibleEntries - 1) {
@@ -854,7 +856,8 @@ void cmCursesMainForm::HandleInput()
       // therefore, the label field for the prev. entry is index-5
       // and the label field for the next entry is index+1
       // (index always corresponds to the value field)
-      else if (key == KEY_UP || key == ctrl('p')) {
+      // scroll down with arrow up, ctrl+p (emacs binding), or k (vim binding)
+      else if (key == KEY_UP || key == ctrl('p') || key == 'k') {
         FIELD* cur = current_field(this->Form);
         int findex = field_index(cur);
         if (findex == 2) {
@@ -1122,16 +1125,17 @@ const char* cmCursesMainForm::s_ConstHelpMessage =
   "Navigation: "
   "You can use the arrow keys and page up, down to navigate the options. "
   "Alternatively, you can use the following keys: \n"
-  " C-n : next option\n"
-  " C-p : previous options\n"
+  " C-n or j : next option\n"
+  " C-p or k : previous options\n"
   " C-d : down one page\n"
   " C-u : up one page\n\n"
   "Editing options: "
   "To change an option  press enter or return. If the current options is a "
   "boolean, this will toggle its value. "
-  "Otherwise, ccmake will enter edit mode. In this mode you can edit an "
-  "option using arrow keys and backspace. Alternatively, you can use the "
-  "following keys:\n"
+  "Otherwise, ccmake will enter edit mode. Alternatively, you can toggle "
+  "a bool variable by pressing space, and enter edit mode with i."
+  "In this mode you can edit an option using arrow keys and backspace. "
+  "Alternatively, you can use the following keys:\n"
   " C-b : back one character\n"
   " C-f : forward one character\n"
   " C-a : go to the beginning of the field\n"

+ 10 - 4
Source/CursesDialog/cmCursesStringWidget.cxx

@@ -67,8 +67,10 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
   int x, y;
 
   FORM* form = fm->GetForm();
+  // when not in edit mode, edit mode is entered by pressing enter or i (vim
+  // binding)
   // 10 == enter
-  if (!this->InEdit && (key != 10 && key != KEY_ENTER)) {
+  if (!this->InEdit && (key != 10 && key != KEY_ENTER && key != 'i')) {
     return false;
   }
 
@@ -97,11 +99,15 @@ bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
     }
 
     // If resize occurred during edit, move out of edit mode
-    if (!this->InEdit && (key != 10 && key != KEY_ENTER)) {
+    if (!this->InEdit && (key != 10 && key != KEY_ENTER && key != 'i')) {
       return false;
     }
-    // 10 == enter
-    if (key == 10 || key == KEY_ENTER) {
+    // enter edit with return and i (vim binding)
+    if (!this->InEdit && (key == 10 || key == KEY_ENTER || key == 'i')) {
+      this->OnReturn(fm, w);
+    }
+    // leave edit with return (but not i -- not a toggle)
+    else if (this->InEdit && (key == 10 || key == KEY_ENTER)) {
       this->OnReturn(fm, w);
     } else if (key == KEY_DOWN || key == ctrl('n') || key == KEY_UP ||
                key == ctrl('p') || key == KEY_NPAGE || key == ctrl('d') ||