diff --git a/Help/release/dev/ccmake-vim-navigation.rst b/Help/release/dev/ccmake-vim-navigation.rst new file mode 100644 index 000000000..8fc141639 --- /dev/null +++ b/Help/release/dev/ccmake-vim-navigation.rst @@ -0,0 +1,4 @@ +ccmake-vim-navigation +--------------------- + +* :manual:`ccmake(1)` learned to support vim-like navigation bindings. diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx index 9bcf0507b..e36ac3402 100644 --- a/Source/CursesDialog/cmCursesBoolWidget.cxx +++ b/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 { diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 9ae38d62d..964f3af55 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -388,7 +388,7 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */) curses_move(y - 4, 0); char fmt_s[] = "%s"; - char fmt[512] = "Press [enter] to edit option"; + char fmt[512] = "Press [enter] to edit option Press [d] to delete an entry"; if (process) { strcpy(fmt, " "); } @@ -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 it's 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" + "boolean, this will toggle its value. " + "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" @@ -1140,7 +1144,6 @@ const char* cmCursesMainForm::s_ConstHelpMessage = " C-k : kill the rest of the field\n" " Esc : Restore field (discard last changes)\n" " Enter : Leave edit mode\n" - "You can also delete an option by pressing 'd'\n\n" "Commands:\n" " q : quit ccmake without generating build files\n" " h : help, shows this screen\n" @@ -1148,6 +1151,7 @@ const char* cmCursesMainForm::s_ConstHelpMessage = " g : generate build files and exit, only available when there are no " "new options and no errors have been detected during last configuration.\n" " l : shows last errors\n" + " d : delete an option\n" " t : toggles advanced mode. In normal mode, only the most important " "options are shown. In advanced mode, all options are shown. We recommend " "using normal mode unless you are an expert.\n" diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx index 6eb5310a3..46b8b8609 100644 --- a/Source/CursesDialog/cmCursesStringWidget.cxx +++ b/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') ||