Skip to content

Commit cf6e030

Browse files
committed
Refactor getting and setting of config options code.
Config options are now stored in AWSShell attributes and loaded on startup. On shutdown, the configs are set based on the AWSShell attributes. The KeyManager class expects a callable to get/set the config options: For the get methods we simply use a lambda that wraps the AWSShell atribute; for the set methods we're forced to define actual methods. Also moves the call to AWSShell.stop_input_and_refresh_cli to within the key handlers of KeyManager. In the future we might want to wrap the calls to self.model_completer.match_fuzzy with a convenience function. Updates tests and docstrings.
1 parent 696684b commit cf6e030

File tree

5 files changed

+210
-178
lines changed

5 files changed

+210
-178
lines changed

awsshell/app.py

Lines changed: 104 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ class AWSShell(object):
5656
:type config_section: :class:`configobj.Section`
5757
:param config_section: Convenience attribute to access the main section
5858
of the config.
59+
60+
:type model_completer: :class:`AWSCLIModelCompleter`
61+
:param model_completer: Matches input with completions. `AWSShell` sets
62+
and gets the attribute `AWSCLIModelCompleter.match_fuzzy`.
63+
64+
:type enable_vi_bindings: bool
65+
:param enable_vi_bindings: If True, enables Vi key bindings. Else, Emacs
66+
key bindings are enabled.
67+
68+
:type show_completion_columns: bool
69+
param show_completion_columns: If True, completions are shown in multiple
70+
columns. Else, completions are shown in a single scrollable column.
71+
72+
:type show_help: bool
73+
:param show_help: If True, shows the help pane. Else, hides the help pane.
74+
75+
:type theme: str
76+
:param theme: The pygments theme.
5977
"""
6078

6179
def __init__(self, completer, model_completer, history, docs):
@@ -66,19 +84,36 @@ def __init__(self, completer, model_completer, history, docs):
6684
self._docs = docs
6785
self.current_docs = u''
6886
self.refresh_cli = False
69-
self._init_config()
87+
self.load_config()
7088

71-
def _init_config(self):
89+
def load_config(self):
90+
"""Loads the config from the config file or template."""
7291
config = Config()
7392
self.config_obj = config.load('awsshellrc')
7493
self.config_section = self.config_obj['aws-shell']
75-
self.model_completer.match_fuzzy = self.match_fuzzy()
94+
self.model_completer.match_fuzzy = self.config_section.as_bool(
95+
'match_fuzzy')
96+
self.enable_vi_bindings = self.config_section.as_bool(
97+
'enable_vi_bindings')
98+
self.show_completion_columns = self.config_section.as_bool(
99+
'show_completion_columns')
100+
self.show_help = self.config_section.as_bool('show_help')
101+
self.theme = self.config_section['theme']
102+
103+
def save_config(self):
104+
"""Saves the config to the config file."""
105+
self.config_section['match_fuzzy'] = self.model_completer.match_fuzzy
106+
self.config_section['enable_vi_bindings'] = self.enable_vi_bindings
107+
self.config_section['show_completion_columns'] = \
108+
self.show_completion_columns
109+
self.config_section['show_help'] = self.show_help
110+
self.config_section['theme'] = self.theme
111+
self.config_obj.write()
76112

77113
@property
78114
def cli(self):
79115
if self._cli is None or self.refresh_cli:
80-
self._cli = self.create_cli_interface(
81-
self.show_completion_columns())
116+
self._cli = self.create_cli_interface(self.show_completion_columns)
82117
self.refresh_cli = False
83118
return self._cli
84119

@@ -90,7 +125,7 @@ def run(self):
90125
except InputInterrupt:
91126
pass
92127
except (KeyboardInterrupt, EOFError):
93-
self.config_obj.write()
128+
self.save_config()
94129
break
95130
else:
96131
if text.strip() in ['quit', 'exit']:
@@ -135,125 +170,86 @@ def stop_input_and_refresh_cli(self):
135170
self.cli.request_redraw()
136171
raise InputInterrupt
137172

138-
def match_fuzzy(self, match_fuzzy=None):
139-
"""Setter/Getter for fuzzy matching mode.
140-
141-
Used by `prompt_toolkit.KeyBindingManager`, which expects this method to
142-
be callable so we can't use the standard @property and @attrib.setter.
143-
144-
:type match_fuzzy: bool
145-
:param match_fuzzy: (Optional) The match fuzzy flag.
146-
147-
:rtype: bool
148-
:return: The match fuzzy flag.
149-
"""
150-
CFG_FUZZY = 'match_fuzzy'
151-
if match_fuzzy is not None:
152-
self.model_completer.match_fuzzy = match_fuzzy
153-
self.config_section[CFG_FUZZY] = match_fuzzy
154-
return self.config_section.as_bool(CFG_FUZZY)
155-
156-
def enable_vi_bindings(self, enable_vi_bindings=None, refresh_ui=False):
157-
"""Setter/Getter for vi mode keybindings.
158-
159-
If vi mode is off, emacs mode is enabled by default by `prompt_toolkit`.
160-
161-
TODO: `enable_vi_bindings`, `show_completion_columns`, and `show_help`
162-
could use a refactor. `prompt_toolkit.KeyBindingManager` seems to make
163-
this a little tricky.
173+
def create_layout(self, display_completions_in_columns, toolbar):
174+
return create_default_layout(
175+
self, u'aws> ', reserve_space_for_menu=True,
176+
display_completions_in_columns=display_completions_in_columns,
177+
get_bottom_toolbar_tokens=toolbar.handler)
164178

165-
Used by `prompt_toolkit.KeyBindingManager`, which expects this method to
166-
be callable so we can't use the standard @property and @attrib.setter.
179+
def create_buffer(self, completer, history):
180+
return Buffer(
181+
history=history,
182+
auto_suggest=AutoSuggestFromHistory(),
183+
enable_history_search=True,
184+
completer=completer,
185+
complete_while_typing=Always(),
186+
accept_action=AcceptAction.RETURN_DOCUMENT)
167187

168-
:type enable_vi_bindings: bool
169-
:param enable_vi_bindings: (Optional) The enable vi bindings flag.
188+
def create_key_manager(self):
189+
"""Creates the :class:`KeyManager`.
170190
171-
:type refresh_ui: bool
172-
:param refresh_ui: (Optional) True: Stops input and refreshes the cli.
191+
The inputs to KeyManager are expected to be callable, so we can't
192+
use the standard @property and @attrib.setter for these attributes.
193+
Lambdas cannot contain assignments so we're forced to define setters.
173194
174-
:rtype: bool
175-
:return: The enable vi bindings flag.
195+
:rtype: :class:`KeyManager`
196+
:return: A KeyManager with callables to set the toolbar options. Also
197+
includes the method stop_input_and_refresh_cli to ensure certain
198+
options take effect within the current session.
176199
"""
177-
CFG_VI = 'enable_vi_bindings'
178-
if enable_vi_bindings is not None:
179-
self.config_section[CFG_VI] = enable_vi_bindings
180-
if refresh_ui:
181-
self.stop_input_and_refresh_cli()
182-
return self.config_section.as_bool(CFG_VI)
183-
184-
def show_completion_columns(self, show_completion_columns=None,
185-
refresh_ui=False):
186-
"""Setter/Getter for showing the completions in columns flag.
187-
188-
Used by `prompt_toolkit.KeyBindingManager`, which expects this method to
189-
be callable so we can't use the standard @property and @attrib.setter.
190200

191-
:type show_completion_columns: bool
192-
:param show_completion_columns: (Optional) The show completions in
193-
multiple columns flag.
201+
def set_match_fuzzy(match_fuzzy):
202+
"""Setter for fuzzy matching mode.
194203
195-
:type refresh_ui: bool
196-
:param refresh_ui: (Optional) True: Stops input and refreshes the cli.
204+
:type match_fuzzy: bool
205+
:param match_fuzzy: The match fuzzy flag.
206+
"""
207+
self.model_completer.match_fuzzy = match_fuzzy
197208

198-
:rtype: bool
199-
:return: The show completions in multiple columns flag.
200-
"""
201-
CFG_COLUMNS = 'show_completion_columns'
202-
if show_completion_columns is not None:
203-
self.config_section[CFG_COLUMNS] = show_completion_columns
204-
if refresh_ui:
205-
self.stop_input_and_refresh_cli()
206-
return self.config_section.as_bool(CFG_COLUMNS)
209+
def set_enable_vi_bindings(enable_vi_bindings):
210+
"""Setter for vi mode keybindings.
207211
208-
def show_help(self, show_help=None, refresh_ui=False):
209-
"""Setter/Getter for showing the help container flag.
212+
If vi mode is off, emacs mode is enabled by default by
213+
`prompt_toolkit`.
210214
211-
Used by `prompt_toolkit.KeyBindingManager`, which expects this method to
212-
be callable so we can't use the standard @property and @attrib.setter.
215+
:type enable_vi_bindings: bool
216+
:param enable_vi_bindings: The enable Vi bindings flag.
217+
"""
218+
self.enable_vi_bindings = enable_vi_bindings
213219

214-
:type show_help: bool
215-
:param show_help: (Optional) The show help flag.
220+
def set_show_completion_columns(show_completion_columns):
221+
"""Setter for showing the completions in columns flag.
216222
217-
:type refresh_ui: bool
218-
:param refresh_ui: (Optional) True: Stops input and refreshes the cli.
223+
:type show_completion_columns: bool
224+
:param show_completion_columns: The show completions in
225+
multiple columns flag.
226+
"""
227+
self.show_completion_columns = show_completion_columns
219228

220-
:rtype: bool
221-
:return: The show help flag.
222-
"""
223-
CFG_HELP = 'show_help'
224-
if show_help is not None:
225-
self.config_section[CFG_HELP] = show_help
226-
if refresh_ui:
227-
self.stop_input_and_refresh_cli()
228-
return self.config_section.as_bool(CFG_HELP)
229+
def set_show_help(show_help):
230+
"""Setter for showing the help container flag.
229231
230-
def create_layout(self, display_completions_in_columns, toolbar):
231-
return create_default_layout(
232-
self, u'aws> ', reserve_space_for_menu=True,
233-
display_completions_in_columns=display_completions_in_columns,
234-
get_bottom_toolbar_tokens=toolbar.handler)
232+
:type show_help: bool
233+
:param show_help: The show help flag.
234+
"""
235+
self.show_help = show_help
235236

236-
def create_buffer(self, completer, history):
237-
return Buffer(
238-
history=history,
239-
auto_suggest=AutoSuggestFromHistory(),
240-
enable_history_search=True,
241-
completer=completer,
242-
complete_while_typing=Always(),
243-
accept_action=AcceptAction.RETURN_DOCUMENT)
237+
return KeyManager(
238+
lambda: self.model_completer.match_fuzzy, set_match_fuzzy,
239+
lambda: self.enable_vi_bindings, set_enable_vi_bindings,
240+
lambda: self.show_completion_columns, set_show_completion_columns,
241+
lambda: self.show_help, set_show_help,
242+
self.stop_input_and_refresh_cli)
244243

245244
def create_application(self, completer, history,
246245
display_completions_in_columns):
247-
self.key_manager = KeyManager(
248-
self.match_fuzzy,
249-
self.enable_vi_bindings,
250-
self.show_completion_columns,
251-
self.show_help)
252-
style_factory = StyleFactory(self.config_section['theme'])
253-
toolbar = Toolbar(self.match_fuzzy,
254-
self.enable_vi_bindings,
255-
self.show_completion_columns,
256-
self.show_help)
246+
self.key_manager = self.create_key_manager()
247+
toolbar = Toolbar(
248+
lambda: self.model_completer.match_fuzzy,
249+
lambda: self.enable_vi_bindings,
250+
lambda: self.show_completion_columns,
251+
lambda: self.show_help)
252+
style_factory = StyleFactory(self.theme)
257253
buffers = {
258254
'clidocs': Buffer(read_only=True)
259255
}
@@ -271,7 +267,7 @@ def create_application(self, completer, history,
271267
)
272268

273269
def on_input_timeout(self, cli):
274-
if not self.show_help():
270+
if not self.show_help:
275271
return
276272
document = cli.current_buffer.document
277273
text = document.text

0 commit comments

Comments
 (0)