private void DoSyntaxHighlighting(RichCommandLineContext context) { if (Highlighter == null) { return; } bool highlightChanged = false; try { highlightChanged = Highlighter.TryHighlight(context); } catch (Exception ex) { if (ThrowOnSyntaxHighlightException) { throw; } else { PowerLogger.LogLine("Syntax highlighting threw exception: " + ex.ToString()); } } if (highlightChanged) { context.RefreshConsole(0, 0); } }
/// <summary> /// Handles the tab key by calling all registered tab completion handlers. /// </summary> /// <param name="context">Context that can be used to inspect the current command line to perform tab completion</param> public void Handle(RichCommandLineContext context) { context.Intercept = true; context.RefreshTokenInfo(); try { foreach (var handler in TabCompletionHandlers) { if (handler.TryTabComplete(context)) { break; } } } catch(Exception ex) { if (ThrowOnTabCompletionHandlerException) { throw; } else { PowerLogger.LogLine("Tab completion handler threw exception: " + ex.ToString()); } } }
/// <summary> /// Handles the tab key by calling all registered tab completion handlers. /// </summary> /// <param name="context">Context that can be used to inspect the current command line to perform tab completion</param> public void Handle(RichCommandLineContext context) { context.Intercept = true; context.RefreshTokenInfo(); try { foreach (var handler in TabCompletionHandlers) { if (handler.TryTabComplete(context)) { break; } } } catch (Exception ex) { if (ThrowOnTabCompletionHandlerException) { throw; } else { PowerLogger.LogLine("Tab completion handler threw exception: " + ex.ToString()); } } }
public override bool CanAssist(RichCommandLineContext context) { Providers.Clear(); Providers.AddRange(standardProviders); CommandLineArgument targetArgument = null; if (context.PreviousNonWhitespaceToken != null && ArgParser.IsDashSpecifiedArgumentIdentifier(context.PreviousNonWhitespaceToken.Value)) { var candidate = context.PreviousNonWhitespaceToken.Value.Substring(1); targetArgument = (from a in Definition.AllGlobalAndActionArguments where a.IsMatch(candidate) select a).SingleOrDefault(); } if (targetArgument != null) { foreach (var assistant in targetArgument.Metadata.Metas <ArgContextualAssistant>()) { var dynamicProvider = assistant.GetContextAssistProvider(Definition); Providers.Add(dynamicProvider); } } foreach (var provider in Providers) { if (provider is PowerArgsContextAwareAssistant) { (provider as PowerArgsContextAwareAssistant).TargetArgument = targetArgument; } } var ret = base.CanAssist(context); return(ret); }
private void DoSyntaxHighlighting(RichCommandLineContext context) { if (Highlighter == null) { return; } bool highlightChanged = false; try { highlightChanged = Highlighter.TryHighlight(context); } catch (Exception ex) { if (ThrowOnSyntaxHighlightException) { throw; } } if (highlightChanged) { FireValueChanged(); } }
public bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { // don't even try mark tokens as invalid unless the cursor is on it if (readerContext.BufferPosition >= highlighterContext.CurrentToken.StartIndex && readerContext.BufferPosition < highlighterContext.CurrentToken.EndIndex) { return(false); } var currentToken = highlighterContext.CurrentToken.Value; var previousToken = PowerArgsRichCommandLineReader.FindPreviousNonWhitespaceToken(readerContext, highlighterContext); var firstToken = readerContext.Tokens[0].Value; CommandLineAction contextualAction = PowerArgsRichCommandLineReader.FindContextualAction(firstToken, definition); CommandLineArgument contextualArgument = PowerArgsRichCommandLineReader.FindContextualArgument(previousToken, contextualAction, definition); if (contextualArgument != null) { if (contextualArgument.TestIsValidAndRevivable(currentToken) == false) { // the current token either failed validation or could not be revived return(true); } } bool expectMatchingArg; CommandLineArgument currentTokenArgument = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(contextualAction, currentToken, out expectMatchingArg, definition); if (currentTokenArgument == null && expectMatchingArg) { // The current token starts with a - or /, but does not match a global or action specific argument, so we'll highlight the token red return(true); } return(false); }
private void HandleRightArrow(RichCommandLineContext context) { // todo - resolve special handling for the TextBox support if (context.Console.BufferWidth == 0) { if (context.Console.CursorLeft < context.Buffer.Count) { context.Console.CursorLeft += 1; } } else { if (context.Console.CursorLeft < context.Console.BufferWidth - 1 && context.BufferPosition < context.Buffer.Count) { context.Console.CursorLeft = context.Console.CursorLeft + 1; } else if (context.Console.CursorLeft == context.Console.BufferWidth - 1) { context.Console.CursorTop++; context.Console.CursorLeft = 0; } } context.Intercept = true; }
/// <summary> /// Returns true if the keyword is matched, false otherwise /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if the keyword matched, false otherwise</returns> public override bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { if (highlighterContext.IsLastToken) { return(false); } return(highlighterContext.CurrentToken.Value.Equals(keyword, comparison)); }
private void _SearchReader_HandleEnterKey(RichCommandLineContext searchReaderContext) { searchReaderContext.Intercept = true; if (latestResults.Count > 0) { SelectedValue = latestResults[selectedIndex]; searchReaderContext.IsFinished = true; } }
private void HandleDelete(RichCommandLineContext context) { if (context.BufferPosition < context.Buffer.Count) { context.Buffer.RemoveAt(context.BufferPosition); context.RefreshConsole(0, 0); } context.Intercept = true; }
private void _SearchReader_HandleKeyPressed(RichCommandLineContext searchReaderContext) { if (searchReaderContext.KeyPressed.Key == ConsoleKey.UpArrow || searchReaderContext.KeyPressed.Key == ConsoleKey.DownArrow) { return; } else { DoSearch(searchReaderContext.Buffer.ToNormalString()); } }
public void Handle(RichCommandLineContext context) { if (context.KeyPressed.Key == ConsoleKey.Delete) { HandleDelete(context); } else if (context.KeyPressed.Key == ConsoleKey.Backspace) { HandleBackspace(context); } }
/// <summary> /// Returns true if the token matches the keyword and the given conditional evaluation returns true /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if the token matches the keyword and the given conditional evaluation returns true</returns> public override bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { if (conditionEval(readerContext, highlighterContext)) { return(base.ShouldBeHighlighted(readerContext, highlighterContext)); } else { return(false); } }
public void Handle(RichCommandLineContext context) { if(context.KeyPressed.Key == ConsoleKey.Delete) { HandleDelete(context); } else if(context.KeyPressed.Key == ConsoleKey.Backspace) { HandleBackspace(context); } }
/// <summary> /// Writes the prompt message and takes over the console until the user makes a selection or cancels via the escape key. This method /// never returns a NoOp result. /// </summary> /// <param name="parentContext">context about the parent reader that we are assisting </param> /// <returns>A selection or cancellation result, never a NoOp</returns> public virtual ContextAssistResult DrawMenu(RichCommandLineContext parentContext) { try { DoSearchInternal(parentContext, null, true); return(ContextAssistResult.CreateInsertResult(parentContext, SelectedValue.RichDisplayText)); } catch (OperationCanceledException) { return(ContextAssistResult.Cancel); } }
public override bool CanAssist(RichCommandLineContext context) { if (TargetArgument != null && TargetArgument.ArgumentType.IsEnum) { Options.Clear(); Options.AddRange(Enum.GetNames(TargetArgument.ArgumentType).Select(name => ContextAssistSearchResult.FromString(name))); return(true); } else { return(false); } }
public override bool CanAssist(RichCommandLineContext context) { if ( context.CurrentTokenIndex == 0 && Definition.Actions.Count > 0) { Options.Clear(); Options.AddRange(Definition.Actions.Select(a => ContextAssistSearchResult.FromString(a.DefaultAlias))); return true; } else { return false; } }
public override bool CanAssist(RichCommandLineContext context) { if (TargetArgument != null && TargetArgument.ArgumentType.IsEnum) { Options.Clear(); Options.AddRange(Enum.GetNames(TargetArgument.ArgumentType).Select(name => ContextAssistSearchResult.FromString(name))); return true; } else { return false; } }
public override bool CanAssist(RichCommandLineContext context) { if (context.CurrentTokenIndex == 0 && Definition.Actions.Count > 0) { Options.Clear(); Options.AddRange(Definition.Actions.Select(a => ContextAssistSearchResult.FromString(a.DefaultAlias))); return(true); } else { return(false); } }
/// <summary> /// Returns true if the regular expression is matched, false otherwise /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if the regular expression is matched, false otherwise</returns> public override bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { var matches = regex.Matches(highlighterContext.CurrentToken.Value); foreach (Match match in matches) { if (match.Value == highlighterContext.CurrentToken.Value) { return(true); } } return(false); }
private void WriteCharacterForPressedKey(RichCommandLineContext context) { if (CursorPosition == Context.Buffer.Count) { Context.Buffer.Add(context.CharacterToWrite); } else { Context.Buffer.Insert(CursorPosition, context.CharacterToWrite); } CursorPosition++; }
/// <summary> /// Cycles through the inner providers and calls their CanAssist method until one of them returns true. /// If that happens, the first to return true is promoted to be the current provider. /// </summary> /// <param name="context">passed to inner providers to see if they can assist</param> /// <returns>true if one of the inner providers can assist, false otherwise</returns> public virtual bool CanAssist(RichCommandLineContext context) { CurrentProvider = null; foreach (var provider in Providers) { if (provider.CanAssist(context)) { CurrentProvider = provider; return(true); } } return(false); }
/// <summary> /// Cycles through the inner providers and calls their CanAssist method until one of them returns true. /// If that happens, the first to return true is promoted to be the current provider. /// </summary> /// <param name="context">passed to inner providers to see if they can assist</param> /// <returns>true if one of the inner providers can assist, false otherwise</returns> public virtual bool CanAssist(RichCommandLineContext context) { CurrentProvider = null; foreach (var provider in Providers) { if (provider.CanAssist(context)) { CurrentProvider = provider; return true; } } return false; }
private void HandleRightArrow(RichCommandLineContext context) { if (context.Console.CursorLeft < context.Console.BufferWidth - 1 && context.BufferPosition < context.Buffer.Count) { context.Console.CursorLeft = context.Console.CursorLeft + 1; } else if (context.Console.CursorLeft == context.Console.BufferWidth - 1) { context.Console.CursorTop++; context.Console.CursorLeft = 0; } context.Intercept = true; }
/// <summary> /// Searches the reader's tokens for a non whitespace token that preceeds the current token /// </summary> /// <param name="readerContext">the reader context to inspect</param> /// <param name="highlighterContext">the highlighter context to inspect</param> /// <returns>a non whitespace token that preceeds the current token or null if no such token is found</returns> public static string FindPreviousNonWhitespaceToken(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { string previousToken = null; for (int i = highlighterContext.CurrentTokenIndex - 1; i >= 0; i--) { if (string.IsNullOrWhiteSpace(readerContext.Tokens[i].Value) == false) { previousToken = readerContext.Tokens[i].Value; break; } } return(previousToken); }
/// <summary> /// Creates a result that replaces the current token with the given selection. /// </summary> /// <param name="context">Context from the parent reader</param> /// <param name="selection">The selection string to insert</param> /// <returns>a result that replaces the current token with the given selection</returns> public static ContextAssistResult CreateInsertResult(RichCommandLineContext context, ConsoleString selection) { context.RefreshTokenInfo(); var ret = new ContextAssistResult(); bool hasInserted = false; var newBuffer = new List <ConsoleCharacter>(); foreach (var token in context.Tokens) { if (context.IsCursorOnToken(token)) { if (string.IsNullOrWhiteSpace(token.Value)) { newBuffer.AddRange(context.GetBufferSubstringFromToken(token)); ret.ConsoleRefreshLeftOffset = selection.Length; } else { var tokenOffset = context.BufferPosition - token.StartIndex; ret.ConsoleRefreshLeftOffset = selection.Length - tokenOffset; } if (hasInserted == false) { hasInserted = true; // cursor is on the current token newBuffer.AddRange(selection); } } else { // this token not be modified newBuffer.AddRange(context.GetBufferSubstringFromToken(token)); } } if (hasInserted == false) { hasInserted = true; // cursor is on the current token newBuffer.AddRange(selection); ret.ConsoleRefreshLeftOffset = selection.Length; } ret.StatusCode = ContextAssistResultStatusCode.Success; ret.NewBuffer = newBuffer; return(ret); }
public void Handle(RichCommandLineContext context) { if(context.KeyPressed.Key == ConsoleKey.Home) { context.Console.CursorTop = context.ConsoleStartTop; context.Console.CursorLeft = context.ConsoleStartLeft; context.Intercept = true; } else if(context.KeyPressed.Key == ConsoleKey.End) { context.Console.CursorTop = context.ConsoleStartTop + (int)(Math.Floor((context.ConsoleStartLeft + context.Buffer.Count) / (double)context.Console.BufferWidth)); context.Console.CursorLeft = (context.ConsoleStartLeft + context.Buffer.Count) % context.Console.BufferWidth; context.Intercept = true; } }
public void Handle(RichCommandLineContext context) { if (context.KeyPressed.Key == ConsoleKey.Home) { context.Console.CursorTop = context.ConsoleStartTop; context.Console.CursorLeft = context.ConsoleStartLeft; context.Intercept = true; } else if (context.KeyPressed.Key == ConsoleKey.End) { context.Console.CursorTop = context.ConsoleStartTop + (int)(Math.Floor((context.ConsoleStartLeft + context.Buffer.Count) / (double)context.Console.BufferWidth)); context.Console.CursorLeft = (context.ConsoleStartLeft + context.Buffer.Count) % context.Console.BufferWidth; context.Intercept = true; } }
/// <summary> /// Implementation of tab completion that leverages tab completion sources that are registered with the target definition. /// </summary> /// <param name="cliContext">cintext used internally</param> /// <returns>true if a tab completion was successfully made, false otherwise</returns> public bool TryTabComplete(RichCommandLineContext cliContext) { var powerArgsContext = ConvertContext(this.Definition, cliContext); bool oldHookWon = false; string completion = null; foreach (var completionSource in oldHooks) { if (completionSource is ITabCompletionSourceWithContext) { if (((ITabCompletionSourceWithContext)completionSource).TryComplete(powerArgsContext.Shift, powerArgsContext.PreviousToken, powerArgsContext.CompletionCandidate, out completion)) { oldHookWon = true; break; } } else { if (completionSource.TryComplete(powerArgsContext.Shift, powerArgsContext.CompletionCandidate, out completion)) { oldHookWon = true; break; } } } if (oldHookWon == false) { foreach (var completionSource in newHooks) { if (completionSource.TryComplete(powerArgsContext, out completion)) { break; } } } if (completion != null) { cliContext.CompleteCurrentToken(cliContext.CurrentToken, new ConsoleString(completion)); return(true); } else { return(false); } }
public void Handle(RichCommandLineContext context) { if (context.KeyPressed.Modifiers.HasFlag(ConsoleModifiers.Control) == false) { return; } context.Intercept = true; context.RefreshTokenInfo(); if (ContextAssistProvider == null || ContextAssistProvider.CanAssist(context) == false) { return; } int left = context.Console.CursorLeft; int top = context.Console.CursorTop; ContextAssistResult result = ContextAssistResult.NoOp; try { context.Console.WriteLine("\n"); result = ContextAssistProvider.DrawMenu(context); while (result.IsTerminal == false) { var key = context.Console.ReadKey(true); result = ContextAssistProvider.OnKeyboardInput(context, key); } } finally { ContextAssistProvider.ClearMenu(context); context.Console.CursorLeft = left; context.Console.CursorTop = top; } if (result.StatusCode == ContextAssistResultStatusCode.Success) { context.ClearConsole(); context.Console.CursorLeft = left; context.Console.CursorTop = top; context.Buffer.Clear(); context.Buffer.AddRange(result.NewBuffer); context.RefreshConsole(result.ConsoleRefreshLeftOffset, 0); } }
/// <summary> /// Reads a line of text from the console. Any interactions you've configured before calling this method will be in effect. /// </summary> /// <param name="initialBuffer">Optionally seed the prompt with an initial value that the end user can modify</param> /// <returns>a line of text from the console</returns> public ConsoleString ReadLine(ConsoleString initialBuffer = null) { RichCommandLineContext context = new RichCommandLineContext(this.HistoryManager); context.Console = this.Console; context.ConsoleStartTop = this.Console.CursorTop; context.ConsoleStartLeft = this.Console.CursorLeft; if (initialBuffer != null) { context.ReplaceConsole(initialBuffer); } while (true) { context.Reset(); context.KeyPressed = this.Console.ReadKey(true); context.CharacterToWrite = new ConsoleCharacter(context.KeyPressed.KeyChar); context.BufferPosition = this.Console.CursorLeft - context.ConsoleStartLeft + (this.Console.CursorTop - context.ConsoleStartTop) * this.Console.BufferWidth; IKeyHandler handler = null; if (KeyHandlers.TryGetValue(context.KeyPressed.Key, out handler) == false && context.CharacterToWrite.Value != '\u0000') { context.WriteCharacterForPressedKey(); DoSyntaxHighlighting(context); } else if (handler != null) { handler.Handle(context); if (context.Intercept == false && context.CharacterToWrite.Value != '\u0000') { this.Console.Write(context.CharacterToWrite); } DoSyntaxHighlighting(context); if (context.IsFinished) { this.Console.WriteLine(); break; } } } return(new ConsoleString(context.Buffer)); }
public RichTextEditor() { this.HistoryManager = new ConsoleHistoryManager(); Context = new RichCommandLineContext(this.HistoryManager); Context.DisableConsoleRefresh = true; Context.Console = new RichTextStateConsole(this); TabHandler = new TabKeyHandler(); SpacebarHandler = new SpacebarKeyHandler(); KeyHandlers = new Dictionary <ConsoleKey, IKeyHandler>(); RegisterHandler(new EnterKeyHandler()); RegisterHandler(new ArrowKeysHandler()); RegisterHandler(new HomeAndEndKeysHandler()); RegisterHandler(new BackspaceAndDeleteKeysHandler()); RegisterHandler(SpacebarHandler); RegisterHandler(TabHandler); }
/// <summary> /// The implementation of ISyntaxHighlighter that uses the configuration you've created to perform syntax highlighting. /// </summary> /// <param name="readerContext">Context that is used internally</param> /// <returns>true if any highlighting changes were made, false otherwise</returns> public bool TryHighlight(RichCommandLineContext readerContext) { readerContext.RefreshTokenInfo(); bool didWork = false; for (int i = 0; i < readerContext.Tokens.Count; i++) { if (string.IsNullOrWhiteSpace(readerContext.Tokens[i].Value)) { continue; } var highlighterContext = new HighlighterContext() { CurrentToken = readerContext.Tokens[i], CurrentTokenIndex = i, IsLastToken = i == readerContext.Tokens.Count - 1, }; bool didWorkOnThisToken = false; bool shouldBeHighlightedByAtLeastOneHighlighter = false; foreach (var tokenHighlighter in TokenHighlighters) { bool shouldBeHighlightedByThisHighlighter = tokenHighlighter.ShouldBeHighlighted(readerContext, highlighterContext); shouldBeHighlightedByAtLeastOneHighlighter = shouldBeHighlightedByAtLeastOneHighlighter || shouldBeHighlightedByThisHighlighter; if (shouldBeHighlightedByThisHighlighter) { didWorkOnThisToken = EnsureHighlighted(highlighterContext.CurrentToken, readerContext, tokenHighlighter.HighlightForegroundColor, tokenHighlighter.HighlightBackgroundColor); if (didWorkOnThisToken) { break; } } } if (shouldBeHighlightedByAtLeastOneHighlighter == false) { didWorkOnThisToken = EnsureHighlighted(highlighterContext.CurrentToken, readerContext, null, null); } didWork = didWork || didWorkOnThisToken; } return(didWork); }
private void HandleBackspace(RichCommandLineContext context) { context.Intercept = true; if (context.BufferPosition == 0) { return; } context.BufferPosition--; if (context.BufferPosition < context.Buffer.Count) { context.Buffer.RemoveAt(context.BufferPosition); context.RefreshConsole(-1, 0); } }
private void HandleBackspace(RichCommandLineContext context) { context.Intercept = true; if(context.BufferPosition == 0) { return; } context.BufferPosition--; if (context.BufferPosition < context.Buffer.Count) { context.Buffer.RemoveAt(context.BufferPosition); context.RefreshConsole(-1, 0); } }
private void HandleLeftArrow(RichCommandLineContext context) { if (context.Console.CursorTop == context.ConsoleStartTop && context.Console.CursorLeft > context.ConsoleStartLeft) { context.Console.CursorLeft -= 1; } else if (context.Console.CursorLeft > 0) { context.Console.CursorLeft -= 1; } else if (context.Console.CursorTop > context.ConsoleStartTop) { context.Console.CursorTop--; context.Console.CursorLeft = context.Console.BufferWidth - 1; } context.Intercept = true; }
private void HandleDownArrow(RichCommandLineContext context) { if (context.HistoryManager.Values.Count == 0) { return; } context.Console.CursorLeft = context.ConsoleStartLeft; context.HistoryManager.Index--; if (context.HistoryManager.Index < 0) { context.HistoryManager.Index = context.HistoryManager.Values.Count - 1; } var newChars = context.HistoryManager.Values[context.HistoryManager.Index]; context.ReplaceConsole(newChars); context.Intercept = true; }
public void Handle(RichCommandLineContext context) { if(context.KeyPressed.Key == ConsoleKey.UpArrow) { HandleUpArrow(context); } else if(context.KeyPressed.Key == ConsoleKey.DownArrow) { HandleDownArrow(context); } else if(context.KeyPressed.Key == ConsoleKey.LeftArrow) { HandleLeftArrow(context); } else if(context.KeyPressed.Key == ConsoleKey.RightArrow) { HandleRightArrow(context); } }
internal static TabCompletionContext ConvertContext(CommandLineArgumentsDefinition definition, RichCommandLineContext innerContext) { TabCompletionContext context = new TabCompletionContext(); context.Definition = definition; context.Shift = innerContext.KeyPressed.Modifiers.HasFlag(ConsoleModifiers.Shift); context.PreviousToken = innerContext.CurrentTokenIndex > 0 ? innerContext.PreviousNonWhitespaceToken.Value : string.Empty; context.CompletionCandidate = innerContext.CurrentToken.Value; if (context.CompletionCandidate == " ") { context.CompletionCandidate = ""; } context.CommandLineText = new ConsoleString(innerContext.Buffer).ToString(); context.TargetAction = FindContextualAction(innerContext.Tokens.FirstOrDefault().Value, definition); context.TargetArgument = FindContextualArgument(context.PreviousToken, context.TargetAction, definition); return context; }
/// <summary> /// Determines if this highlighter should highlight the current token with this highlighter's foreground and background /// colors. /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if this highlighter should highlight the current token, false otherwise</returns> public abstract bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext);
/// <summary> /// Returns true if the keyword is matched, false otherwise /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if the keyword matched, false otherwise</returns> public override bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { if (highlighterContext.IsLastToken) return false; return highlighterContext.CurrentToken.Value.Equals(keyword, comparison); }
/// <summary> /// Returns true if the current token is a numeric value, false otherwise /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if the current token is a numeric value, false otherwise</returns> public override bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { double numericValue; return double.TryParse(highlighterContext.CurrentToken.Value, out numericValue); }
/// <summary> /// Clears the current provider's menu /// </summary> /// <param name="context">passed to the current provider</param> public virtual void ClearMenu(RichCommandLineContext context) { CurrentProvider.ClearMenu(context); }
/// <summary> /// Searches the reader's tokens for a non whitespace token that preceeds the current token /// </summary> /// <param name="readerContext">the reader context to inspect</param> /// <param name="highlighterContext">the highlighter context to inspect</param> /// <returns>a non whitespace token that preceeds the current token or null if no such token is found</returns> public static string FindPreviousNonWhitespaceToken(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { string previousToken = null; for (int i = highlighterContext.CurrentTokenIndex - 1; i >= 0; i--) { if (string.IsNullOrWhiteSpace(readerContext.Tokens[i].Value) == false) { previousToken = readerContext.Tokens[i].Value; break; } } return previousToken; }
/// <summary> /// Draws the current provider's menu /// </summary> /// <param name="context">passed to the current provider</param> /// <returns>the inner provider's result</returns> public virtual ContextAssistResult DrawMenu(RichCommandLineContext context) { return CurrentProvider.DrawMenu(context); }
/// <summary> /// The implementation of ISyntaxHighlighter that uses the configuration you've created to perform syntax highlighting. /// </summary> /// <param name="readerContext">Context that is used internally</param> /// <returns>true if any highlighting changes were made, false otherwise</returns> public bool TryHighlight(RichCommandLineContext readerContext) { readerContext.RefreshTokenInfo(); bool didWork = false; for (int i = 0; i < readerContext.Tokens.Count; i++) { if(string.IsNullOrWhiteSpace(readerContext.Tokens[i].Value)) { continue; } var highlighterContext = new HighlighterContext() { CurrentToken = readerContext.Tokens[i], CurrentTokenIndex = i, IsLastToken = i == readerContext.Tokens.Count-1, }; bool didWorkOnThisToken = false; bool shouldBeHighlightedByAtLeastOneHighlighter = false; foreach (var tokenHighlighter in TokenHighlighters) { bool shouldBeHighlightedByThisHighlighter = tokenHighlighter.ShouldBeHighlighted(readerContext, highlighterContext); shouldBeHighlightedByAtLeastOneHighlighter = shouldBeHighlightedByAtLeastOneHighlighter || shouldBeHighlightedByThisHighlighter; if (shouldBeHighlightedByThisHighlighter) { didWorkOnThisToken = EnsureHighlighted(highlighterContext.CurrentToken, readerContext, tokenHighlighter.HighlightForegroundColor, tokenHighlighter.HighlightBackgroundColor); if (didWorkOnThisToken) break; } } if(shouldBeHighlightedByAtLeastOneHighlighter == false) { didWorkOnThisToken = EnsureHighlighted(highlighterContext.CurrentToken, readerContext, null, null); } didWork = didWork || didWorkOnThisToken; } return didWork; }
/// <summary> /// Passes the keyboard input to the current provider /// </summary> /// <param name="context">passed to the current provider</param> /// <param name="keyPress">passed to the current provider</param> /// <returns>the current provider's result</returns> public virtual ContextAssistResult OnKeyboardInput(RichCommandLineContext context, ConsoleKeyInfo keyPress) { return CurrentProvider.OnKeyboardInput(context, keyPress); }
private bool EnsureHighlighted(Token token, RichCommandLineContext context, ConsoleColor? fg, ConsoleColor? bg) { if (fg.HasValue == false) fg = ConsoleString.DefaultForegroundColor; if (bg.HasValue == false) bg = ConsoleString.DefaultBackgroundColor; bool didWork = false; for (int i = token.StartIndex; i < token.StartIndex + token.Value.Length; i++) { if (context.Buffer[i].ForegroundColor != fg.Value || context.Buffer[i].BackgroundColor != bg.Value) { didWork = true; context.Buffer[i] = new ConsoleCharacter(context.Buffer[i].Value, fg, bg); } } return didWork; }
/// <summary> /// Returns true if the token matches the keyword and the given conditional evaluation returns true /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if the token matches the keyword and the given conditional evaluation returns true</returns> public override bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { if (conditionEval(readerContext, highlighterContext)) { return base.ShouldBeHighlighted(readerContext, highlighterContext); } else { return false; } }
/// <summary> /// Calls the handler action code /// </summary> /// <param name="context">context from the parent reader</param> public void Handle(RichCommandLineContext context) { Handler(context); }
/// <summary> /// Returns true if there is at least one option, false otherwise. /// </summary> /// <param name="context">context about the parent reader</param> /// <returns>true if there is at least one option, false otherwise</returns> public override bool CanAssist(RichCommandLineContext context) { return Options.Count > 0; }
/// <summary> /// Implementation of tab completion that leverages tab completion sources that are registered with the target definition. /// </summary> /// <param name="cliContext">cintext used internally</param> /// <returns>true if a tab completion was successfully made, false otherwise</returns> public bool TryTabComplete(RichCommandLineContext cliContext) { var powerArgsContext = ConvertContext(this.Definition, cliContext); bool oldHookWon = false; string completion = null; foreach (var completionSource in oldHooks) { if (completionSource is ITabCompletionSourceWithContext) { if (((ITabCompletionSourceWithContext)completionSource).TryComplete(powerArgsContext.Shift, powerArgsContext.PreviousToken, powerArgsContext.CompletionCandidate, out completion)) { oldHookWon = true; break; } } else { if (completionSource.TryComplete(powerArgsContext.Shift, powerArgsContext.CompletionCandidate, out completion)) { oldHookWon = true; break; } } } if (oldHookWon == false) { foreach (var completionSource in newHooks) { if (completionSource.TryComplete(powerArgsContext, out completion)) { break; } } } if (completion != null) { cliContext.CompleteCurrentToken(cliContext.CurrentToken, new ConsoleString(completion)); return true; } else { return false; } }
public bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { // don't even try mark tokens as invalid unless the cursor is on it if (readerContext.BufferPosition >= highlighterContext.CurrentToken.StartIndex && readerContext.BufferPosition < highlighterContext.CurrentToken.EndIndex) { return false; } var currentToken = highlighterContext.CurrentToken.Value; var previousToken = PowerArgsRichCommandLineReader.FindPreviousNonWhitespaceToken(readerContext, highlighterContext); var firstToken = readerContext.Tokens[0].Value; CommandLineAction contextualAction = PowerArgsRichCommandLineReader.FindContextualAction(firstToken, definition); CommandLineArgument contextualArgument = PowerArgsRichCommandLineReader.FindContextualArgument(previousToken, contextualAction, definition); if (contextualArgument != null) { if(contextualArgument.TestIsValidAndRevivable(currentToken) == false) { // the current token either failed validation or could not be revived return true; } } bool expectMatchingArg; CommandLineArgument currentTokenArgument = PowerArgsRichCommandLineReader.FindCurrentTokenArgument(contextualAction, currentToken, out expectMatchingArg, definition); if(currentTokenArgument == null && expectMatchingArg) { // The current token starts with a - or /, but does not match a global or action specific argument, so we'll highlight the token red return true; } return false; }
/// <summary> /// Creates a result that replaces the current token with the given selection. /// </summary> /// <param name="context">Context from the parent reader</param> /// <param name="selection">The selection string to insert</param> /// <returns>a result that replaces the current token with the given selection</returns> public static ContextAssistResult CreateInsertResult(RichCommandLineContext context, ConsoleString selection) { context.RefreshTokenInfo(); var ret = new ContextAssistResult(); bool hasInserted = false; var newBuffer = new List<ConsoleCharacter>(); foreach (var token in context.Tokens) { if (context.IsCursorOnToken(token)) { if (string.IsNullOrWhiteSpace(token.Value)) { newBuffer.AddRange(context.GetBufferSubstringFromToken(token)); ret.ConsoleRefreshLeftOffset = selection.Length; } else { var tokenOffset = context.BufferPosition - token.StartIndex; ret.ConsoleRefreshLeftOffset = selection.Length - tokenOffset; } if (hasInserted == false) { hasInserted = true; // cursor is on the current token newBuffer.AddRange(selection); } } else { // this token not be modified newBuffer.AddRange(context.GetBufferSubstringFromToken(token)); } } if (hasInserted == false) { hasInserted = true; // cursor is on the current token newBuffer.AddRange(selection); ret.ConsoleRefreshLeftOffset = selection.Length; } ret.StatusCode = ContextAssistResultStatusCode.Success; ret.NewBuffer = newBuffer; return ret; }
/// <summary> /// Returns true if the regular expression is matched, false otherwise /// </summary> /// <param name="readerContext">context from the reader</param> /// <param name="highlighterContext">context about the current token</param> /// <returns>true if the regular expression is matched, false otherwise</returns> public override bool ShouldBeHighlighted(RichCommandLineContext readerContext, HighlighterContext highlighterContext) { var matches = regex.Matches(highlighterContext.CurrentToken.Value); foreach(Match match in matches) { if (match.Value == highlighterContext.CurrentToken.Value) return true; } return false; }