Skip to content

Commit 097a20b

Browse files
authored
Fixes/changes to interactive history (#5636)
* fixed history persistence, logic * version bump * single source for history, fix clear-history
1 parent 62a137c commit 097a20b

File tree

4 files changed

+59
-51
lines changed

4 files changed

+59
-51
lines changed

src/command_modules/azure-cli-interactive/HISTORY.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
Release History
44
===============
55

6+
0.3.17
7+
++++++
8+
* Persist history across different sessions
9+
* Fixed history while in scope
10+
611
0.3.16
712
++++++
813
* Fix issue where user is prompted to login when using interactive mode in Cloud Shell.

src/command_modules/azure-cli-interactive/azclishell/app.py

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from azclishell.frequency_heuristic import DISPLAY_TIME, frequency_heuristic
3535
from azclishell.gather_commands import add_new_lines, GatherCommands
3636
from azclishell.key_bindings import InteractiveKeyBindings
37-
from azclishell.layout import create_layout, create_tutorial_layout, set_scope
37+
from azclishell.layout import create_layout, create_tutorial_layout, set_scope, get_scope
3838
from azclishell.progress import progress_view
3939
from azclishell.telemetry import Telemetry
4040
from azclishell.threads import LoadCommandTableThread
@@ -88,8 +88,8 @@ def restart_completer(shell_ctx):
8888
# pylint: disable=too-many-instance-attributes
8989
class AzInteractiveShell(object):
9090

91-
def __init__(self, cli_ctx, style=None, completer=None, styles=None,
92-
lexer=None, history=InMemoryHistory(),
91+
def __init__(self, cli_ctx, style=None, completer=None,
92+
lexer=None, history=None,
9393
app=None, input_custom=sys.stdin, output_custom=None,
9494
user_feedback=False, intermediate_sleep=.25, final_sleep=4):
9595

@@ -142,7 +142,7 @@ def __init__(self, cli_ctx, style=None, completer=None, styles=None,
142142
def __call__(self):
143143

144144
if self.cli_ctx.data["az_interactive_active"]:
145-
logger.warning("You're in the interactive shell already.\n")
145+
logger.warning("You're in the interactive shell already.")
146146
return
147147

148148
if self.config.BOOLEAN_STATES[self.config.config.get('DEFAULT', 'firsttime')]:
@@ -476,60 +476,59 @@ def _special_cases(self, cmd, outside):
476476
continue_flag = False
477477
args = parse_quotes(cmd)
478478
cmd_stripped = cmd.strip()
479-
if cmd_stripped and cmd.split(' ', 1)[0].lower() == 'az':
480-
self.telemetry.track_ssg('az', cmd)
481-
cmd = ' '.join(cmd.split()[1:])
482-
if self.default_command:
483-
cmd = self.default_command + " " + cmd
484479

485-
if cmd_stripped == "quit" or cmd_stripped == "exit":
480+
if not cmd_stripped and cmd:
481+
# add scope if there are only spaces
482+
cmd = self.default_command + " " + cmd
483+
elif cmd_stripped == "quit" or cmd_stripped == "exit":
486484
break_flag = True
487485
elif cmd_stripped == "clear-history":
488-
# clears the history, but only when you restart
489-
outside = True
490-
cmd = 'echo -n "" >' +\
491-
os.path.join(
492-
self.config.config_dir(),
493-
self.config.get_history())
486+
continue_flag = True
487+
self.reset_history()
494488
elif cmd_stripped == CLEAR_WORD:
495489
outside = True
496490
cmd = CLEAR_WORD
497-
if cmd_stripped:
498-
if cmd_stripped[0] == SELECT_SYMBOL['outside']:
499-
cmd = cmd_stripped[1:]
500-
outside = True
501-
if cmd.strip() and cmd.split()[0] == 'cd':
502-
self.handle_cd(parse_quotes(cmd))
503-
continue_flag = True
504-
self.telemetry.track_ssg('outside', '')
491+
elif cmd_stripped[0] == SELECT_SYMBOL['outside']:
492+
cmd = cmd_stripped[1:]
493+
outside = True
494+
if cmd.strip() and cmd.split()[0] == 'cd':
495+
self.handle_cd(parse_quotes(cmd))
496+
continue_flag = True
497+
self.telemetry.track_ssg('outside', '')
505498

506-
elif cmd_stripped[0] == SELECT_SYMBOL['exit_code']:
507-
meaning = "Success" if self.last_exit == 0 else "Failure"
499+
elif cmd_stripped[0] == SELECT_SYMBOL['exit_code']:
500+
meaning = "Success" if self.last_exit == 0 else "Failure"
508501

509-
print(meaning + ": " + str(self.last_exit), file=self.output)
510-
continue_flag = True
511-
self.telemetry.track_ssg('exit code', '')
512-
elif SELECT_SYMBOL['query'] in cmd_stripped and self.last and self.last.result:
513-
continue_flag = self.handle_jmespath_query(args)
514-
self.telemetry.track_ssg('query', '')
502+
print(meaning + ": " + str(self.last_exit), file=self.output)
503+
continue_flag = True
504+
self.telemetry.track_ssg('exit code', '')
505+
elif SELECT_SYMBOL['query'] in cmd_stripped and self.last and self.last.result:
506+
continue_flag = self.handle_jmespath_query(args)
507+
self.telemetry.track_ssg('query', '')
515508

516-
elif args[0] == '--version' or args[0] == '-v':
517-
try:
518-
continue_flag = True
519-
self.cli_ctx.show_version()
520-
except SystemExit:
521-
pass
522-
elif "|" in cmd or ">" in cmd:
509+
elif args[0] == '--version' or args[0] == '-v':
510+
try:
511+
continue_flag = True
512+
self.cli_ctx.show_version()
513+
except SystemExit:
514+
pass
515+
elif SELECT_SYMBOL['example'] in cmd:
516+
cmd, continue_flag = self.handle_example(cmd, continue_flag)
517+
self.telemetry.track_ssg('tutorial', cmd)
518+
elif SELECT_SYMBOL['scope'] == cmd_stripped[0:2]:
519+
continue_flag, cmd = self.handle_scoping_input(continue_flag, cmd, cmd_stripped)
520+
else:
521+
# not a special character; add scope and remove 'az'
522+
if self.default_command:
523+
cmd = self.default_command + " " + cmd
524+
elif cmd.split(' ', 1)[0].lower() == 'az':
525+
self.telemetry.track_ssg('az', cmd)
526+
cmd = ' '.join(cmd.split()[1:])
527+
if "|" in cmd or ">" in cmd:
523528
# anything I don't parse, send off
524529
outside = True
525530
cmd = "az " + cmd
526531

527-
elif SELECT_SYMBOL['example'] in cmd:
528-
cmd, continue_flag = self.handle_example(cmd, continue_flag)
529-
self.telemetry.track_ssg('tutorial', cmd)
530-
elif len(cmd_stripped) > 2 and SELECT_SYMBOL['scope'] == cmd_stripped[0:2]:
531-
continue_flag, cmd = self.handle_scoping_input(continue_flag, cmd, cmd_stripped)
532-
533532
return break_flag, continue_flag, outside, cmd
534533

535534
def handle_jmespath_query(self, args):
@@ -604,8 +603,7 @@ def handle_scoping_input(self, continue_flag, cmd, text):
604603
cmd = cmd.replace(SELECT_SYMBOL['scope'], '')
605604
self.telemetry.track_ssg('scope command', value)
606605

607-
elif SELECT_SYMBOL['unscope'] == default_split[0] and \
608-
len(self.default_command.split()) > 0:
606+
elif SELECT_SYMBOL['unscope'] == default_split[0] and self.default_command.split():
609607

610608
value = self.default_command.split()[-1]
611609
self.default_command = ' ' + ' '.join(self.default_command.split()[:-1])
@@ -621,6 +619,12 @@ def handle_scoping_input(self, continue_flag, cmd, text):
621619
default_split = default_split[1:]
622620
return continue_flag, cmd
623621

622+
def reset_history(self):
623+
history_file_path = os.path.join(self.config.config_dir, self.config.get_history())
624+
os.remove(history_file_path)
625+
self.history = FileHistory(history_file_path)
626+
self.cli.buffers[DEFAULT_BUFFER].history = self.history
627+
624628
def cli_execute(self, cmd):
625629
""" sends the command to the CLI to be executed """
626630

@@ -709,9 +713,9 @@ def run(self):
709713
# when the user pressed Control D
710714
break
711715
else:
716+
self.history.append(text)
712717
b_flag, c_flag, outside, cmd = self._special_cases(cmd, outside)
713-
if not self.default_command:
714-
self.history.append(text)
718+
715719
if b_flag:
716720
break
717721
if c_flag:

src/command_modules/azure-cli-interactive/azclishell/key_bindings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ def pan_down(event):
6666
def config_settings(event):
6767
""" opens the configuration """
6868
shell_ctx.telemetry.track_key('F1')
69-
7069
shell_ctx.is_prompting = True
7170
config = shell_ctx.config
7271
answer = ""

src/command_modules/azure-cli-interactive/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
cmdclass = {}
1515

1616
# Version is also defined in azclishell.__init__.py.
17-
VERSION = "0.3.16"
17+
VERSION = "0.3.17"
1818
# The full list of classifiers is available at
1919
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
2020
CLASSIFIERS = [

0 commit comments

Comments
 (0)