diff --git a/README.rst b/README.rst index 5c5f2440..469c62a1 100644 --- a/README.rst +++ b/README.rst @@ -125,6 +125,7 @@ Example: answers = inquirer.prompt(questions) Checkbox questions can take one extra argument :code:`carousel=False`. If set to true, the answers will rotate (back to first when pressing down on last choice, and down to last choice when pressing up on first choice) +Use ctrl+a and ctrl+q to select and unselect all |inquirer checkbox| diff --git a/src/inquirer/render/console/_checkbox.py b/src/inquirer/render/console/_checkbox.py index 7adb1197..887720a8 100644 --- a/src/inquirer/render/console/_checkbox.py +++ b/src/inquirer/render/console/_checkbox.py @@ -66,13 +66,13 @@ def get_options(self): def process_input(self, pressed): question = self.question - if pressed == key.UP: + if pressed in (key.UP, key.SHIFT_TAB): if question.carousel and self.current == 0: self.current = len(question.choices) - 1 else: self.current = max(0, self.current - 1) return - elif pressed == key.DOWN: + elif pressed in (key.DOWN, key.CTRL_I): if question.carousel and self.current == len(question.choices) - 1: self.current = 0 else: @@ -89,6 +89,11 @@ def process_input(self, pressed): elif pressed == key.RIGHT: if self.current not in self.selection: self.selection.append(self.current) + elif pressed == key.CTRL_A: + for x in self.question.choices: + self.selection = list(range(len(self.question.choices))) + elif pressed == key.CTRL_Q: + self.selection = [] elif pressed == key.ENTER: result = [] for x in self.selection: diff --git a/tests/acceptance/test_checkbox.py b/tests/acceptance/test_checkbox.py index 5bda0dfd..8669ffef 100644 --- a/tests/acceptance/test_checkbox.py +++ b/tests/acceptance/test_checkbox.py @@ -57,6 +57,33 @@ def test_select_last(self): self.sut.send(key.ENTER) self.sut.expect(r"{'interests': \['Computers', 'Books', 'History'\]}.*", timeout=1) # noqa + def test_navigate_with_tab(self): + self.sut.send(key.CTRL_I) + self.sut.send(key.LEFT) + self.sut.send(key.ENTER) + self.sut.expect(r"{'interests': \['Computers'\]}.*", timeout=1) # noqa + + # Check after merge release readchar >= dev 4.0.0 + @unittest.SkipTest + def test_navigate_with_shift_tab(self): + self.sut.send(key.DOWN) + self.sut.send(key.DOWN) + self.sut.send(key.SHIFT_TAB) + self.sut.send(key.LEFT) + self.sut.send(key.ENTER) + self.sut.expect(r"{'interests': \['Computers'\]}.*", timeout=1) # noqa + + def test_select_all_with_ctrl_a(self): + self.sut.send(key.CTRL_A) + self.sut.send(key.ENTER) + self.sut.expect(r"{'interests': \['Computers', 'Books', 'Science', 'Nature', 'Fantasy', 'History'\]}.*", timeout=1) # noqa + + def test_unselect_all_with_ctrl_q(self): + self.sut.send(key.CTRL_A) + self.sut.send(key.CTRL_Q) + self.sut.send(key.ENTER) + self.sut.expect(r"{'interests': \[\]}.*", timeout=1) # noqa + @unittest.skipUnless(sys.platform.startswith("lin"), "Linux only") class CheckCarouselTest(unittest.TestCase): diff --git a/tests/integration/console_render/test_checkbox.py b/tests/integration/console_render/test_checkbox.py index 0350d74e..dd7e18e6 100644 --- a/tests/integration/console_render/test_checkbox.py +++ b/tests/integration/console_render/test_checkbox.py @@ -145,6 +145,19 @@ def test_move_down_carousel(self): assert result == ["bar"] + def test_move_down_with_tab_carousel(self): + stdin = helper.event_factory(key.CTRL_I, key.CTRL_I, key.CTRL_I, key.CTRL_I, key.SPACE, key.ENTER) + message = "Foo message" + variable = "Bar variable" + choices = ["foo", "bar", "bazz"] + + question = questions.Checkbox(variable, message, choices=choices, carousel=True) + + sut = ConsoleRender(event_generator=stdin) + result = sut.render(question) + + assert result == ["bar"] + def test_move_up_carousel(self): stdin = helper.event_factory(key.UP, key.SPACE, key.ENTER) message = "Foo message" @@ -158,6 +171,21 @@ def test_move_up_carousel(self): assert result == ["bazz"] + # Check after merge release readchar >= dev 4.0.0 + @unittest.SkipTest + def test_move_up_with_shift_tab_carousel(self): + stdin = helper.event_factory(key.SHIFT_TAB, key.SPACE, key.ENTER) + message = "Foo message" + variable = "Bar variable" + choices = ["foo", "bar", "bazz"] + + question = questions.Checkbox(variable, message, choices=choices, carousel=True) + + sut = ConsoleRender(event_generator=stdin) + result = sut.render(question) + + assert result == ["bazz"] + def test_ctrl_c_breaks_execution(self): stdin_array = [key.CTRL_C] stdin = helper.event_factory(*stdin_array)