Skip to content

Commit

Permalink
[Interactive] Optimize the visualization of help text when the window…
Browse files Browse the repository at this point in the history
… is reduced horizontally (#6611)
  • Loading branch information
ReaNAiveD authored Aug 14, 2023
1 parent 129c37f commit 115504f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 27 deletions.
4 changes: 4 additions & 0 deletions src/interactive/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Release History
===============

0.5.3
+++++
* Optimize the visualization of help text when the window is reduced horizontally

0.5.2
+++++
* Add command skipped message in Scenario Execution Mode
Expand Down
2 changes: 1 addition & 1 deletion src/interactive/azext_interactive/azclishell/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

VERSION = '0.5.2'
VERSION = '0.5.3'
42 changes: 37 additions & 5 deletions src/interactive/azext_interactive/azclishell/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,15 @@ def on_input_timeout(self, cli):
self._update_default_info()

cli.buffers['description'].reset(
initial_document=Document(self.description_docs, cursor_position=0))
initial_document=Document(self._wrap_desc_param(self.description_docs), cursor_position=0))
cli.buffers['parameter'].reset(
initial_document=Document(self.param_docs))
initial_document=Document(self._wrap_desc_param(self.param_docs)))
cli.buffers['examples'].reset(
initial_document=Document(self.example_docs))
cli.buffers['default_values'].reset(
initial_document=Document(
u'{}'.format(self.config_default if self.config_default else 'No Default Values')))
self._update_help_text()
self._update_toolbar()
cli.request_redraw()

Expand All @@ -246,6 +247,21 @@ def redraw_scenario_recommendation_info(self):
initial_document=Document(u'{}'.format(scenarios_rec_info)))
self.cli.request_redraw()

def _desc_param_buffer_width(self):
_, cols = get_window_dim()
# The rightmost column in window doesn't seem to be used
cols = int(cols) - 1
if self.config.get_boolean('Layout', 'command_description') \
and self.config.get_boolean('Layout', 'param_description'):
return (cols - 1) // 2
else:
return cols

def _wrap_desc_param(self, content, max_lines=4):
width = self._desc_param_buffer_width()
from textwrap import fill
return fill(content, width=width, max_lines=max_lines, placeholder='...')

def _space_examples(self, list_examples, rows, section_value):
""" makes the example text """
examples_with_index = []
Expand Down Expand Up @@ -277,6 +293,25 @@ def _space_examples(self, list_examples, rows, section_value):

return example + page_number + ' CTRL+Y (^) CTRL+N (v)'

def _update_help_text(self):
_, cols = get_window_dim()
cols = int(cols) - 1

from .configuration import GESTURE_INFO, GESTURE_LENGTH
from textwrap import fill
lines = []
for key in GESTURE_INFO:
# Build the help text of each GESTURE_INFO, use `fill` to support wrap(but here we fix the max_lines to 1)
# `subsequent_indent` is to align the lines of GESTURE_INFO with the first line
# e.g.
# %%[cmd] : set a scope, and scopes
# can be chained
lines.append(fill(GESTURE_INFO[key], initial_indent=key.ljust(GESTURE_LENGTH) + ': ',
subsequent_indent=' ' * (GESTURE_LENGTH + 2), width=cols, max_lines=1,
placeholder='...'))

self.cli.buffers['symbols'].reset(initial_document=Document(u'{}'.format('\n'.join(lines))))

def _update_toolbar(self):
cli = self.cli
_, cols = get_window_dim()
Expand Down Expand Up @@ -956,9 +991,6 @@ def run(self):
self.cli_ctx.get_progress_controller().init_progress(ShellProgressView())
self.cli_ctx.get_progress_controller = self.progress_patch

from .configuration import SHELL_HELP
self.cli.buffers['symbols'].reset(
initial_document=Document(u'{}'.format(SHELL_HELP)))
# flush telemetry for new commands and send successful interactive mode entry event
telemetry.set_success()
telemetry.flush()
Expand Down
31 changes: 10 additions & 21 deletions src/interactive/azext_interactive/azclishell/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,19 @@

GESTURE_INFO = {
# pylint: disable=line-too-long
SELECT_SYMBOL['search'] + ' [keyword]': "search for commands and scenarios",
SELECT_SYMBOL['search'] + '[keyword]': "search for commands and scenarios",
SELECT_SYMBOL['outside'] + "[cmd]": "use commands outside the application",
SELECT_SYMBOL['example'] + " [num]": "complete a recommended scenario step by step",
"[cmd] + [param] +" + "\"" + SELECT_SYMBOL[
'query'] + "[query]" + "\"": "Inject jmespath query from previous command",
"\"" + SELECT_SYMBOL['query'] + "[query]" + "\"": "Jmespath query of the previous command",
"[cmd] " + SELECT_SYMBOL['example'] + " [num]": "do a step by step tutorial of example",
SELECT_SYMBOL['example'] + "[num]": "complete a recommended scenario step by step",
"[cmd][param]" + SELECT_SYMBOL['query'] + "[query]": "Inject jmespath query from previous command",
SELECT_SYMBOL['query'] + "[query]": "Jmespath query of the previous command",
"[cmd]" + SELECT_SYMBOL['example'] + "[num]": "do a step by step tutorial of example",
SELECT_SYMBOL['exit_code']: "get the exit code of the previous command",
SELECT_SYMBOL['scope'] + '[cmd]': "set a scope, and scopes can be chained with spaces",
SELECT_SYMBOL['scope'] + ' ' + SELECT_SYMBOL['unscope']: "go back a scope",
SELECT_SYMBOL['scope'] + SELECT_SYMBOL['unscope']: "go back a scope",
}

CONFIG_FILE_NAME = 'shell-config'
GESTURE_LENGTH = max(len(key) for key in GESTURE_INFO) + 1


def help_text(values):
""" reformats the help text """
result = ""
for key in values:
# ' '.join('' for x in range(GESTURE_LENGTH - len(key))) is used to make the help text aligned
# Example: If values = {'/ [keyword]': 'description1', '#[cmd]': 'description2'}, the result will be:'/ [keyword]: description1\n#[cmd] : description2\n'
result += key + ' '.join('' for x in range(GESTURE_LENGTH - len(key))) + ': ' + values[key] + '\n'
return result


SHELL_HELP = help_text(GESTURE_INFO)
GESTURE_LENGTH = max(len(key) for key in GESTURE_INFO)


class Configuration(object):
Expand Down Expand Up @@ -150,6 +136,9 @@ def update(self):
with open(os.path.join(self.config_dir, CONFIG_FILE_NAME), 'w') as config_file:
self.config.write(config_file)

def get_boolean(self, section, option):
return self.BOOLEAN_STATES[self.config.get(section, option)]


def ask_user_for_telemetry():
""" asks the user for if we can collect telemetry """
Expand Down

0 comments on commit 115504f

Please sign in to comment.