diff --git a/awsshell/app.py b/awsshell/app.py index 84b5660..21c16a7 100644 --- a/awsshell/app.py +++ b/awsshell/app.py @@ -252,9 +252,13 @@ def __init__(self, completer, model_completer, docs, self.show_completion_columns = None self.show_help = None self.theme = None + self.key_bindings = None self.load_config() + if self.key_bindings is None: + self.set_default_key_bindings() + def load_config(self): """Load the config from the config file or template.""" config = Config() @@ -268,6 +272,8 @@ def load_config(self): 'show_completion_columns') self.show_help = self.config_section.as_bool('show_help') self.theme = self.config_section['theme'] + if 'keys' in self.config_section: + self.key_bindings = self.config_section['keys'] def save_config(self): """Save the config to the config file.""" @@ -277,8 +283,19 @@ def save_config(self): self.show_completion_columns self.config_section['show_help'] = self.show_help self.config_section['theme'] = self.theme + self.config_section['keys'] = self.key_bindings self.config_obj.write() + def set_default_key_bindings(self): + self.key_bindings = { + 'toggle_fuzzy': 'F2', + 'toggle_editor': 'F3', + 'toggle_column': 'F4', + 'toggle_help': 'F5', + 'toggle_focus': 'F9', + 'exit': 'F10' + } + @property def cli(self): if self._cli is None or self.refresh_cli: @@ -410,7 +427,8 @@ def set_show_help(show_help): lambda: self.enable_vi_bindings, set_enable_vi_bindings, lambda: self.show_completion_columns, set_show_completion_columns, lambda: self.show_help, set_show_help, - self.stop_input_and_refresh_cli) + self.stop_input_and_refresh_cli, + self.key_bindings) def create_application(self, completer, history, display_completions_in_columns): @@ -419,7 +437,8 @@ def create_application(self, completer, history, lambda: self.model_completer.match_fuzzy, lambda: self.enable_vi_bindings, lambda: self.show_completion_columns, - lambda: self.show_help) + lambda: self.show_help, + self.key_manager.key_bindings) style_factory = StyleFactory(self.theme) buffers = { 'clidocs': Buffer(read_only=True) diff --git a/awsshell/awsshellrc b/awsshell/awsshellrc index a51950b..50146d8 100644 --- a/awsshell/awsshellrc +++ b/awsshell/awsshellrc @@ -18,3 +18,49 @@ show_help = True # pastie, paraiso-light, trac, default, fruity. # to disable themes, set theme = none theme = vim + +# Keyboard Shortcuts +[[keys]] +toggle_fuzzy = F2 +toggle_editor = F3 +toggle_column = F4 +toggle_help = F5 +toggle_focus = F9 +exit = F10 + +# Keyboard Shortcuts Possible Values +# ControlA, ControlB, .., ContolZ + +# ControlSpace +# ControlBackslash +# ControlSquareClose +# ControlCircumflex +# ControlUnderscore +# ControlLeft +# ControlRight +# ControlUp +# ControlDown + +# Up +# Down +# Right +# Left + +# ShiftLeft +# ShiftUp +# ShiftDown +# ShiftRight + +# Home +# End +# Delete +# ShiftDelete +# ControlDelete +# PageUp +# PageDown +# BackTab +# Insert +# Backspace + +# F1, F2, .. , F24 + diff --git a/awsshell/keys.py b/awsshell/keys.py index 5e2df96..b9c4690 100644 --- a/awsshell/keys.py +++ b/awsshell/keys.py @@ -30,8 +30,10 @@ class KeyManager(object): def __init__(self, get_match_fuzzy, set_match_fuzzy, get_enable_vi_bindings, set_enable_vi_bindings, get_show_completion_columns, set_show_completion_columns, - get_show_help, set_show_help, stop_input_and_refresh_cli): + get_show_help, set_show_help, stop_input_and_refresh_cli, + key_bindings): self.manager = None + self.key_bindings = key_bindings self._create_key_manager( get_match_fuzzy, set_match_fuzzy, get_enable_vi_bindings, set_enable_vi_bindings, @@ -99,8 +101,9 @@ def _create_key_manager(self, get_match_fuzzy, set_match_fuzzy, enable_auto_suggest_bindings=True, enable_open_in_editor=False) - @self.manager.registry.add_binding(Keys.F2) - def handle_f2(_): + @self.manager.registry.add_binding( + getattr(Keys, self.key_bindings['toggle_fuzzy'])) + def handle_toggle_fuzzy(_): """Toggle fuzzy matching. :type _: :class:`prompt_toolkit.Event` @@ -109,8 +112,9 @@ def handle_f2(_): """ set_match_fuzzy(not get_match_fuzzy()) - @self.manager.registry.add_binding(Keys.F3) - def handle_f3(_): + @self.manager.registry.add_binding( + getattr(Keys, self.key_bindings['toggle_editor'])) + def handle_toggle_editor(_): """Toggle Vi mode keybindings matching. Disabling Vi keybindings will enable Emacs keybindings. @@ -122,8 +126,9 @@ def handle_f3(_): set_enable_vi_bindings(not get_enable_vi_bindings()) stop_input_and_refresh_cli() - @self.manager.registry.add_binding(Keys.F4) - def handle_f4(_): + @self.manager.registry.add_binding( + getattr(Keys, self.key_bindings['toggle_column'])) + def handle_toggle_column(_): """Toggle multiple column completions. :type _: :class:`prompt_toolkit.Event` @@ -133,8 +138,9 @@ def handle_f4(_): set_show_completion_columns(not get_show_completion_columns()) stop_input_and_refresh_cli() - @self.manager.registry.add_binding(Keys.F5) - def handle_f5(_): + @self.manager.registry.add_binding( + getattr(Keys, self.key_bindings['toggle_help'])) + def handle_toggle_help(_): """Toggle the help container. :type _: :class:`prompt_toolkit.Event` @@ -144,8 +150,9 @@ def handle_f5(_): set_show_help(not get_show_help()) stop_input_and_refresh_cli() - @self.manager.registry.add_binding(Keys.F9) - def handle_f9(event): + @self.manager.registry.add_binding( + getattr(Keys, self.key_bindings['toggle_focus'])) + def handle_toggle_focus(event): """Switch between the default and docs buffers. :type event: :class:`prompt_toolkit.Event` @@ -158,8 +165,9 @@ def handle_f9(event): else: event.cli.focus(u'clidocs') - @self.manager.registry.add_binding(Keys.F10) - def handle_f10(event): + @self.manager.registry.add_binding( + getattr(Keys, self.key_bindings['exit'])) + def handle_exit(event): """Quit when the `F10` key is pressed. :type event: :class:`prompt_toolkit.Event` diff --git a/awsshell/toolbar.py b/awsshell/toolbar.py index 6b4d344..c405c21 100644 --- a/awsshell/toolbar.py +++ b/awsshell/toolbar.py @@ -22,10 +22,11 @@ class Toolbar(object): """ def __init__(self, get_match_fuzzy, get_enable_vi_bindings, - get_show_completion_columns, get_show_help): + get_show_completion_columns, get_show_help, key_bindings): + self.key_bindings = key_bindings self.handler = self._create_toolbar_handler( get_match_fuzzy, get_enable_vi_bindings, - get_show_completion_columns, get_show_help) + get_show_completion_columns, get_show_help,) def _create_toolbar_handler(self, get_match_fuzzy, get_enable_vi_bindings, get_show_completion_columns, get_show_help): @@ -93,17 +94,27 @@ def get_toolbar_items(cli): show_buffer_name = 'doc' return [ (match_fuzzy_token, - ' [F2] Fuzzy: {0} '.format(match_fuzzy_cfg)), + ' [{0}] Fuzzy: {1} '.format( + self.key_bindings['toggle_fuzzy'], + match_fuzzy_cfg)), (enable_vi_bindings_token, - ' [F3] Keys: {0} '.format(enable_vi_bindings_cfg)), + ' [{0}] Keys: {1} '.format( + self.key_bindings['toggle_editor'], + enable_vi_bindings_cfg)), (show_columns_token, - ' [F4] {0} Column '.format(show_columns_cfg)), + ' [{0}] {1} Column '.format( + self.key_bindings['toggle_column'], + show_columns_cfg)), (show_help_token, - ' [F5] Help: {0} '.format(show_help_cfg)), + ' [{0}] Help: {1} '.format( + self.key_bindings['toggle_help'], + show_help_cfg)), (Token.Toolbar, - ' [F9] Focus: {0} '.format(show_buffer_name)), + ' [{0}] Focus: {1} '.format( + self.key_bindings['toggle_focus'], + show_buffer_name)), (Token.Toolbar, - ' [F10] Exit ') + ' [{0}] Exit '.format(self.key_bindings['exit'])) ] return get_toolbar_items diff --git a/tests/integration/test_keys.py b/tests/integration/test_keys.py index 3186113..8fe0012 100644 --- a/tests/integration/test_keys.py +++ b/tests/integration/test_keys.py @@ -37,35 +37,35 @@ def feed_key(self, key): self.processor.feed(KeyPress(key, u'')) self.processor.process_keys() - def test_F2(self): + def test_toggle_fuzzy(self): match_fuzzy = self.aws_shell.model_completer.match_fuzzy self.feed_key(Keys.F2) assert match_fuzzy != self.aws_shell.model_completer.match_fuzzy - def test_F3(self): + def test_toggle_editor(self): enable_vi_bindings = self.aws_shell.enable_vi_bindings with self.assertRaises(InputInterrupt): self.feed_key(Keys.F3) assert enable_vi_bindings != self.aws_shell.enable_vi_bindings - def test_F4(self): + def test_toggle_column(self): show_completion_columns = self.aws_shell.show_completion_columns with self.assertRaises(InputInterrupt): self.feed_key(Keys.F4) assert show_completion_columns != \ self.aws_shell.show_completion_columns - def test_F5(self): + def test_toggle_help(self): show_help = self.aws_shell.show_help with self.assertRaises(InputInterrupt): self.feed_key(Keys.F5) assert show_help != self.aws_shell.show_help - def test_F9(self): + def test_toggle_focus(self): assert self.aws_shell.cli.current_buffer_name == u'DEFAULT_BUFFER' self.feed_key(Keys.F9) assert self.aws_shell.cli.current_buffer_name == u'clidocs' - def test_F10(self): + def test_press_exit(self): self.feed_key(Keys.F10) assert self.aws_shell.cli.is_exiting diff --git a/tests/unit/test_toolbar.py b/tests/unit/test_toolbar.py index aec722a..e372912 100644 --- a/tests/unit/test_toolbar.py +++ b/tests/unit/test_toolbar.py @@ -27,7 +27,8 @@ def setUp(self): lambda: self.aws_shell.model_completer.match_fuzzy, lambda: self.aws_shell.enable_vi_bindings, lambda: self.aws_shell.show_completion_columns, - lambda: self.aws_shell.show_help) + lambda: self.aws_shell.show_help, + self.aws_shell.key_bindings) def test_toolbar_on(self): self.aws_shell.model_completer.match_fuzzy = True diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index bd9f9b0..fb87fa4 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -73,7 +73,9 @@ def test_can_use_as_context_manager(self): filename = f.name f.write("foobar") f.flush() - self.assertEqual(open(filename).read(), "foobar") + f = open(filename) + self.assertEqual(f.read(), "foobar") + f.close() def test_is_removed_after_exiting_context(self): with temporary_file('w') as f: