using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core.Commands; using Tango.SharedUI; namespace Tango.Console { /// /// Represents a command prompt console control view model. /// /// public class ConsoleControlVM : ViewModel { private int _historyIndex; private List _knownSuggestions; /// /// Occurs when a command is executing. /// public event EventHandler CommandExecuting; /// /// Gets the commands history. /// public ObservableCollection Commands { get; private set; } private ConsoleCommand _currentCommand; /// /// Gets or sets the current command. /// public ConsoleCommand CurrentCommand { get { return _currentCommand; } set { _currentCommand = value; RaisePropertyChangedAuto(); } } private List _suggestions; /// /// Gets or sets the available auto complete suggestions. /// public List Suggestions { get { return _suggestions; } set { _suggestions = value; RaisePropertyChangedAuto(); } } /// /// Executes the current command. /// public RelayCommand ExecuteCommand { get; set; } /// /// Navigates down through the commands history. /// public RelayCommand HistoryDownCommand { get; set; } /// /// Navigates up through the commands history. /// public RelayCommand HistoryUpCommand { get; set; } /// /// Initializes a new instance of the class. /// public ConsoleControlVM() { Commands = new ObservableCollection(); CurrentCommand = new ConsoleCommand() { WorkingFolder = Environment.CurrentDirectory }; ExecuteCommand = new RelayCommand(Execute); HistoryDownCommand = new RelayCommand(HistoryDown); HistoryUpCommand = new RelayCommand(HistoryUp); _knownSuggestions = new List(ConsoleDictionary.GetKnownCommands().Select(x => new ConsoleSuggestion() { Type = ConsoleSuggestionType.Command, Name = x.Name, Description = x.Description })); Suggestions = new List(_knownSuggestions); } private void HistoryUp() { if (_historyIndex > 0) { _historyIndex--; CreateNew(CurrentCommand.WorkingFolder, false, GetDistinctCommands()[_historyIndex].CommandText, true); } } private void HistoryDown() { if (_historyIndex < GetDistinctCommands().Count - 1) { _historyIndex++; CreateNew(CurrentCommand.WorkingFolder, false, GetDistinctCommands()[_historyIndex].CommandText, true); } } private void Execute() { if (CurrentCommand != null) { if (!CurrentCommand.CommandText.IsNotNullOrEmpty()) { CreateNew(CurrentCommand.WorkingFolder, true); return; } if (CurrentCommand.CommandText.ToLower() == "clear") { Clear(); return; } CurrentCommand.IsExecuting = true; ConsoleCommandExecutingEventArgs args = new ConsoleCommandExecutingEventArgs(CurrentCommand, (result) => { CurrentCommand.IsExecuting = false; CurrentCommand.Output = result.Output; CreateNew(result.WorkingFolder, true); AppendSuggestions(result.Suggestions); }); CommandExecuting?.Invoke(this, args); } } /// /// Concatenates the specified suggestions to the current suggestions. /// /// The suggestions. public void AppendSuggestions(List suggestions) { Suggestions = _knownSuggestions.Concat(suggestions).OrderBy(x => x.Name).ToList(); } /// /// Clears the console. /// public void Clear() { Commands.Clear(); CreateNew(CurrentCommand.WorkingFolder, false); } /// /// Clears and creates a new current command with the specified working folder. /// /// The working folder. public void Clear(String workingFolder) { Commands.Clear(); CreateNew(workingFolder, false); } private void CreateNew(String workingFolder, bool pushCurrent, String commandText = null, bool fromHistory = false) { if (pushCurrent) { Commands.Add(CurrentCommand); _historyIndex = GetDistinctCommands().Count; } CurrentCommand = new ConsoleCommand() { WorkingFolder = workingFolder != null ? workingFolder : CurrentCommand.WorkingFolder, CommandText = commandText, IsFromHistory = fromHistory }; } private List GetDistinctCommands() { return Commands.Where(x => !x.IsFromHistory).ToList(); } } }